Esempio n. 1
0
        public static Models.UserProfile GetUserProfile(string name)
        {
            IDatabase cache = CacheConnectionHelper.Connection.GetDatabase();

            Models.UserProfile userProfile = (Models.UserProfile)cache.Get(name);
            if (userProfile == null)
            {
                #region Get User Profile from AD
                Uri serviceRoot = new Uri(SettingsHelper.AzureAdGraphApiEndPoint);
                var token       = AppToken.GetAppToken();

                ActiveDirectoryClient adClient = new ActiveDirectoryClient(
                    serviceRoot,
                    async() => await AppToken.GetAppTokenAsync());

                string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;

                Microsoft.Azure.ActiveDirectory.GraphClient.Application app = (Microsoft.Azure.ActiveDirectory.GraphClient.Application)adClient.Applications.Where(
                    a => a.AppId == SettingsHelper.ClientId).ExecuteSingleAsync().Result;
                if (app == null)
                {
                    throw new ApplicationException("Unable to get a reference to application in Azure AD.");
                }

                string     requestUrl = string.Format("https://graph.windows.net/{0}/users/{1}?api-version=1.5", SettingsHelper.Tenant, name);
                HttpClient hc         = new HttpClient();
                hc.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
                HttpResponseMessage hrm = hc.GetAsync(new Uri(requestUrl)).Result;

                if (hrm.IsSuccessStatusCode)
                {
                    Models.UserProfile currentUserProfile = JsonConvert.DeserializeObject <Models.UserProfile>(hrm.Content.ReadAsStringAsync().Result);
                    cache.Set(ClaimsPrincipal.Current.Identities.First().Name, currentUserProfile, TimeSpan.FromMinutes(SettingsHelper.CacheUserProfileMinutes));

                    return(currentUserProfile);
                }
                else
                {
                    return(null);
                }
                #endregion
            }
            else
            {
                return(userProfile);
            }
        }
        /// <summary>
        /// Restore an application.
        /// </summary>
        /// <param name="application">Application to be restored.</param>
        /// <param name="identifierUris">Identifier uris to be assigned after restore.</param>
        /// <returns>Restored application.</returns>
        public virtual Application Restore(Application application, IList<string> identifierUris)
        {
            Utils.ValidateGraphObject(application, "application");

            if (identifierUris == null)
            {
                identifierUris = new List<string>();
            }

            Uri requestUri = Utils.GetRequestUri<Application>(
                this, application.ObjectId, Constants.ActionRestoreApplication);

            Dictionary<string, IList<string>> parameters = new Dictionary<string, IList<string>>();
            parameters["identifierUris"] = identifierUris;

            string requestJson = JsonConvert.SerializeObject(parameters);
            string responseJson = this.ClientConnection.UploadString(
                requestUri, HttpVerb.POST, requestJson, null, null);

            PagedResults<Application> pagedResults =
                SerializationHelper.DeserializeJsonResponse<Application>(responseJson, requestUri);

            if (pagedResults != null && pagedResults.Results.Count > 0)
            {
                return pagedResults.Results[0];
            }

            // TODO: Should we throw an exception here?
            return null;
        }
        /// <summary>
        /// Register Application to Azure AD
        /// </summary>
        /// <returns>registered application's clientid</returns>
        public string RegisterApp()
        {
            authContext = new AuthenticationContext(props.Authority);

            // Application Name
            string appName = "CRM for LINQPad";

            ActiveDirectoryClient activeDirectoryClient;

            int i = 0;

            while (true)
            {
                // Instantiate ActiveDirectoryClient
                activeDirectoryClient = GetActiveDirectoryClientAsApplication(useCurrentUser);

                if (CheckAzureAdPrivilege(activeDirectoryClient))
                {
                    break;
                }
                else
                {
                    MessageBox.Show("Current login user does not have privilege to register an applicaiton to the Azure AD. You need to login as Company Admin so that it can reigster an applicaiton, or cancel the wizard, then enter ClientId/RedirectUri manually.");
                    // Clear the ADAL cache.
                    authContext.TokenCache.Clear();
                    useCurrentUser = false;
                    if (i == 1)
                    {
                        return(null);
                    }
                    else
                    {
                        i++;
                    }
                }
            }

            // Check if same name application already exists.
            var existingApp = activeDirectoryClient.Applications
                              .Where(x => x.DisplayName == appName)
                              .ExecuteAsync().Result.CurrentPage.FirstOrDefault();

            // If it is already registered, then return existing clientid.
            if (existingApp != null && existingApp.RequiredResourceAccess.Count() == 2)
            {
                return(existingApp.AppId);
            }
            else
            {
                existingApp.DeleteAsync().Wait();
            }

            // Instantiate Application to Azure AD.
            IApplication myapp = new Microsoft.Azure.ActiveDirectory.GraphClient.Application();

            myapp.DisplayName = appName;
            var redirectUri = "http://localhost/linqpad";

            myapp.ReplyUrls.Add(redirectUri);
            props.RedirectUri  = redirectUri;
            myapp.PublicClient = true;
            // Mark this only to this tenant
            myapp.AvailableToOtherTenants = false;

            // Create the Application to Azure AD.
            activeDirectoryClient.Applications.AddApplicationAsync(myapp).Wait();

            // Obtain the created Application.
            var createdApp = activeDirectoryClient.Applications
                             .Where(x => x.DisplayName == appName)
                             .ExecuteAsync().Result.CurrentPage.FirstOrDefault();

            // Instantiate Service regarding to the application.
            IServicePrincipal myservice = new ServicePrincipal();

            myservice.AppId = createdApp.AppId;
            myservice.Tags.Add("WindowsAzureActiveDirectoryIntegratedApp");

            // Create the Service.
            activeDirectoryClient.ServicePrincipals.AddServicePrincipalAsync(myservice).Wait();

            // Obtain the created Service.
            var createdService = activeDirectoryClient.ServicePrincipals
                                 .Where(x => x.DisplayName == appName)
                                 .ExecuteAsync().Result.CurrentPage.FirstOrDefault();

            // Set permissions.
            // Get Microsoft.Azure.ActiveDirectory Service.
            var service1 = activeDirectoryClient.ServicePrincipals
                           .Where(x => x.AppId == "00000002-0000-0000-c000-000000000000")
                           .ExecuteAsync().Result.CurrentPage.FirstOrDefault();

            // Instantiate UserProfile.Read OAuth2PermissionGrant for the Service
            OAuth2PermissionGrant grant0 = new OAuth2PermissionGrant();

            grant0.ClientId    = createdService.ObjectId;
            grant0.ResourceId  = service1.ObjectId;
            grant0.ConsentType = "AllPrincipals";
            grant0.Scope       = "User.Read";
            grant0.ExpiryTime  = DateTime.Now.AddYears(1);

            // Create the OAuth2PermissionGrant
            activeDirectoryClient.Oauth2PermissionGrants.AddOAuth2PermissionGrantAsync(grant0).Wait();

            // Get Microsoft.CRM Service.
            var service2 = activeDirectoryClient.ServicePrincipals
                           .Where(x => x.AppId == "00000007-0000-0000-c000-000000000000")
                           .ExecuteAsync().Result.CurrentPage.FirstOrDefault();

            // Instantiate user_impersonation OAuth2PermissionGrant for the Service
            OAuth2PermissionGrant grant = new OAuth2PermissionGrant();

            grant.ClientId    = createdService.ObjectId;
            grant.ResourceId  = service2.ObjectId;
            grant.ConsentType = "AllPrincipals";
            grant.Scope       = "user_impersonation";
            grant.ExpiryTime  = DateTime.Now.AddYears(1);

            // Create the OAuth2PermissionGrant
            activeDirectoryClient.Oauth2PermissionGrants.AddOAuth2PermissionGrantAsync(grant).Wait();

            // Create RequiredResourceAccess
            // Instantiate ResourceAccess for Microsoft.Azure.ActiveDirectory/UserProfile.Read permission.
            ResourceAccess resourceAccess1 = new ResourceAccess();

            resourceAccess1.Id   = service1.Oauth2Permissions.Where(x => x.Value == "User.Read").First().Id;
            resourceAccess1.Type = "Scope";
            // Instantiate RequiredResourceAccess and assign the ResourceAccess
            RequiredResourceAccess requiredresourceAccess1 = new RequiredResourceAccess();

            requiredresourceAccess1.ResourceAppId = service1.AppId;
            requiredresourceAccess1.ResourceAccess.Add(resourceAccess1);

            // Instantiate ResourceAccess for Microsoft.CRM/user_impersonation.Read permission.
            ResourceAccess resourceAccess2 = new ResourceAccess();

            resourceAccess2.Id   = service2.Oauth2Permissions.Where(x => x.Value == "user_impersonation").First().Id;
            resourceAccess2.Type = "Scope";
            // Instantiate RequiredResourceAccess and assign the ResourceAccess
            RequiredResourceAccess requiredResourceAccess2 = new RequiredResourceAccess();

            requiredResourceAccess2.ResourceAppId = service2.AppId;
            requiredResourceAccess2.ResourceAccess.Add(resourceAccess2);

            // Add RequiredResourceAccess information to the Application
            createdApp.RequiredResourceAccess.Add(requiredresourceAccess1);
            createdApp.RequiredResourceAccess.Add(requiredResourceAccess2);

            // Update the Application
            createdApp.UpdateAsync().Wait();

            // Once all Azure AD work done, clear ADAL cache again in case user logged in as different user.
            authContext.TokenCache.Clear();

            // Return AppId (ClientId)
            return(createdApp.AppId);
        }
Esempio n. 4
0
        private static void Main()
        {
            // record start DateTime of execution
            string currentDateTime = DateTime.Now.ToUniversalTime().ToString();

            #region Setup Active Directory Client

            //*********************************************************************
            // setup Active Directory Client
            //*********************************************************************
            ActiveDirectoryClient activeDirectoryClient;
            try
            {
                activeDirectoryClient = AuthenticationHelper.GetActiveDirectoryClientAsApplication();
            }
            catch (AuthenticationException ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Acquiring a token failed with the following error: {0}", ex.Message);
                if (ex.InnerException != null)
                {
                    //You should implement retry and back-off logic per the guidance given here:http://msdn.microsoft.com/en-us/library/dn168916.aspx
                    //InnerException Message will contain the HTTP error status codes mentioned in the link above
                    Console.WriteLine("Error detail: {0}", ex.InnerException.Message);
                }
                Console.ResetColor();
                Console.ReadKey();
                return;
            }

            #endregion

            #region TenantDetails

            //*********************************************************************
            // Get Tenant Details
            // Note: update the string TenantId with your TenantId.
            // This can be retrieved from the login Federation Metadata end point:             
            // https://login.windows.net/GraphDir1.onmicrosoft.com/FederationMetadata/2007-06/FederationMetadata.xml
            //  Replace "GraphDir1.onMicrosoft.com" with any domain owned by your organization
            // The returned value from the first xml node "EntityDescriptor", will have a STS URL
            // containing your TenantId e.g. "https://sts.windows.net/4fd2b2f2-ea27-4fe5-a8f3-7b1a7c975f34/" is returned for GraphDir1.onMicrosoft.com
            //*********************************************************************
            VerifiedDomain initialDomain = new VerifiedDomain();
            VerifiedDomain defaultDomain = new VerifiedDomain();
            ITenantDetail tenant = null;
            Console.WriteLine("\n Retrieving Tenant Details");
            try
            {
                List<ITenantDetail> tenantsList = activeDirectoryClient.TenantDetails
                    .Where(tenantDetail => tenantDetail.ObjectId.Equals(Constants.TenantId))
                    .ExecuteAsync().Result.CurrentPage.ToList();
                if (tenantsList.Count > 0)
                {
                    tenant = tenantsList.First();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("\nError getting TenantDetails {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }

            if (tenant == null)
            {
                Console.WriteLine("Tenant not found");
            }
            else
            {
                TenantDetail tenantDetail = (TenantDetail)tenant;
                Console.WriteLine("Tenant Display Name: " + tenantDetail.DisplayName);

                // Get the Tenant's Verified Domains 
                initialDomain = tenantDetail.VerifiedDomains.First(x => x.Initial.HasValue && x.Initial.Value);
                Console.WriteLine("Initial Domain Name: " + initialDomain.Name);
                defaultDomain = tenantDetail.VerifiedDomains.First(x => [email protected] && [email protected]);
                Console.WriteLine("Default Domain Name: " + defaultDomain.Name);

                // Get Tenant's Tech Contacts
                foreach (string techContact in tenantDetail.TechnicalNotificationMails)
                {
                    Console.WriteLine("Tenant Tech Contact: " + techContact);
                }
            }

            #endregion

            #region Create a new User

            IUser newUser = new User();
            if (defaultDomain.Name != null)
            {
                newUser.DisplayName = "Sample App Demo User (Manager)";
                newUser.UserPrincipalName = Helper.GetRandomString(10) + "@" + defaultDomain.Name;
                newUser.AccountEnabled = true;
                newUser.MailNickname = "SampleAppDemoUserManager";
                newUser.PasswordProfile = new PasswordProfile
                {
                    Password = "******",
                    ForceChangePasswordNextLogin = true
                };
                newUser.UsageLocation = "US";
                try
                {
                    activeDirectoryClient.Users.AddUserAsync(newUser).Wait();
                    Console.WriteLine("\nNew User {0} was created", newUser.DisplayName);
                }
                catch (Exception e)
                {
                    Console.WriteLine("\nError creating new user {0} {1}", e.Message,
                        e.InnerException != null ? e.InnerException.Message : "");
                }
            }

            #endregion

            #region List of max 4 Users by UPN

            //*********************************************************************
            // Demonstrate Getting a list of Users with paging (get 4 users), sorted by displayName
            //*********************************************************************
            int maxUsers = 4;
            try
            {
                Console.WriteLine("\n Retrieving Users");
                List<IUser> users = activeDirectoryClient.Users.OrderBy(user =>
                    user.UserPrincipalName).Take(maxUsers).ExecuteAsync().Result.CurrentPage.ToList();
                foreach (IUser user in users)
                {
                    Console.WriteLine("UserObjectId: {0}  UPN: {1}", user.ObjectId, user.UserPrincipalName);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("\nError getting Users. {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }

            #endregion

            #region Create a User with a temp Password

            //*********************************************************************************************
            // Create a new User with a temp Password
            //*********************************************************************************************
            IUser userToBeAdded = new User();
            userToBeAdded.DisplayName = "Sample App Demo User";
            userToBeAdded.UserPrincipalName = Helper.GetRandomString(10) + "@" + defaultDomain.Name;
            userToBeAdded.AccountEnabled = true;
            userToBeAdded.MailNickname = "SampleAppDemoUser";
            userToBeAdded.PasswordProfile = new PasswordProfile
            {
                Password = "******",
                ForceChangePasswordNextLogin = true
            };
            userToBeAdded.UsageLocation = "US";
            try
            {
                activeDirectoryClient.Users.AddUserAsync(userToBeAdded).Wait();
                Console.WriteLine("\nNew User {0} was created", userToBeAdded.DisplayName);
            }
            catch (Exception e)
            {
                Console.WriteLine("\nError creating new user. {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }

            #endregion

            #region Update newly created User

            //*******************************************************************************************
            // update the newly created user's Password, PasswordPolicies and City
            //*********************************************************************************************
            if (userToBeAdded.ObjectId != null)
            {
                // update User's city and reset their User's Password
                userToBeAdded.City = "Seattle";
                userToBeAdded.Country = "UK";
                PasswordProfile PasswordProfile = new PasswordProfile
                {
                    Password = "******",
                    ForceChangePasswordNextLogin = false
                };
                userToBeAdded.PasswordProfile = PasswordProfile;
                userToBeAdded.PasswordPolicies = "DisablePasswordExpiration, DisableStrongPassword";
                try
                {
                    userToBeAdded.UpdateAsync().Wait();
                    Console.WriteLine("\nUser {0} was updated", userToBeAdded.DisplayName);
                }
                catch (Exception e)
                {
                    Console.WriteLine("\nError Updating the user {0} {1}", e.Message,
                        e.InnerException != null ? e.InnerException.Message : "");
                }
            }

            #endregion

            #region Search User by UPN

            // search for a single user by UPN
            string searchString = "admin@" + initialDomain.Name;
            Console.WriteLine("\n Retrieving user with UPN {0}", searchString);
            User retrievedUser = new User();
            List<IUser> retrievedUsers = null;
            try
            {
                retrievedUsers = activeDirectoryClient.Users
                    .Where(user => user.UserPrincipalName.Equals(searchString))
                    .ExecuteAsync().Result.CurrentPage.ToList();
            }
            catch (Exception e)
            {
                Console.WriteLine("\nError getting new user {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }
            // should only find one user with the specified UPN
            if (retrievedUsers != null && retrievedUsers.Count == 1)
            {
                retrievedUser = (User)retrievedUsers.First();
            }
            else
            {
                Console.WriteLine("User not found {0}", searchString);
            }

            #endregion

            #region User Operations

            if (retrievedUser.UserPrincipalName != null)
            {
                Console.WriteLine("\n Found User: "******"  UPN: " +
                                  retrievedUser.UserPrincipalName);

                #region Assign User a Manager

                //Assigning User a new manager.
                if (newUser.ObjectId != null)
                {
                    Console.WriteLine("\n Assign User {0}, {1} as Manager.", retrievedUser.DisplayName,
                        newUser.DisplayName);
                    retrievedUser.Manager = newUser as DirectoryObject;
                    try
                    {
                        newUser.UpdateAsync().Wait();
                        Console.Write("User {0} is successfully assigned {1} as Manager.", retrievedUser.DisplayName,
                            newUser.DisplayName);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("\nError assigning manager to user. {0} {1}", e.Message,
                            e.InnerException != null ? e.InnerException.Message : "");
                    }
                }

                #endregion

                #region Get User's Manager

                //Get the retrieved user's manager.
                Console.WriteLine("\n Retrieving User {0}'s Manager.", retrievedUser.DisplayName);
                DirectoryObject usersManager = retrievedUser.Manager;
                if (usersManager != null)
                {
                    User manager = usersManager as User;
                    if (manager != null)
                    {
                        Console.WriteLine("User {0} Manager details: \nManager: {1}  UPN: {2}",
                            retrievedUser.DisplayName, manager.DisplayName, manager.UserPrincipalName);
                    }
                }
                else
                {
                    Console.WriteLine("Manager not found.");
                }

                #endregion

                #region Get User's Direct Reports

                //*********************************************************************
                // get the user's Direct Reports
                //*********************************************************************
                if (newUser.ObjectId != null)
                {
                    Console.WriteLine("\n Getting User{0}'s Direct Reports.", newUser.DisplayName);
                    IUserFetcher newUserFetcher = (IUserFetcher)newUser;
                    try
                    {
                        IPagedCollection<IDirectoryObject> directReports =
                            newUserFetcher.DirectReports.ExecuteAsync().Result;
                        do
                        {
                            List<IDirectoryObject> directoryObjects = directReports.CurrentPage.ToList();
                            foreach (IDirectoryObject directoryObject in directoryObjects)
                            {
                                if (directoryObject is User)
                                {
                                    User directReport = directoryObject as User;
                                    Console.WriteLine("User {0} Direct Report is {1}", newUser.UserPrincipalName,
                                        directReport.UserPrincipalName);
                                }
                            }
                            directReports = directReports.GetNextPageAsync().Result;
                        } while (directReports != null);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("\nError getting direct reports of user. {0} {1}", e.Message,
                            e.InnerException != null ? e.InnerException.Message : "");
                    }
                }

                #endregion

                #region Get list of Group IDS, user is member of

                //*********************************************************************
                // get a list of Group IDs that the user is a member of
                //*********************************************************************
                //const bool securityEnabledOnly = false;
                //IEnumerable<string> memberGroups = retrievedUser.GetMemberGroupsAsync(securityEnabledOnly).Result;
                //Console.WriteLine("\n {0} is a member of the following Groups (IDs)", retrievedUser.DisplayName);
                //foreach (String memberGroup in memberGroups)
                //{
                //    Console.WriteLine("Member of Group ID: " + memberGroup);
                //}

                #endregion

                #region Get User's Group And Role Membership, Getting the complete set of objects

                //*********************************************************************
                // get the User's Group and Role membership, getting the complete set of objects
                //*********************************************************************
                Console.WriteLine("\n {0} is a member of the following Group and Roles (IDs)", retrievedUser.DisplayName);
                IUserFetcher retrievedUserFetcher = retrievedUser;
                try
                {
                    IPagedCollection<IDirectoryObject> pagedCollection = retrievedUserFetcher.MemberOf.ExecuteAsync().Result;
                    do
                    {
                        List<IDirectoryObject> directoryObjects = pagedCollection.CurrentPage.ToList();
                        foreach (IDirectoryObject directoryObject in directoryObjects)
                        {
                            if (directoryObject is Group)
                            {
                                Group group = directoryObject as Group;
                                Console.WriteLine(" Group: {0}  Description: {1}", group.DisplayName, group.Description);
                            }
                            if (directoryObject is DirectoryRole)
                            {
                                DirectoryRole role = directoryObject as DirectoryRole;
                                Console.WriteLine(" Role: {0}  Description: {1}", role.DisplayName, role.Description);
                            }
                        }
                        pagedCollection = pagedCollection.GetNextPageAsync().Result;
                    } while (pagedCollection != null);
                }
                catch (Exception e)
                {
                    Console.WriteLine("\nError getting user's groups and roles memberships. {0} {1}", e.Message,
                        e.InnerException != null ? e.InnerException.Message : "");
                }

                #endregion
            }

            #endregion

            #region Search for User (People Picker)

            //*********************************************************************
            // People picker
            // Search for a user using text string "Us" match against userPrincipalName, displayName, giveName, surname   
            //*********************************************************************
            searchString = "Us";
            Console.WriteLine("\nSearching for any user with string {0} in UPN,DisplayName,First or Last Name",
                searchString);
            List<IUser> usersList = null;
            IPagedCollection<IUser> searchResults = null;
            try
            {
                IUserCollection userCollection = activeDirectoryClient.Users;
                searchResults = userCollection.Where(user =>
                    user.UserPrincipalName.StartsWith(searchString) ||
                    user.DisplayName.StartsWith(searchString) ||
                    user.GivenName.StartsWith(searchString) ||
                    user.Surname.StartsWith(searchString)).ExecuteAsync().Result;
                usersList = searchResults.CurrentPage.ToList();
            }
            catch (Exception e)
            {
                Console.WriteLine("\nError getting User {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }

            if (usersList != null && usersList.Count > 0)
            {
                do
                {
                    usersList = searchResults.CurrentPage.ToList();
                    foreach (IUser user in usersList)
                    {
                        Console.WriteLine("User DisplayName: {0}  UPN: {1}",
                            user.DisplayName, user.UserPrincipalName);
                    }
                    searchResults = searchResults.GetNextPageAsync().Result;
                } while (searchResults != null);
            }
            else
            {
                Console.WriteLine("User not found");
            }

            #endregion

            #region Search for Group using StartWith filter

            //*********************************************************************
            // Search for a group using a startsWith filter (displayName property)
            //*********************************************************************
            Group retrievedGroup = new Group();
            searchString = "My";
            List<IGroup> foundGroups = null;
            try
            {
                foundGroups = activeDirectoryClient.Groups
                    .Where(group => group.DisplayName.StartsWith(searchString))
                    .ExecuteAsync().Result.CurrentPage.ToList();
            }
            catch (Exception e)
            {
                Console.WriteLine("\nError getting Group {0} {1}",
                    e.Message, e.InnerException != null ? e.InnerException.Message : "");
            }
            if (foundGroups != null && foundGroups.Count > 0)
            {
                retrievedGroup = foundGroups.First() as Group;
            }
            else
            {
                Console.WriteLine("Group Not Found");
            }

            #endregion

            #region Assign Member to Group

            if (retrievedGroup.ObjectId != null)
            {
                try
                {
                    retrievedGroup.Members.Add(newUser as DirectoryObject);
                    retrievedGroup.UpdateAsync().Wait();
                }
                catch (Exception e)
                {
                    Console.WriteLine("\nError assigning member to group. {0} {1}",
                        e.Message, e.InnerException != null ? e.InnerException.Message : "");
                }

            }

            #endregion

            #region Get Group members

            if (retrievedGroup.ObjectId != null)
            {
                Console.WriteLine("\n Found Group: " + retrievedGroup.DisplayName + "  " + retrievedGroup.Description);

                //*********************************************************************
                // get the groups' membership - 
                // Note this method retrieves ALL links in one request - please use this method with care - this
                // may return a very large number of objects
                //*********************************************************************
                IGroupFetcher retrievedGroupFetcher = retrievedGroup;
                try
                {
                    IPagedCollection<IDirectoryObject> members = retrievedGroupFetcher.Members.ExecuteAsync().Result;
                    Console.WriteLine(" Members:");
                    do
                    {
                        List<IDirectoryObject> directoryObjects = members.CurrentPage.ToList();
                        foreach (IDirectoryObject member in directoryObjects)
                        {
                            if (member is User)
                            {
                                User user = member as User;
                                Console.WriteLine("User DisplayName: {0}  UPN: {1}",
                                    user.DisplayName,
                                    user.UserPrincipalName);
                            }
                            if (member is Group)
                            {
                                Group group = member as Group;
                                Console.WriteLine("Group DisplayName: {0}", group.DisplayName);
                            }
                            if (member is Contact)
                            {
                                Contact contact = member as Contact;
                                Console.WriteLine("Contact DisplayName: {0}", contact.DisplayName);
                            }
                        }
                        members = members.GetNextPageAsync().Result;
                    } while (members != null);
                }
                catch (Exception e)
                {
                    Console.WriteLine("\nError getting groups' membership. {0} {1}",
                        e.Message, e.InnerException != null ? e.InnerException.Message : "");
                }
            }

            #endregion

            #region Add User to Group

            //*********************************************************************************************
            // Add User to the "WA" Group 
            //*********************************************************************************************
            if (retrievedGroup.ObjectId != null)
            {
                try
                {
                    retrievedGroup.Members.Add(userToBeAdded as DirectoryObject);
                    retrievedGroup.UpdateAsync().Wait();
                }
                catch (Exception e)
                {
                    Console.WriteLine("\nAdding user to group failed {0} {1}", e.Message,
                        e.InnerException != null ? e.InnerException.Message : "");
                }
            }

            #endregion

            #region Create a new Group

            //*********************************************************************************************
            // Create a new Group
            //*********************************************************************************************
            Group californiaEmployees = new Group
            {
                DisplayName = "California Employees" + Helper.GetRandomString(8),
                Description = "Employees in the state of California",
                MailNickname = "CalEmployees",
                MailEnabled = false,
                SecurityEnabled = true
            };
            try
            {
                activeDirectoryClient.Groups.AddGroupAsync(californiaEmployees).Wait();
                Console.WriteLine("\nNew Group {0} was created", californiaEmployees.DisplayName);
            }
            catch (Exception e)
            {
                Console.WriteLine("\nError creating new Group {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }

            #endregion

            #region Delete User

            //*********************************************************************************************
            // Delete the user that we just created
            //*********************************************************************************************
            if (userToBeAdded.ObjectId != null)
            {
                try
                {
                    userToBeAdded.DeleteAsync().Wait();
                    Console.WriteLine("\nUser {0} was deleted", userToBeAdded.DisplayName);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Deleting User failed {0} {1}", e.Message,
                        e.InnerException != null ? e.InnerException.Message : "");
                }
            }
            if (newUser.ObjectId != null)
            {
                try
                {
                    newUser.DeleteAsync().Wait();
                    Console.WriteLine("\nUser {0} was deleted", newUser.DisplayName);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Deleting User failed {0} {1}", e.Message,
                        e.InnerException != null ? e.InnerException.Message : "");
                }
            }

            #endregion

            #region Delete Group

            //*********************************************************************************************
            // Delete the Group that we just created
            //*********************************************************************************************
            if (californiaEmployees.ObjectId != null)
            {
                try
                {
                    californiaEmployees.DeleteAsync().Wait();
                    Console.WriteLine("\nGroup {0} was deleted", californiaEmployees.DisplayName);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Deleting Group failed {0} {1}", e.Message,
                        e.InnerException != null ? e.InnerException.Message : "");
                }
            }

            #endregion

            #region Get All Roles

            //*********************************************************************
            // Get All Roles
            //*********************************************************************
            List<IDirectoryRole> foundRoles = null;
            try
            {
                foundRoles = activeDirectoryClient.DirectoryRoles.ExecuteAsync().Result.CurrentPage.ToList();
            }
            catch (Exception e)
            {
                Console.WriteLine("\nError getting Roles {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }

            if (foundRoles != null && foundRoles.Count > 0)
            {
                foreach (IDirectoryRole role in foundRoles)
                {
                    Console.WriteLine("\n Found Role: {0} {1} {2} ",
                        role.DisplayName, role.Description, role.ObjectId);
                }
            }
            else
            {
                Console.WriteLine("Role Not Found {0}", searchString);
            }

            #endregion

            #region Get Service Principals

            //*********************************************************************
            // get the Service Principals
            //*********************************************************************
            IPagedCollection<IServicePrincipal> servicePrincipals = null;
            try
            {
                servicePrincipals = activeDirectoryClient.ServicePrincipals.ExecuteAsync().Result;
            }
            catch (Exception e)
            {
                Console.WriteLine("\nError getting Service Principal {0} {1}",
                    e.Message, e.InnerException != null ? e.InnerException.Message : "");
            }
            if (servicePrincipals != null)
            {
                do
                {
                    List<IServicePrincipal> servicePrincipalsList = servicePrincipals.CurrentPage.ToList();
                    foreach (IServicePrincipal servicePrincipal in servicePrincipalsList)
                    {
                        Console.WriteLine("Service Principal AppId: {0}  Name: {1}", servicePrincipal.AppId,
                            servicePrincipal.DisplayName);
                    }
                    servicePrincipals = servicePrincipals.GetNextPageAsync().Result;
                } while (servicePrincipals != null);
            }

            #endregion

            #region Get Applications

            //*********************************************************************
            // get the Application objects
            //*********************************************************************
            IPagedCollection<IApplication> applications = null;
            try
            {
                applications = activeDirectoryClient.Applications.Take(999).ExecuteAsync().Result;
            }
            catch (Exception e)
            {
                Console.WriteLine("\nError getting Applications {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }
            if (applications != null)
            {
                do
                {
                    List<IApplication> appsList = applications.CurrentPage.ToList();
                    foreach (IApplication app in appsList)
                    {
                        Console.WriteLine("Application AppId: {0}  Name: {1}", app.AppId, app.DisplayName);
                    }
                    applications = applications.GetNextPageAsync().Result;
                } while (applications != null);
            }

            #endregion

            #region User License Assignment

            //*********************************************************************************************
            // User License Assignment - assign EnterprisePack license to new user, and disable SharePoint service
            //   first get a list of Tenant's subscriptions and find the "Enterprisepack" one
            //   Enterprise Pack includes service Plans for ExchangeOnline, SharePointOnline and LyncOnline
            //   validate that Subscription is Enabled and there are enough units left to assign to users
            //*********************************************************************************************
            IPagedCollection<ISubscribedSku> skus = null;
            try
            {
                skus = activeDirectoryClient.SubscribedSkus.ExecuteAsync().Result;
            }
            catch (Exception e)
            {
                Console.WriteLine("\nError getting Applications {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }
            if (skus != null)
            {
                do
                {
                    List<ISubscribedSku> subscribedSkus = skus.CurrentPage.ToList();
                    foreach (ISubscribedSku sku in subscribedSkus)
                    {
                        if (sku.SkuPartNumber == "ENTERPRISEPACK")
                        {
                            if ((sku.PrepaidUnits.Enabled.Value > sku.ConsumedUnits) &&
                                (sku.CapabilityStatus == "Enabled"))
                            {
                                // create addLicense object and assign the Enterprise Sku GUID to the skuId
                                // 
                                AssignedLicense addLicense = new AssignedLicense { SkuId = sku.SkuId.Value };

                                // find plan id of SharePoint Service Plan
                                foreach (ServicePlanInfo servicePlan in sku.ServicePlans)
                                {
                                    if (servicePlan.ServicePlanName.Contains("SHAREPOINT"))
                                    {
                                        addLicense.DisabledPlans.Add(servicePlan.ServicePlanId.Value);
                                        break;
                                    }
                                }

                                IList<AssignedLicense> licensesToAdd = new[] { addLicense };
                                IList<Guid> licensesToRemove = new Guid[] { };

                                // attempt to assign the license object to the new user 
                                try
                                {
                                    if (newUser.ObjectId != null)
                                    {
                                        newUser.AssignLicenseAsync(licensesToAdd, licensesToRemove).Wait();
                                        Console.WriteLine("\n User {0} was assigned license {1}",
                                            newUser.DisplayName,
                                            addLicense.SkuId);
                                    }
                                }
                                catch (Exception e)
                                {
                                    Console.WriteLine("\nLicense assingment failed {0} {1}", e.Message,
                                        e.InnerException != null ? e.InnerException.Message : "");
                                }
                            }
                        }
                    }
                    skus = skus.GetNextPageAsync().Result;
                } while (skus != null);
            }

            #endregion

            #region Switch to OAuth Authorization Code Grant (Acting as a user)

            activeDirectoryClient = AuthenticationHelper.GetActiveDirectoryClientAsUser();

            #endregion

            #region Create Application

            //*********************************************************************************************
            // Create a new Application object with App Role Assignment (Direct permission)
            //*********************************************************************************************
            Application appObject = new Application { DisplayName = "Test-Demo App" + Helper.GetRandomString(8) };
            appObject.IdentifierUris.Add("https://localhost/demo/" + Guid.NewGuid());
            appObject.ReplyUrls.Add("https://localhost/demo");
            AppRole appRole = new AppRole();
            appRole.Id = Guid.NewGuid();
            appRole.IsEnabled = true;
            appRole.AllowedMemberTypes.Add("User");
            appRole.DisplayName = "Something";
            appRole.Description = "Anything";
            appRole.Value = "policy.write";
            appObject.AppRoles.Add(appRole);

            // created Keycredential object for the new App object
            KeyCredential keyCredential = new KeyCredential
            {
                StartDate = DateTime.UtcNow,
                EndDate = DateTime.UtcNow.AddYears(1),
                Type = "Symmetric",
                Value = Convert.FromBase64String("g/TMLuxgzurjQ0Sal9wFEzpaX/sI0vBP3IBUE/H/NS4="),
                Usage = "Verify"
            };
            appObject.KeyCredentials.Add(keyCredential);

            try
            {
                activeDirectoryClient.Applications.AddApplicationAsync(appObject).Wait();
                Console.WriteLine("New Application created: " + appObject.ObjectId);
            }
            catch (Exception e)
            {
                Console.WriteLine("Application Creation execption: {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }

            #endregion

            #region Create Service Principal

            //*********************************************************************************************
            // create a new Service principal
            //*********************************************************************************************
            ServicePrincipal newServicePrincpal = new ServicePrincipal();
            if (appObject != null)
            {
                newServicePrincpal.DisplayName = appObject.DisplayName;
                newServicePrincpal.AccountEnabled = true;
                newServicePrincpal.AppId = appObject.AppId;
                try
                {
                    activeDirectoryClient.ServicePrincipals.AddServicePrincipalAsync(newServicePrincpal).Wait();
                    Console.WriteLine("New Service Principal created: " + newServicePrincpal.ObjectId);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Service Principal Creation execption: {0} {1}", e.Message,
                        e.InnerException != null ? e.InnerException.Message : "");
                }
            }

            #endregion

            #region Create an Extension Property

            ExtensionProperty linkedInUserId = new ExtensionProperty
            {
                Name = "linkedInUserId",
                DataType = "String",
                TargetObjects = { "User" }
            };
            try
            {
                appObject.ExtensionProperties.Add(linkedInUserId);
                appObject.UpdateAsync().Wait();
                Console.WriteLine("\nUser object extended successfully.");
            }
            catch (Exception e)
            {
                Console.WriteLine("\nError extending the user object {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }

            #endregion

            #region Manipulate an Extension Property

            try
            {
                if (retrievedUser != null && retrievedUser.ObjectId != null)
                {
                    retrievedUser.SetExtendedProperty(linkedInUserId.Name, "ExtensionPropertyValue");
                    retrievedUser.UpdateAsync().Wait();
                    Console.WriteLine("\nUser {0}'s extended property set successully.", retrievedUser.DisplayName);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("\nError Updating the user object {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }

            #endregion

            #region Get an Extension Property

            try
            {
                if (retrievedUser != null && retrievedUser.ObjectId != null)
                {
                    IReadOnlyDictionary<string, object> extendedProperties = retrievedUser.GetExtendedProperties();
                    object extendedProperty = extendedProperties[linkedInUserId.Name];
                    Console.WriteLine("\n Retrieved User {0}'s extended property value is: {1}.", retrievedUser.DisplayName,
                        extendedProperty);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("\nError Updating the user object {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }

            #endregion

            #region Assign Direct Permission
            try
            {
                User user =
                        (User)activeDirectoryClient.Users.ExecuteAsync().Result.CurrentPage.ToList().FirstOrDefault();
                if (appObject.ObjectId != null && user != null && newServicePrincpal.ObjectId != null)
                {
                    AppRoleAssignment appRoleAssignment = new AppRoleAssignment();
                    appRoleAssignment.Id = appRole.Id;
                    appRoleAssignment.ResourceId = Guid.Parse(newServicePrincpal.ObjectId);
                    appRoleAssignment.PrincipalType = "User";
                    appRoleAssignment.PrincipalId = Guid.Parse(user.ObjectId);
                    user.AppRoleAssignments.Add(appRoleAssignment);
                    user.UpdateAsync().Wait();
                    Console.WriteLine("User {0} is successfully assigned direct permission.", retrievedUser.DisplayName);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Direct Permission Assignment failed: {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }

            #endregion

            #region Get Devices

            //*********************************************************************************************
            // Get a list of Mobile Devices from tenant
            //*********************************************************************************************
            Console.WriteLine("\nGetting Devices");
            IPagedCollection<IDevice> devices = null;
            try
            {
                devices = activeDirectoryClient.Devices.ExecuteAsync().Result;
            }
            catch (Exception e)
            {
                Console.WriteLine("/nError getting devices {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }

            if (devices != null)
            {
                do
                {
                    List<IDevice> devicesList = devices.CurrentPage.ToList();
                    foreach (IDevice device in devicesList)
                    {
                        if (device.ObjectId != null)
                        {
                            Console.WriteLine("Device ID: {0}, Type: {1}", device.DeviceId, device.DeviceOSType);
                            IPagedCollection<IDirectoryObject> registeredOwners = device.RegisteredOwners;
                            if (registeredOwners != null)
                            {
                                do
                                {
                                    List<IDirectoryObject> registeredOwnersList = registeredOwners.CurrentPage.ToList();
                                    foreach (IDirectoryObject owner in registeredOwnersList)
                                    {
                                        Console.WriteLine("Device Owner ID: " + owner.ObjectId);
                                    }
                                    registeredOwners = registeredOwners.GetNextPageAsync().Result;
                                } while (registeredOwners != null);
                            }
                        }
                    }
                    devices = devices.GetNextPageAsync().Result;
                } while (devices != null);
            }

            #endregion

            #region Create New Permission

            //*********************************************************************************************
            // Create new permission object
            //*********************************************************************************************
            OAuth2PermissionGrant permissionObject = new OAuth2PermissionGrant();
            permissionObject.ConsentType = "AllPrincipals";
            permissionObject.Scope = "user_impersonation";
            permissionObject.StartTime = DateTime.Now;
            permissionObject.ExpiryTime = (DateTime.Now).AddMonths(12);

            // resourceId is objectId of the resource, in this case objectId of AzureAd (Graph API)
            permissionObject.ResourceId = "52620afb-80de-4096-a826-95f4ad481686";

            //ClientId = objectId of servicePrincipal
            permissionObject.ClientId = newServicePrincpal.ObjectId;
            try
            {
                activeDirectoryClient.Oauth2PermissionGrants.AddOAuth2PermissionGrantAsync(permissionObject).Wait();
                Console.WriteLine("New Permission object created: " + permissionObject.ObjectId);
            }
            catch (Exception e)
            {
                Console.WriteLine("Permission Creation exception: {0} {1}", e.Message, e.InnerException != null ? e.InnerException.Message : "");
            }

            #endregion

            #region Get All Permissions

            //*********************************************************************************************
            // get all Permission Objects
            //*********************************************************************************************
            Console.WriteLine("\n Getting Permissions");
            IPagedCollection<IOAuth2PermissionGrant> permissions = null;
            try
            {
                permissions = activeDirectoryClient.Oauth2PermissionGrants.ExecuteAsync().Result;
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: {0} {1}", e.Message, e.InnerException != null ? e.InnerException.Message : "");
            }
            if (permissions != null)
            {
                do
                {
                    List<IOAuth2PermissionGrant> perms = permissions.CurrentPage.ToList();
                    foreach (IOAuth2PermissionGrant perm in perms)
                    {
                        Console.WriteLine("Permission: {0}  Name: {1}", perm.ClientId, perm.Scope);
                    }
                    permissions = permissions.GetNextPageAsync().Result;
                } while (permissions != null);
            }

            #endregion

            #region Delete Application

            //*********************************************************************************************
            // Delete Application Objects
            //*********************************************************************************************
            if (appObject.ObjectId != null)
            {
                try
                {
                    appObject.DeleteAsync().Wait();
                    Console.WriteLine("Deleted Application object: " + appObject.ObjectId);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Application Deletion execption: {0} {1}", e.Message,
                        e.InnerException != null ? e.InnerException.Message : "");
                }
            }

            #endregion

            #region Batch Operations

            //*********************************************************************************************
            // Show Batching with 3 operators.  Note: up to 5 operations can be in a batch
            //*********************************************************************************************
            IReadOnlyQueryableSet<User> userQuery = activeDirectoryClient.DirectoryObjects.OfType<User>();
            IReadOnlyQueryableSet<Group> groupsQuery = activeDirectoryClient.DirectoryObjects.OfType<Group>();
            IReadOnlyQueryableSet<DirectoryRole> rolesQuery =
                activeDirectoryClient.DirectoryObjects.OfType<DirectoryRole>();
            try
            {
                IBatchElementResult[] batchResult =
                    activeDirectoryClient.Context.ExecuteBatchAsync(userQuery, groupsQuery, rolesQuery).Result;
                int responseCount = 1;
                foreach (IBatchElementResult result in batchResult)
                {
                    if (result.FailureResult != null)
                    {
                        Console.WriteLine("Failed: {0} ",
                            result.FailureResult.InnerException);
                    }
                    if (result.SuccessResult != null)
                    {
                        Console.WriteLine("Batch Item Result {0} succeeded",
                            responseCount++);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Batch execution failed. : {0} {1}", e.Message,
                    e.InnerException != null ? e.InnerException.Message : "");
            }

            #endregion

            //*********************************************************************************************
            // End of Demo Console App
            //*********************************************************************************************

            Console.WriteLine("\nCompleted at {0} \n Press Any Key to Exit.", currentDateTime);
            Console.ReadKey();
        }
        static void Main()
        {
            // get OAuth token using Client Credentials
            string tenantName = "GraphDir1.onMicrosoft.com";
            string authString = "https://login.windows.net/" + tenantName;

            AuthenticationContext authenticationContext = new AuthenticationContext(authString,false);

            // Config for OAuth client credentials
            string clientId = "118473c2-7619-46e3-a8e4-6da8d5f56e12";
            string clientSecret = "hOrJ0r0TZ4GQ3obp+vk3FZ7JBVP+TX353kNo6QwNq7Q=";
            ClientCredential clientCred = new ClientCredential(clientId, clientSecret);
            string resource = "https://graph.windows.net";
            string token;
            try
            {
                AuthenticationResult authenticationResult = authenticationContext.AcquireToken(resource, clientCred);
                token = authenticationResult.AccessToken;
            }

            catch (AuthenticationException ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Acquiring a token failed with the following error: {0}", ex.Message);
                if (ex.InnerException != null)
                {
                    //You should implement retry and back-off logic per the guidance given here:http://msdn.microsoft.com/en-us/library/dn168916.aspx
                    //InnerException Message will contain the HTTP error status codes mentioned in the link above
                    Console.WriteLine("Error detail: {0}", ex.InnerException.Message);
                }
                Console.ResetColor();
                Console.ReadKey();
                return;
            }

            // record start DateTime of execution
            string CurrentDateTime = DateTime.Now.ToUniversalTime().ToString();

            //*********************************************************************
            // setup Graph connection
            //*********************************************************************
            Guid ClientRequestId = Guid.NewGuid();
            GraphSettings graphSettings = new GraphSettings();
            graphSettings.ApiVersion = "2013-11-08";
            graphSettings.GraphDomainName = "graph.windows.net";
            GraphConnection graphConnection = new GraphConnection(token, ClientRequestId,graphSettings);
            VerifiedDomain initialDomain = new VerifiedDomain();
            VerifiedDomain defaultDomain = new VerifiedDomain();

            //*********************************************************************
            // Get Tenant Details
            // Note: update the string tenantId with your TenantId.
            // This can be retrieved from the login Federation Metadata end point:
            // https://login.windows.net/GraphDir1.onmicrosoft.com/FederationMetadata/2007-06/FederationMetadata.xml
            //  Replace "GraphDir1.onMicrosoft.com" with any domain owned by your organization
            // The returned value from the first xml node "EntityDescriptor", will have a STS URL
            // containing your tenantId e.g. "https://sts.windows.net/4fd2b2f2-ea27-4fe5-a8f3-7b1a7c975f34/" is returned for GraphDir1.onMicrosoft.com
            //*********************************************************************
            string tenantId = "4fd2b2f2-ea27-4fe5-a8f3-7b1a7c975f34";
            GraphObject tenant = graphConnection.Get(typeof(TenantDetail), tenantId);

            if (tenant == null)
            {
                Console.WriteLine("Tenant not found");
            }
            else
            {
                TenantDetail tenantDetail = (TenantDetail)tenant;
                Console.WriteLine("Tenant Display Name: " + tenantDetail.DisplayName);

                // Get the Tenant's Verified Domains
                initialDomain = tenantDetail.VerifiedDomains.First(x => x.Initial.HasValue && x.Initial.Value);
                Console.WriteLine("Initial Domain Name: " + initialDomain.Name);
                defaultDomain = tenantDetail.VerifiedDomains.First(x => x.Default.HasValue && x.Default.Value);
                Console.WriteLine("Default Domain Name: " + defaultDomain.Name);
                foreach (string techContact in tenantDetail.TechnicalNotificationMails)
                {
                    Console.WriteLine("Tenant Tech Contact: " + techContact);
                }
            }
            //*********************************************************************
            // Demonstrate Getting a list of Users with paging (get 4 users), sort by displayName
            //*********************************************************************
            Console.WriteLine("\n Retrieving Users");

            FilterGenerator userFilter = new FilterGenerator();
            userFilter.Top = 4;
            userFilter.OrderByProperty = GraphProperty.DisplayName;
            PagedResults<User> users = graphConnection.List<User>(null, userFilter);
            foreach (User user in users.Results)
            {
                Console.WriteLine("UserObjectId: {0}  UPN: {1}", user.ObjectId, user.UserPrincipalName);
            }

            // if there are more users to retrieve, get the rest of the users, and specify maximum page size 999
            do
            {
                userFilter.Top = 999;
                if (users.PageToken != null)
                {
                    users = graphConnection.List<User>(users.PageToken, userFilter);
                    Console.WriteLine("\n Next page of results");
                }

                foreach (User user in users.Results)
                {
                    Console.WriteLine("DisplayName: {0}  UPN: {1}", user.DisplayName, user.UserPrincipalName);
                }
            } while (users.PageToken != null);

            // search for a single user by UPN
            string searchString = "adam@" + initialDomain.Name;
            FilterGenerator filter = new FilterGenerator();
            Expression filterExpression = ExpressionHelper.CreateEqualsExpression(typeof(User), GraphProperty.UserPrincipalName, searchString );
            filter.QueryFilter = filterExpression;

            User retrievedUser = new User();
            PagedResults<User> pagedUserResults = graphConnection.List<User>(null, filter);

            // should only find one user with the specified UPN
            if (pagedUserResults.Results.Count == 1)
            {
                retrievedUser = pagedUserResults.Results[0] as User;
            }
            else
            {
                Console.WriteLine("User not found {0}", searchString);
            }

            if (retrievedUser.UserPrincipalName != null)
            {
                Console.WriteLine("\n Found User: "******"  UPN: " + retrievedUser.UserPrincipalName);

                // get the user's Manager
                    int count = 0;
                    PagedResults<GraphObject> managers = graphConnection.GetLinkedObjects(retrievedUser, LinkProperty.Manager, null);
                    foreach (GraphObject managerObject in managers.Results)
                    {
                      if (managerObject.ODataTypeName.Contains("User"))
                        {
                          User manager = (User)managers.Results[count];
                          Console.WriteLine(" Manager: {0}  UPN: {1}", manager.DisplayName, manager.UserPrincipalName);
                        }
                      count++;
                    }
                //*********************************************************************
                // get the user's Direct Reports
                //*********************************************************************
                int top = 99;
                PagedResults<GraphObject> directReportObjects = graphConnection.GetLinkedObjects(retrievedUser, LinkProperty.DirectReports, null, top);
                foreach (GraphObject graphObject in directReportObjects.Results)
                {
                    if (graphObject.ODataTypeName.Contains("User"))
                    {
                        User User = (User)graphObject;
                        Console.WriteLine(" DirectReport {0}: {1}  UPN: {2}", User.ObjectType, User.DisplayName, User.UserPrincipalName);
                    }

                    if (graphObject.ODataTypeName.Contains("Contact"))
                    {
                        Contact Contact = (Contact)graphObject;
                        Console.WriteLine(" DirectReport {0}: {1}  Mail: {2} ", Contact.ObjectType, Contact.DisplayName, Contact.Mail);
                    }
                }
                //*********************************************************************
                // get a list of Group IDs that the user is a member of
                //*********************************************************************
                Console.WriteLine("\n {0} is a member of the following Groups (IDs)", retrievedUser.DisplayName);
                bool securityGroupsOnly = false;
                IList<string> usersGroupMembership = graphConnection.GetMemberGroups(retrievedUser, securityGroupsOnly);
                foreach (String groupId in usersGroupMembership)
                {
                    Console.WriteLine("Member of Group ID: "+ groupId);
                }

                //*********************************************************************
                // get the User's Group and Role membership, getting the complete set of objects
                //*********************************************************************
                PagedResults<GraphObject> memberOfObjects = graphConnection.GetLinkedObjects(retrievedUser, LinkProperty.MemberOf, null, top);
                foreach (GraphObject graphObject in memberOfObjects.Results)
                {
                    if (graphObject.ODataTypeName.Contains("Group"))
                    {
                        Group Group = (Group)graphObject;
                        Console.WriteLine(" Group: {0}  Description: {1}", Group.DisplayName, Group.Description);
                    }

                    if (graphObject.ODataTypeName.Contains("Role"))
                    {
                        Role Role = (Role)graphObject;
                        Console.WriteLine(" Role: {0}  Description: {1}", Role.DisplayName, Role.Description);
                    }
                }
            }
            //*********************************************************************
            // People picker
            // Search for a user using text string "ad" match against userPrincipalName, proxyAddresses, displayName, giveName, surname
            //*********************************************************************
            searchString = "ad";
            Console.WriteLine("\nSearching for any user with string {0} in UPN,ProxyAddresses,DisplayName,First or Last Name", searchString);

            FilterGenerator userMatchFilter = new FilterGenerator();
            userMatchFilter.Top = 19;
            Expression firstExpression = ExpressionHelper.CreateStartsWithExpression(typeof(User), GraphProperty.UserPrincipalName, searchString);
            Expression secondExpression = ExpressionHelper.CreateAnyExpression(typeof(User), GraphProperty.ProxyAddresses, "smtp:" + searchString);
            userMatchFilter.QueryFilter = ExpressionHelper.JoinExpressions(firstExpression, secondExpression, ExpressionType.Or);

            Expression thirdExpression = ExpressionHelper.CreateStartsWithExpression(typeof(User), GraphProperty.DisplayName, searchString);
            userMatchFilter.QueryFilter = ExpressionHelper.JoinExpressions(userMatchFilter.QueryFilter, thirdExpression, ExpressionType.Or);

            Expression fourthExpression = ExpressionHelper.CreateStartsWithExpression(typeof(User), GraphProperty.GivenName, searchString);
            userMatchFilter.QueryFilter = ExpressionHelper.JoinExpressions(userMatchFilter.QueryFilter, fourthExpression, ExpressionType.Or);

            Expression fifthExpression = ExpressionHelper.CreateStartsWithExpression(typeof(User), GraphProperty.Surname, searchString);
            userMatchFilter.QueryFilter = ExpressionHelper.JoinExpressions(userMatchFilter.QueryFilter, fifthExpression, ExpressionType.Or);

            PagedResults<User> serachResults = graphConnection.List<User>(null, userMatchFilter);

            if (serachResults.Results.Count > 0)
            {
                foreach (User User in serachResults.Results)
                {
                    Console.WriteLine("User DisplayName: {0}  UPN: {1}", User.DisplayName, User.UserPrincipalName);
                }
            }
            else
            {
                Console.WriteLine("User not found");
            }

            //*********************************************************************
            // Search for a group using a startsWith filter (displayName property)
            //*********************************************************************
            Group retrievedGroup = new Group();
            searchString = "Wash";
            filter.QueryFilter = ExpressionHelper.CreateStartsWithExpression(typeof(Group), GraphProperty.DisplayName, searchString);
            filter.Top = 99;

            PagedResults<Group> pagedGroupResults = graphConnection.List<Group>(null, filter);

            if (pagedGroupResults.Results.Count > 0)
            {
                retrievedGroup = pagedGroupResults.Results[0] as Group;
            }
            else
            {
                Console.WriteLine("Group Not Found");
            }

            if (retrievedGroup.ObjectId != null)
            {
                Console.WriteLine("\n Found Group: " + retrievedGroup.DisplayName + "  " + retrievedGroup.Description);

                //*********************************************************************
                // get the groups' membership using GetAllDirectLinks -
                // Note this method retrieves ALL links in one request - please use this method with care - this
                // may return a very large number of objects
                //*********************************************************************

                GraphObject graphObj = (GraphObject)retrievedGroup;

                IList<GraphObject> members = graphConnection.GetAllDirectLinks(graphObj, LinkProperty.Members);
                if (members.Count > 0)
                {
                    Console.WriteLine(" Members:");
                    foreach (GraphObject graphObject in members)
                    {
                        if (graphObject.ODataTypeName.Contains("User"))
                        {
                            User User = (User)graphObject;
                            Console.WriteLine("User DisplayName: {0}  UPN: {1}", User.DisplayName, User.UserPrincipalName);
                        }

                        if (graphObject.ODataTypeName.Contains("Group"))
                        {
                            Group Group = (Group)graphObject;
                            Console.WriteLine("Group DisplayName: {0}", Group.DisplayName);
                        }

                        if (graphObject.ODataTypeName.Contains("Contact"))
                        {
                            Contact Contact = (Contact)graphObject;
                            Console.WriteLine("Contact DisplayName: {0}", Contact.DisplayName);
                        }
                    }
                }
            }
            //*********************************************************************
            // Search for a Role by displayName
            //*********************************************************************
            searchString = "Company Administrator";
            filter.QueryFilter = ExpressionHelper.CreateStartsWithExpression(typeof(Role), GraphProperty.DisplayName, searchString);
            PagedResults<Role> pagedRoleResults = graphConnection.List<Role>(null, null);

            if (pagedRoleResults.Results.Count > 0)
            {
                foreach (GraphObject graphObject in pagedRoleResults.Results)
                {
                    Role role = graphObject as Role;
                    if (role.DisplayName == searchString.Trim())
                    {
                        Console.WriteLine("\n Found Role: {0} {1} {2} ", role.DisplayName, role.Description, role.ObjectId);
                    }
                }
            }
            else
            {
                Console.WriteLine("Role Not Found {0}",searchString);
            }

            //*********************************************************************
            // get the Service Principals
            //*********************************************************************
            filter.Top = 999;
            filter.QueryFilter = null;
            PagedResults<ServicePrincipal> servicePrincipals = new PagedResults<ServicePrincipal>();
            do
            {
                servicePrincipals = graphConnection.List<ServicePrincipal>(servicePrincipals.PageToken, filter);
                if (servicePrincipals != null)
                {
                    foreach (ServicePrincipal servicePrincipal in servicePrincipals.Results)
                    {
                        Console.WriteLine("Service Principal AppId: {0}  Name: {1}", servicePrincipal.AppId, servicePrincipal.DisplayName);
                    }
                }
            } while (servicePrincipals.PageToken != null);

            //*********************************************************************
            // get the  Application objects
            //*********************************************************************
            filter.Top = 999;
            PagedResults<Application> applications = new PagedResults<Application>();
            do
            {
                applications = graphConnection.List<Application>(applications.PageToken, filter);
                if (applications != null)
                {
                    foreach (Application application in applications.Results)
                    {
                        Console.WriteLine("Application AppId: {0}  Name: {1}", application.AppId, application.DisplayName);
                    }
                }
             }while (applications.PageToken != null);

            string targetAppId = applications.Results[0].ObjectId;

            //********************************************************************************************
            //  We'll now switch to Authenticating using OAuth Authorization Code Grant
            //  which includes user Authentication/Delegation
            //*********************************************************************************************
            var redirectUri = new Uri("https://localhost");
            string clientIdForUserAuthn = "66133929-66a4-4edc-aaee-13b04b03207d";
            AuthenticationResult userAuthnResult = null;
            try
            {
                userAuthnResult = authenticationContext.AcquireToken(resource, clientIdForUserAuthn, redirectUri, PromptBehavior.Always);
                token = userAuthnResult.AccessToken;
                Console.WriteLine("\n Welcome " + userAuthnResult.UserInfo.GivenName + " " + userAuthnResult.UserInfo.FamilyName);
            }
            catch (AuthenticationException ex)
            {
                string message = ex.Message;
                if (ex.InnerException != null)
                    message += "InnerException : " + ex.InnerException.Message;
                Console.WriteLine(message);
                Console.ReadKey();
                return;
            }

            // re-establish Graph connection using the new token
            graphConnection = new GraphConnection(token, ClientRequestId, graphSettings);

            //*********************************************************************************************
            // Create a new User with a temp password
            //*********************************************************************************************
            User userToBeAdded = new User();
            userToBeAdded.DisplayName = "Sample App Demo User";
            userToBeAdded.UserPrincipalName = "SampleAppDemoUser@" + defaultDomain.Name;
            userToBeAdded.AccountEnabled = true;
            userToBeAdded.MailNickname = "SampleAppDemoUser";
            userToBeAdded.PasswordProfile = new PasswordProfile();
            userToBeAdded.PasswordProfile.Password = "******";
            userToBeAdded.PasswordProfile.ForceChangePasswordNextLogin = true;
            userToBeAdded.UsageLocation = "US";
            User newlyCreatedUser = new User();
            try
            {
              newlyCreatedUser = graphConnection.Add<User>(userToBeAdded);
              Console.WriteLine("\nNew User {0} was created", userToBeAdded.DisplayName);
            }
            catch (GraphException graphException)
            {
                Console.WriteLine("\nError creating new user {0} {1}", graphException.Code, graphException.Message);
            }

            //*********************************************************************************************
            // update the newly created user's Password, PasswordPolicies and City
            //*********************************************************************************************
            if (newlyCreatedUser.ObjectId != null)
            {
                string userObjectId = newlyCreatedUser.ObjectId;

                // update User's city and reset their User's password
                User updateUser = graphConnection.Get<User>(userObjectId);
                updateUser.City = "Seattle";
                PasswordProfile passwordProfile = new PasswordProfile();
                passwordProfile.Password = "******";
                passwordProfile.ForceChangePasswordNextLogin = false;
                updateUser.PasswordProfile = passwordProfile;
                updateUser.PasswordPolicies = "DisablePasswordExpiration, DisableStrongPassword";
                try
                {
                    graphConnection.Update(updateUser);
                    Console.WriteLine("\nUser {0} was updated", updateUser.DisplayName);
                }
                catch (GraphException graphException)
                {
                    Console.WriteLine("\nError Updating the user {0} {1}", graphException.Code, graphException.Message);
                }

                //*********************************************************************************************
                // Add, then retrieve a thumbnailPhoto for the newly created user
                //*********************************************************************************************
                Bitmap thumbnailPhoto = new Bitmap(20, 20);
                thumbnailPhoto.SetPixel(5, 5, Color.Beige);
                thumbnailPhoto.SetPixel(5, 6, Color.Beige);
                thumbnailPhoto.SetPixel(6, 5, Color.Beige);
                thumbnailPhoto.SetPixel(6, 6, Color.Beige);

                using (MemoryStream ms = new MemoryStream())
                {
                    thumbnailPhoto.Save(ms, ImageFormat.Jpeg);
                    graphConnection.SetStreamProperty(newlyCreatedUser, GraphProperty.ThumbnailPhoto, ms, "image/jpeg");
                    //  graphConnection.SetStreamProperty(newlyCreatedUser, "thumbnailPhoto", ms, "image/jpeg");
                }

                using (Stream ms = graphConnection.GetStreamProperty(newlyCreatedUser, GraphProperty.ThumbnailPhoto, "image/jpeg"))
                {
                    Image jpegImage = Image.FromStream(ms);
                }

                //*********************************************************************************************
                // User License Assignment - assign EnterprisePack license to new user, and disable SharePoint service
                //   first get a list of Tenant's subscriptions and find the "Enterprisepack" one
                //   Enterprise Pack includes service Plans for ExchangeOnline, SharePointOnline and LyncOnline
                //   validate that Subscription is Enabled and there are enough units left to assign to users
                //*********************************************************************************************
                PagedResults<SubscribedSku> skus = graphConnection.List<SubscribedSku>(null, null);
                foreach (SubscribedSku sku in skus.Results)
                {
                    if (sku.SkuPartNumber == "ENTERPRISEPACK")
                        if ((sku.PrepaidUnits.Enabled.Value > sku.ConsumedUnits) && (sku.CapabilityStatus == "Enabled"))
                        {
                            // create addLicense object and assign the Enterprise Sku GUID to the skuId
                            //
                            AssignedLicense addLicense = new AssignedLicense();
                            addLicense.SkuId = sku.SkuId.Value;

                            // find plan id of SharePoint Service Plan
                            foreach (ServicePlanInfo servicePlan in sku.ServicePlans)
                            {
                                if (servicePlan.ServicePlanName.Contains("SHAREPOINT"))
                                {
                                    addLicense.DisabledPlans.Add(servicePlan.ServicePlanId.Value);
                                    break;
                                }
                            }

                            IList<AssignedLicense> licensesToAdd = new AssignedLicense[] { addLicense };
                            IList<Guid> licensesToRemove = new Guid[] { };

                            // attempt to assign the license object to the new user
                            try
                            {
                                graphConnection.AssignLicense(newlyCreatedUser, licensesToAdd, licensesToRemove);
                                Console.WriteLine("\n User {0} was assigned license {1}", newlyCreatedUser.DisplayName, addLicense.SkuId);
                            }
                            catch (GraphException graphException)
                            {
                                Console.WriteLine("\nLicense assingment failed {0} {1}", graphException.Code, graphException.Message);
                            }

                        }
                }

                //*********************************************************************************************
                // Add User to the "WA" Group
                //*********************************************************************************************
                if (retrievedGroup.ObjectId != null)
                {
                    try
                    {
                        graphConnection.AddLink(retrievedGroup, newlyCreatedUser, LinkProperty.Members);
                        Console.WriteLine("\nUser {0} was added to Group {1}", newlyCreatedUser.DisplayName, retrievedGroup.DisplayName);
                    }
                    catch (GraphException graphException)
                    {
                        Console.WriteLine("\nAdding user to group failed {0} {1}", graphException.Code, graphException.Message);
                    }
                }

                //*********************************************************************************************
                // Create a new Group
                //*********************************************************************************************
                Group CaliforniaEmployees = new Group();
                CaliforniaEmployees.DisplayName = "California Employees";
                CaliforniaEmployees.Description = "Employees in the state of California";
                CaliforniaEmployees.MailNickname = "CalEmployees";
                CaliforniaEmployees.MailEnabled = false;
                CaliforniaEmployees.SecurityEnabled = true;
                Group newGroup = null;
                try
                {
                    newGroup = graphConnection.Add<Group>(CaliforniaEmployees);
                    Console.WriteLine("\nNew Group {0} was created", newGroup.DisplayName);
                }
                catch (GraphException graphException)
                {
                    Console.WriteLine("\nError creating new Group {0} {1}", graphException.Code, graphException.Message);
                }

                //*********************************************************************************************
                // Add the new User member to the new Group
                //*********************************************************************************************
                if (newGroup.ObjectId != null)
                {
                    try
                    {
                        graphConnection.AddLink(newGroup, newlyCreatedUser, LinkProperty.Members);
                        Console.WriteLine("\nUser {0} was added to Group {1}", newlyCreatedUser.DisplayName, newGroup.DisplayName);
                    }
                    catch (GraphException graphException)
                    {
                        Console.WriteLine("\nAdding user to group failed {0} {1}", graphException.Code, graphException.Message);
                    }
                }

                //*********************************************************************************************
                // Delete the user that we just created
                //*********************************************************************************************
                if (newlyCreatedUser.ObjectId != null)
                {
                    try
                    {
                        graphConnection.Delete(newlyCreatedUser);
                        Console.WriteLine("\nUser {0} was deleted", newlyCreatedUser.DisplayName);
                    }
                    catch (GraphException graphException)
                    {
                        Console.WriteLine("Deleting User failed {0} {1}", graphException.Code, graphException.Message);
                    }
                }

                //*********************************************************************************************
                // Delete the Group that we just created
                //*********************************************************************************************
                if (newGroup.ObjectId != null)
                {
                    try
                    {
                        graphConnection.Delete(newGroup);
                        Console.WriteLine("\nGroup {0} was deleted", newGroup.DisplayName);
                    }
                    catch (GraphException graphException)
                    {
                        Console.WriteLine("Deleting Group failed: {0} {1}", graphException.Code, graphException.Message);
                    }
                }

            }

            //*********************************************************************************************
            // Get a list of Mobile Devices from tenant
            //*********************************************************************************************
            Console.WriteLine("\nGetting Devices");
            FilterGenerator deviceFilter = new FilterGenerator();
            deviceFilter.Top = 999;
            PagedResults<Device> devices = graphConnection.List<Device>(null, deviceFilter);
            foreach(Device device in devices.Results)
            {
                if (device.ObjectId !=null)
                {
                    Console.WriteLine("Device ID: {0}, Type: {1}", device.DeviceId, device.DeviceOSType);
                    foreach (GraphObject owner in device.RegisteredOwners)
                    {
                        Console.WriteLine("Device Owner ID: " + owner.ObjectId);
                    }
                }
            }

            //*********************************************************************************************
            // Create a new Application object
            //*********************************************************************************************
            Application appObject = new Application();
            appObject.DisplayName = "Test-Demo App";
            appObject.IdentifierUris.Add("https://localhost/demo/" + Guid.NewGuid().ToString());
            appObject.ReplyUrls.Add("https://localhost/demo");

            // created Keycredential object for the new App object
            KeyCredential KeyCredential = new KeyCredential();
            KeyCredential.StartDate = DateTime.UtcNow;
            KeyCredential.EndDate = DateTime.UtcNow.AddYears(1);
            KeyCredential.Type = "Symmetric";
            KeyCredential.Value = Convert.FromBase64String("g/TMLuxgzurjQ0Sal9wFEzpaX/sI0vBP3IBUE/H/NS4=");
            KeyCredential.Usage = "Verify";
            appObject.KeyCredentials.Add(KeyCredential);

            GraphObject newApp = null;
            try
            {
                newApp = graphConnection.Add(appObject);
                Console.WriteLine("New Application created: " + newApp.ObjectId);
            }
            catch (GraphException graphException)
            {
                Console.WriteLine("Application Creation execption: {0} {1}", graphException.Code, graphException.Message);
            }

            // Get the application object that was just created
            if (newApp != null)
            {
                GraphObject app = graphConnection.Get(typeof(Application), newApp.ObjectId);
                Application retrievedApp = (Application)app;

                //*********************************************************************************************
                // create a new Service principal
                //*********************************************************************************************
                ServicePrincipal newServicePrincpal = new ServicePrincipal();
                newServicePrincpal.DisplayName = "Test-Demo App";
                newServicePrincpal.AccountEnabled = true;
                newServicePrincpal.AppId = retrievedApp.AppId;

                GraphObject newSP = null;
                try
                {
                    newSP = graphConnection.Add<ServicePrincipal>(newServicePrincpal);
                    //    newSP = graphConnection.Add(newServicePrincpal);
                    Console.WriteLine("New Service Principal created: " + newSP.ObjectId);
                }
                catch (GraphException graphException)
                {
                    Console.WriteLine("Service Principal Creation execption: {0} {1}", graphException.Code, graphException.Message);
                }

                //*********************************************************************************************
                // get all Permission Objects
                //*********************************************************************************************
                Console.WriteLine("\n Getting Permissions");
                filter.Top = 999;
                PagedResults<Permission> permissions = new PagedResults<Permission>();
                do
                {
                    try
                    {
                        permissions = graphConnection.List<Permission>(permissions.PageToken, filter);
                    }
                    catch (GraphException graphException)
                    {
                        Console.WriteLine("Error: {0} {1}", graphException.Code, graphException.Message);
                        break;
                    }

                    foreach (Permission permission in permissions.Results)
                    {
                        Console.WriteLine("Permission: {0}  Name: {1}", permission.ClientId, permission.Scope);
                    }

                } while (permissions.PageToken != null);

                //*********************************************************************************************
                // Create new permission object
                //*********************************************************************************************
                Permission permissionObject = new Permission();
                permissionObject.ConsentType = "AllPrincipals";
                permissionObject.Scope = "user_impersonation";
                permissionObject.StartTime = DateTime.Now;
                permissionObject.ExpiryTime = (DateTime.Now).AddMonths(12);

                // resourceId is objectId of the resource, in this case objectId of AzureAd (Graph API)
                permissionObject.ResourceId = "dbf73c3e-e80b-495b-a82f-2f772bb0a417";

                //ClientId = objectId of servicePrincipal
                permissionObject.ClientId = newSP.ObjectId;

                GraphObject newPermission = null;
                try
                {
                    newPermission = graphConnection.Add(permissionObject);
                    Console.WriteLine("New Permission object created: " + newPermission.ObjectId);
                }
                catch (GraphException graphException)
                {
                    Console.WriteLine("Permission Creation exception: {0} {1}", graphException.Code, graphException.Message);
                }

                //*********************************************************************************************
                // Delete Application Objects
                //*********************************************************************************************

                if (retrievedApp.ObjectId != null)
                {
                    try
                    {
                        graphConnection.Delete(retrievedApp);
                        Console.WriteLine("Deleting Application object: " + retrievedApp.ObjectId);
                    }
                    catch (GraphException graphException)
                    {
                        Console.WriteLine("Application Deletion execption: {0} {1}", graphException.Code, graphException.Message);
                    }
                }
            }

            //*********************************************************************************************
            // Show Batching with 3 operators.  Note: up to 5 operations can be in a batch
            //*********************************************************************************************
            // get users
            Console.WriteLine("\n Executing Batch Request");
            BatchRequestItem firstItem = new BatchRequestItem(
                                        "GET",
                                        false,
                                        Utils.GetListUri<User>(graphConnection, null, new FilterGenerator()),
                                        null,
                                        String.Empty);

            // get members of a Group
            Uri membersUri = Utils.GetRequestUri<Group>(graphConnection, retrievedGroup.ObjectId, "members");

            BatchRequestItem secondItem = new BatchRequestItem(
                                        "GET",
                                        false,
                                        new Uri(membersUri.ToString()),
                                        null,
                                        String.Empty);

            // update an existing group's Description property

            retrievedGroup.Description = "New Employees in Washington State";

            BatchRequestItem thirdItem = new BatchRequestItem(
                                           "Patch",
                                            true,
                                            Utils.GetRequestUri<Group>(graphConnection,retrievedGroup.ObjectId),
                                            null,
                                            retrievedGroup.ToJson(true));

            // Execute the batch requst
            IList<BatchRequestItem> batchRequest = new BatchRequestItem[] { firstItem, secondItem, thirdItem };
            IList<BatchResponseItem> batchResponses = graphConnection.ExecuteBatch(batchRequest);

            int responseCount = 0;
            foreach (BatchResponseItem responseItem in batchResponses)
            {
                if (responseItem.Failed)
                {
                    Console.WriteLine("Failed: {0} {1}",
                                    responseItem.Exception.Code,
                                    responseItem.Exception.ErrorMessage);
                }
                else
                {
                    Console.WriteLine("Batch Item Result {0} succeeded {1}",
                                     responseCount++,
                                     !responseItem.Failed);
                }
            }

            // this next section shows how to access the signed-in user's mailbox.
            // First we get a new token for Office365 Exchange Online Resource
            // using the multi-resource refresh token tha was included when the previoius
            // token was acquired.
            // We can now request a new token for Office365 Exchange Online.
            //
            string office365Emailresource = "https://outlook.office365.com/";
            string office365Token = null;
            if (userAuthnResult.IsMultipleResourceRefreshToken)
            {
                userAuthnResult = authenticationContext.AcquireTokenByRefreshToken(userAuthnResult.RefreshToken, clientIdForUserAuthn, office365Emailresource);
                office365Token = userAuthnResult.AccessToken;

                //
                // Call the Office365 API and retrieve the top item from the user's mailbox.
                //
                string requestUrl = "https://outlook.office365.com/EWS/OData/Me/Inbox/Messages?$top=1";
                WebRequest getMailboxRequest;
                getMailboxRequest = WebRequest.Create(requestUrl);
                getMailboxRequest.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + office365Token);
                Console.WriteLine("\n Getting the User's Mailbox Contents \n");

                //
                // Read the contents of the user's mailbox, and display to the console.
                //
                Stream objStream = null;
                try
                {
                    objStream = getMailboxRequest.GetResponse().GetResponseStream();
                    StreamReader objReader = new StreamReader(objStream);

                    string sLine = "";
                    int i = 0;

                    while (sLine != null)
                    {
                        i++;
                        sLine = objReader.ReadLine();
                        if (sLine != null)
                        {
                            Console.WriteLine("{0}:{1}", i, sLine);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("\n Error Getting User's Mailbox: {0} \n", ex.Message);
                }
            }

            //*********************************************************************************************
            // End of Demo Console App
            //*********************************************************************************************
            Console.WriteLine("\nCompleted at {0} \n ClientRequestId: {1}", CurrentDateTime, ClientRequestId);
            Console.ReadKey();
            return;
        }