/// <summary>
        /// Get an Office 365 Group (i.e. Unified Group) by Id
        /// </summary>
        /// <param name="groupId">The ID of the Office 365 Group</param>
        /// <param name="accessToken">The OAuth 2.0 Access Token to use for invoking the Microsoft Graph</param>
        /// <param name="includeSite">Defines whether to return details about the Modern SharePoint Site backing the group. Default is true.</param>
        /// <param name="retryCount">Number of times to retry the request in case of throttling</param>
        /// <param name="delay">Milliseconds to wait before retrying the request. The delay will be increased (doubled) every retry</param>
        /// <param name="includeClassification">Defines whether to return classification value of the unified group. Default is true.</param>
        public static UnifiedGroupEntity GetUnifiedGroup(String groupId, String accessToken, int retryCount = 10, int delay = 500, bool includeSite = true, bool includeClassification = false)
        {
            if (String.IsNullOrEmpty(groupId))
            {
                throw new ArgumentNullException(nameof(groupId));
            }

            if (String.IsNullOrEmpty(accessToken))
            {
                throw new ArgumentNullException(nameof(accessToken));
            }

            UnifiedGroupEntity result = null;

            try
            {
                // Use a synchronous model to invoke the asynchronous process
                result = Task.Run(async() =>
                {
                    UnifiedGroupEntity group = null;

                    var graphClient = CreateGraphClient(accessToken, retryCount, delay);

                    var g = await graphClient.Groups[groupId].Request().GetAsync();

                    group = new UnifiedGroupEntity
                    {
                        GroupId      = g.Id,
                        DisplayName  = g.DisplayName,
                        Description  = g.Description,
                        Mail         = g.Mail,
                        MailNickname = g.MailNickname
                    };
                    if (includeSite)
                    {
                        try
                        {
                            group.SiteUrl = GetUnifiedGroupSiteUrl(groupId, accessToken);
                        }
                        catch (ServiceException e)
                        {
                            group.SiteUrl = e.Error.Message;
                        }
                    }

                    if (includeClassification)
                    {
                        group.Classification = GetGroupClassification(groupId, accessToken);
                    }

                    return(group);
                }).GetAwaiter().GetResult();
            }
            catch (ServiceException ex)
            {
                Log.Error(Constants.LOGGING_SOURCE, CoreResources.GraphExtensions_ErrorOccured, ex.Error.Message);
                throw;
            }
            return(result);
        }
Example #2
0
        protected override void ExecuteCmdlet()
        {
            UnifiedGroupEntity group = null;

            if (Identity != null)
            {
                // We have to retrieve a specific group
                if (Identity.Group != null)
                {
                    group = UnifiedGroupsUtility.GetUnifiedGroup(Identity.Group.GroupId, AccessToken, includeSite: false);
                }
                else if (!String.IsNullOrEmpty(Identity.GroupId))
                {
                    group = UnifiedGroupsUtility.GetUnifiedGroup(Identity.GroupId, AccessToken, includeSite: false);
                }
            }

            if (group != null)
            {
                // Get Owners of the group.

                List <UnifiedGroupUser> owners = UnifiedGroupsUtility.GetUnifiedGroupOwners(group, AccessToken);
                WriteObject(owners);
            }
        }
        protected override void ExecuteCmdlet()
        {
            UnifiedGroupEntity        group  = null;
            List <UnifiedGroupEntity> groups = null;

#pragma warning disable 0618
            var includeSiteUrl = ParameterSpecified(nameof(ExcludeSiteUrl)) ? !ExcludeSiteUrl.ToBool() : IncludeSiteUrl.ToBool();
#pragma warning restore 0618

            if (Identity != null)
            {
                group = Identity.GetGroup(AccessToken, includeSite: includeSiteUrl);
            }
            else
            {
                groups = UnifiedGroupsUtility.GetUnifiedGroups(AccessToken, includeSite: IncludeSiteUrl, includeClassification: IncludeClassification.IsPresent, includeHasTeam: IncludeHasTeam.IsPresent);
            }

            if (group != null)
            {
                WriteObject(group);
            }
            else if (groups != null)
            {
                WriteObject(groups, true);
            }
        }
Example #4
0
        protected override void ExecuteCmdlet()
        {
            UnifiedGroupEntity group = null;

            if (Identity != null)
            {
                group = Identity.GetGroup(AccessToken);
            }

            Stream groupLogoStream = null;

            if (group != null)
            {
                if (GroupLogoPath != null)
                {
                    if (!Path.IsPathRooted(GroupLogoPath))
                    {
                        GroupLogoPath = Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, GroupLogoPath);
                    }
                    groupLogoStream = new FileStream(GroupLogoPath, FileMode.Open, FileAccess.Read);
                }

                UnifiedGroupsUtility.UpdateUnifiedGroup(group.GroupId, AccessToken, displayName: DisplayName,
                                                        description: Description, owners: Owners, members: Members, groupLogo: groupLogoStream, isPrivate: IsPrivate);
            }
            else
            {
                WriteError(new ErrorRecord(new Exception("Group not found"), "GROUPNOTFOUND", ErrorCategory.ObjectNotFound, this));
            }
        }
Example #5
0
        protected override void ExecuteCmdlet()
        {
            UnifiedGroupEntity group = null;

            if (Identity != null)
            {
                // We have to retrieve a specific group
                if (Identity.Group != null)
                {
                    group = UnifiedGroupsUtility.GetUnifiedGroup(Identity.Group.GroupId, AccessToken);
                }
                else if (!String.IsNullOrEmpty(Identity.GroupId))
                {
                    group = UnifiedGroupsUtility.GetUnifiedGroup(Identity.GroupId, AccessToken);
                }
            }

            Stream groupLogoStream = null;

            if (group != null)
            {
                if (GroupLogoPath != null)
                {
                    if (!Path.IsPathRooted(GroupLogoPath))
                    {
                        GroupLogoPath = Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, GroupLogoPath);
                    }
                    groupLogoStream = new FileStream(GroupLogoPath, FileMode.Open, FileAccess.Read);
                }
                UnifiedGroupsUtility.UpdateUnifiedGroup(group.GroupId, AccessToken, displayName: DisplayName,
                                                        description: Description, groupLogo: groupLogoStream);
            }
        }
Example #6
0
        public UnifiedGroupEntity GetGroup(string accessToken, bool includeClassification = false)
        {
            UnifiedGroupEntity group = null;

            if (Group != null)
            {
                group = UnifiedGroupsUtility.GetUnifiedGroup(Group.GroupId, accessToken, includeClassification: includeClassification);
            }
            else if (!String.IsNullOrEmpty(GroupId))
            {
                group = UnifiedGroupsUtility.GetUnifiedGroup(GroupId, accessToken, includeClassification: includeClassification);
            }
            else if (!string.IsNullOrEmpty(DisplayName))
            {
                var groups = UnifiedGroupsUtility.GetUnifiedGroups(accessToken, DisplayName, includeSite: true, includeClassification: includeClassification);
                if (groups == null || groups.Count == 0)
                {
                    groups = UnifiedGroupsUtility.GetUnifiedGroups(accessToken, mailNickname: DisplayName, includeSite: true, includeClassification: includeClassification);
                }
                if (groups != null && groups.Any())
                {
                    group = groups.FirstOrDefault();
                }
            }
            return(group);
        }
        protected override void ExecuteCmdlet()
        {
            UnifiedGroupEntity group = null;

            if (Identity != null)
            {
                group = Identity.GetGroup(AccessToken);
            }

            Stream groupLogoStream = null;

            if (group != null)
            {
                if (GroupLogoPath != null)
                {
                    if (!Path.IsPathRooted(GroupLogoPath))
                    {
                        GroupLogoPath = Path.Combine(SessionState.Path.CurrentFileSystemLocation.Path, GroupLogoPath);
                    }
                    groupLogoStream = new FileStream(GroupLogoPath, FileMode.Open, FileAccess.Read);
                }
                bool?isPrivateGroup = null;
                if (IsPrivate.IsPresent)
                {
                    isPrivateGroup = IsPrivate.ToBool();
                }
                try
                {
                    UnifiedGroupsUtility.UpdateUnifiedGroup(
                        groupId: group.GroupId,
                        accessToken: AccessToken,
                        displayName: DisplayName,
                        description: Description,
                        owners: Owners,
                        members: Members,
                        groupLogo: groupLogoStream,
                        isPrivate: isPrivateGroup,
                        createTeam: CreateTeam);

                    if (ParameterSpecified(nameof(HideFromAddressLists)) || ParameterSpecified(nameof(HideFromOutlookClients)))
                    {
                        // For this scenario a separate call needs to be made
                        UnifiedGroupsUtility.SetUnifiedGroupVisibility(group.GroupId, AccessToken, HideFromAddressLists, HideFromOutlookClients);
                    }
                }
                catch (Exception e)
                {
                    while (e.InnerException != null)
                    {
                        e = e.InnerException;
                    }
                    WriteError(new ErrorRecord(e, "GROUPUPDATEFAILED", ErrorCategory.InvalidOperation, this));
                }
            }
            else
            {
                WriteError(new ErrorRecord(new Exception("Group not found"), "GROUPNOTFOUND", ErrorCategory.ObjectNotFound, this));
            }
        }
        /// <summary>
        /// Returns all the Owners of an Office 365 group.
        /// </summary>
        /// <param name="group">The Office 365 group object of type UnifiedGroupEntity</param>
        /// <param name="accessToken">The OAuth 2.0 Access Token to use for invoking the Microsoft Graph</param>
        /// <param name="retryCount">Number of times to retry the request in case of throttling</param>
        /// <param name="delay">Milliseconds to wait before retrying the request. The delay will be increased (doubled) every retry</param>
        /// <returns>Owners of an Office 365 group as a list of UnifiedGroupUser entity</returns>
        public static List <UnifiedGroupUser> GetUnifiedGroupOwners(UnifiedGroupEntity group, string accessToken, int retryCount = 10, int delay = 500)
        {
            List <UnifiedGroupUser> unifiedGroupUsers           = null;
            List <User>             unifiedGroupGraphUsers      = null;
            IGroupOwnersCollectionWithReferencesPage groupUsers = null;

            if (String.IsNullOrEmpty(accessToken))
            {
                throw new ArgumentNullException(nameof(accessToken));
            }

            try
            {
                var result = Task.Run(async() =>
                {
                    var graphClient = CreateGraphClient(accessToken, retryCount, delay);

                    // Get the owners of an Office 365 group.
                    groupUsers = await graphClient.Groups[group.GroupId].Owners.Request().GetAsync();
                    if (groupUsers.CurrentPage != null && groupUsers.CurrentPage.Count > 0)
                    {
                        unifiedGroupGraphUsers = new List <User>();
                        GenerateGraphUserCollection(groupUsers.CurrentPage, unifiedGroupGraphUsers);
                    }

                    // Retrieve users when the results are paged.
                    while (groupUsers.NextPageRequest != null)
                    {
                        groupUsers = groupUsers.NextPageRequest.GetAsync().GetAwaiter().GetResult();
                        if (groupUsers.CurrentPage != null && groupUsers.CurrentPage.Count > 0)
                        {
                            GenerateGraphUserCollection(groupUsers.CurrentPage, unifiedGroupGraphUsers);
                        }
                    }

                    // Create the collection of type OfficeDevPnP 'UnifiedGroupUser' after all users are retrieved, including paged data.
                    if (unifiedGroupGraphUsers != null && unifiedGroupGraphUsers.Count > 0)
                    {
                        unifiedGroupUsers = new List <UnifiedGroupUser>();
                        foreach (User usr in unifiedGroupGraphUsers)
                        {
                            UnifiedGroupUser groupUser  = new UnifiedGroupUser();
                            groupUser.UserPrincipalName = usr.UserPrincipalName != null ? usr.UserPrincipalName : string.Empty;
                            groupUser.DisplayName       = usr.DisplayName != null ? usr.DisplayName : string.Empty;
                            unifiedGroupUsers.Add(groupUser);
                        }
                    }
                    return(unifiedGroupUsers);
                }).GetAwaiter().GetResult();
            }
            catch (ServiceException ex)
            {
                Log.Error(Constants.LOGGING_SOURCE, CoreResources.GraphExtensions_ErrorOccured, ex.Error.Message);
                throw;
            }
            return(unifiedGroupUsers);
        }
        protected override void ExecuteCmdlet()
        {
            if (Identity != null)
            {
                UnifiedGroupEntity group = Identity.GetGroup(AccessToken);

                if (group != null)
                {
                    UnifiedGroupsUtility.DeleteUnifiedGroup(group.GroupId, AccessToken);
                }
            }
        }
        protected override void ExecuteCmdlet()
        {
            UnifiedGroupEntity group = null;

            if (Identity != null)
            {
                group = Identity.GetGroup(AccessToken);
            }

            if (group != null)
            {
                UnifiedGroupsUtility.AddUnifiedGroupMembers(group.GroupId, Users, AccessToken, RemoveExisting.ToBool());
            }
        }
Example #11
0
        protected override void ExecuteCmdlet()
        {
            UnifiedGroupEntity group = null;

            if (Identity != null)
            {
                group = Identity.GetGroup(AccessToken);
            }

            if (group != null)
            {
                UnifiedGroupsUtility.RemoveUnifiedGroupOwners(group.GroupId, Users, AccessToken);
            }
        }
Example #12
0
        protected override void ExecuteCmdlet()
        {
            UnifiedGroupEntity group = null;

            if (Identity != null)
            {
                group = Identity.GetGroup(AccessToken);
            }

            if (group != null)
            {
                UnifiedGroupsUtility.ClearUnifiedGroupMembers(group.GroupId, AccessToken);
            }
        }
Example #13
0
        public UnifiedGroupEntity GetDeletedGroup(string accessToken)
        {
            UnifiedGroupEntity group = null;

            if (Group != null)
            {
                group = UnifiedGroupsUtility.GetDeletedUnifiedGroup(Group.GroupId, accessToken);
            }
            else if (!string.IsNullOrEmpty(GroupId))
            {
                group = UnifiedGroupsUtility.GetDeletedUnifiedGroup(GroupId, accessToken);
            }

            return(group);
        }
        protected override void ExecuteCmdlet()
        {
            UnifiedGroupEntity group = null;

            if (Identity != null)
            {
                group = Identity.GetGroup(AccessToken, false);
            }

            if (group != null)
            {
                // Get Owners of the group
                List <UnifiedGroupUser> owners = UnifiedGroupsUtility.GetUnifiedGroupOwners(group, AccessToken);
                WriteObject(owners);
            }
        }
Example #15
0
        protected override void ExecuteCmdlet()
        {
            if (PnPConnection.CurrentConnection.ClientId == PnPConnection.PnPManagementShellClientId)
            {
                PnPConnection.CurrentConnection.Scopes = new[] { "Group.ReadWrite.All" };
            }

            UnifiedGroupEntity group = null;

            if (Identity != null)
            {
                group = Identity.GetGroup(AccessToken, false);
            }

            if (group != null)
            {
                UnifiedGroupsUtility.AddUnifiedGroupMembers(group.GroupId, Users, AccessToken, RemoveExisting.ToBool());
            }
        }
Example #16
0
        protected override void ExecuteCmdlet()
        {
            UnifiedGroupEntity        group  = null;
            List <UnifiedGroupEntity> groups = null;

            if (Identity != null)
            {
                // We have to retrieve a specific group
                if (Identity.Group != null)
                {
                    group = UnifiedGroupsUtility.GetUnifiedGroup(Identity.Group.GroupId, AccessToken, includeSite: !ExcludeSiteUrl.IsPresent);
                }
                else if (!String.IsNullOrEmpty(Identity.DisplayName))
                {
                    groups = UnifiedGroupsUtility.ListUnifiedGroups(AccessToken, Identity.DisplayName, includeSite: !ExcludeSiteUrl.IsPresent);
                    if (groups == null || groups.Count == 0)
                    {
                        groups = UnifiedGroupsUtility.ListUnifiedGroups(AccessToken, mailNickname: Identity.DisplayName, includeSite: !ExcludeSiteUrl.IsPresent);
                    }
                }
                else if (!String.IsNullOrEmpty(Identity.GroupId))
                {
                    group = UnifiedGroupsUtility.GetUnifiedGroup(Identity.GroupId, AccessToken, includeSite: !ExcludeSiteUrl.IsPresent);
                }
            }
            else
            {
                // Retrieve all the groups
                groups = UnifiedGroupsUtility.ListUnifiedGroups(AccessToken, includeSite: !ExcludeSiteUrl.IsPresent);
            }

            if (group != null)
            {
                WriteObject(group);
            }
            else if (groups != null)
            {
                WriteObject(groups, true);
            }
        }
        protected override void ExecuteCmdlet()
        {
            if (Identity != null)
            {
                UnifiedGroupEntity group = null;

                // We have to retrieve a specific group
                if (Identity.Group != null)
                {
                    group = UnifiedGroupsUtility.GetUnifiedGroup(Identity.Group.GroupId, AccessToken);
                }
                else if (!String.IsNullOrEmpty(Identity.GroupId))
                {
                    group = UnifiedGroupsUtility.GetUnifiedGroup(Identity.GroupId, AccessToken);
                }

                if (group != null)
                {
                    UnifiedGroupsUtility.DeleteUnifiedGroup(group.GroupId, AccessToken);
                }
            }
        }
        protected override void ExecuteCmdlet()
        {
            UnifiedGroupEntity        group  = null;
            List <UnifiedGroupEntity> groups = null;

            if (Identity != null)
            {
                group = Identity.GetDeletedGroup(AccessToken);
            }
            else
            {
                groups = UnifiedGroupsUtility.ListDeletedUnifiedGroups(AccessToken);
            }

            if (group != null)
            {
                WriteObject(group);
            }
            else if (groups != null)
            {
                WriteObject(groups, true);
            }
        }
        /// <summary>
        /// Get an Office 365 Group (i.e. Unified Group) by Id
        /// </summary>
        /// <param name="groupId">The ID of the Office 365 Group</param>
        /// <param name="accessToken">The OAuth 2.0 Access Token to use for invoking the Microsoft Graph</param>
        /// <param name="retryCount">Number of times to retry the request in case of throttling</param>
        /// <param name="delay">Milliseconds to wait before retrying the request. The delay will be increased (doubled) every retry</param>
        public static UnifiedGroupEntity GetUnifiedGroup(String groupId, String accessToken,
                                                         int retryCount = 10, int delay = 500)
        {
            if (String.IsNullOrEmpty(groupId))
            {
                throw new ArgumentNullException(nameof(groupId));
            }

            if (String.IsNullOrEmpty(accessToken))
            {
                throw new ArgumentNullException(nameof(accessToken));
            }

            // Use a synchronous model to invoke the asynchronous process
            var result = Task.Run(async() =>
            {
                UnifiedGroupEntity group = null;

                var graphClient = CreateGraphClient(accessToken, retryCount, delay);

                var g = await graphClient.Groups[groupId].Request().GetAsync();

                group = new UnifiedGroupEntity
                {
                    GroupId      = g.Id,
                    DisplayName  = g.DisplayName,
                    Description  = g.Description,
                    Mail         = g.Mail,
                    MailNickname = g.MailNickname,
                    SiteUrl      = GetUnifiedGroupSiteUrl(groupId, accessToken),
                };

                return(group);
            }).GetAwaiter().GetResult();

            return(result);
        }
        protected override void ExecuteCmdlet()
        {
            UnifiedGroupEntity        group  = null;
            List <UnifiedGroupEntity> groups = null;

            if (Identity != null)
            {
                // We have to retrieve a specific group
                if (Identity.Group != null)
                {
                    group = UnifiedGroupsUtility.GetUnifiedGroup(Identity.Group.GroupId, AccessToken);
                }
                else if (!String.IsNullOrEmpty(Identity.DisplayName))
                {
                    groups = UnifiedGroupsUtility.ListUnifiedGroups(AccessToken, Identity.DisplayName);
                }
                else if (!String.IsNullOrEmpty(Identity.GroupId))
                {
                    group = UnifiedGroupsUtility.GetUnifiedGroup(Identity.GroupId, AccessToken);
                }
            }
            else
            {
                // Retrieve all the groups
                groups = UnifiedGroupsUtility.ListUnifiedGroups(AccessToken);
            }

            if (group != null)
            {
                WriteObject(group);
            }
            else if (groups != null)
            {
                WriteObject(groups, true);
            }
        }
Example #21
0
        protected override void ExecuteCmdlet()
        {
            UnifiedGroupEntity        group  = null;
            List <UnifiedGroupEntity> groups = null;

            if (Identity != null)
            {
                group = Identity.GetGroup(AccessToken);
            }
            else
            {
                // Retrieve all the groups
                groups = UnifiedGroupsUtility.ListUnifiedGroups(AccessToken, includeSite: !ExcludeSiteUrl.IsPresent, includeClassification: IncludeClassification.IsPresent, includeHasTeam: IncludeHasTeam.IsPresent);
            }

            if (group != null)
            {
                WriteObject(group);
            }
            else if (groups != null)
            {
                WriteObject(groups, true);
            }
        }
        /// <summary>
        /// Creates a new Office 365 Group (i.e. Unified Group) with its backing Modern SharePoint Site
        /// </summary>
        /// <param name="displayName">The Display Name for the Office 365 Group</param>
        /// <param name="description">The Description for the Office 365 Group</param>
        /// <param name="mailNickname">The Mail Nickname for the Office 365 Group</param>
        /// <param name="accessToken">The OAuth 2.0 Access Token to use for invoking the Microsoft Graph</param>
        /// <param name="owners">A list of UPNs for group owners, if any</param>
        /// <param name="members">A list of UPNs for group members, if any</param>
        /// <param name="groupLogo">The binary stream of the logo for the Office 365 Group</param>
        /// <param name="isPrivate">Defines whether the group will be private or public, optional with default false (i.e. public)</param>
        /// <param name="retryCount">Number of times to retry the request in case of throttling</param>
        /// <param name="delay">Milliseconds to wait before retrying the request. The delay will be increased (doubled) every retry</param>
        /// <returns>The just created Office 365 Group</returns>
        public static UnifiedGroupEntity CreateUnifiedGroup(string displayName, string description, string mailNickname,
                                                            string accessToken, string[] owners = null, string[] members = null, Stream groupLogo = null,
                                                            bool isPrivate = false, int retryCount = 10, int delay = 500)
        {
            UnifiedGroupEntity result = null;

            if (String.IsNullOrEmpty(displayName))
            {
                throw new ArgumentNullException(nameof(displayName));
            }

            if (String.IsNullOrEmpty(description))
            {
                throw new ArgumentNullException(nameof(description));
            }

            if (String.IsNullOrEmpty(mailNickname))
            {
                throw new ArgumentNullException(nameof(mailNickname));
            }

            if (String.IsNullOrEmpty(accessToken))
            {
                throw new ArgumentNullException(nameof(accessToken));
            }

            // Use a synchronous model to invoke the asynchronous process
            result = Task.Run(async() =>
            {
                var group = new UnifiedGroupEntity();

                var graphClient = CreateGraphClient(accessToken, retryCount, delay);

                // Prepare the group resource object
                var newGroup = new Microsoft.Graph.Group
                {
                    DisplayName     = displayName,
                    Description     = description,
                    MailNickname    = mailNickname,
                    MailEnabled     = true,
                    SecurityEnabled = false,
                    Visibility      = isPrivate == true ? "Private" : "Public",
                    GroupTypes      = new List <string> {
                        "Unified"
                    },
                };

                Microsoft.Graph.Group addedGroup = null;
                String modernSiteUrl             = null;

                // Add the group to the collection of groups (if it does not exist
                if (addedGroup == null)
                {
                    addedGroup = await graphClient.Groups.Request().AddAsync(newGroup);

                    if (addedGroup != null)
                    {
                        group.DisplayName  = addedGroup.DisplayName;
                        group.Description  = addedGroup.Description;
                        group.GroupId      = addedGroup.Id;
                        group.Mail         = addedGroup.Mail;
                        group.MailNickname = addedGroup.MailNickname;

                        int imageRetryCount = retryCount;

                        if (groupLogo != null)
                        {
                            using (var memGroupLogo = new MemoryStream())
                            {
                                groupLogo.CopyTo(memGroupLogo);

                                while (imageRetryCount > 0)
                                {
                                    bool groupLogoUpdated = false;
                                    memGroupLogo.Position = 0;

                                    using (var tempGroupLogo = new MemoryStream())
                                    {
                                        memGroupLogo.CopyTo(tempGroupLogo);
                                        tempGroupLogo.Position = 0;

                                        try
                                        {
                                            groupLogoUpdated = UpdateUnifiedGroup(addedGroup.Id,
                                                                                  accessToken, groupLogo: tempGroupLogo);
                                        }
                                        catch
                                        {
                                            // Skip any exception and simply retry
                                        }
                                    }

                                    // In case of failure retry up to 10 times, with 500ms delay in between
                                    if (!groupLogoUpdated)
                                    {
                                        // Pop up the delay for the group image
                                        Thread.Sleep(TimeSpan.FromMilliseconds(delay * (retryCount - imageRetryCount)));
                                        imageRetryCount--;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                        }

                        int driveRetryCount = retryCount;

                        while (driveRetryCount > 0 && String.IsNullOrEmpty(modernSiteUrl))
                        {
                            try
                            {
                                modernSiteUrl = GetUnifiedGroupSiteUrl(addedGroup.Id, accessToken);
                            }
                            catch
                            {
                                // Skip any exception and simply retry
                            }

                            // In case of failure retry up to 10 times, with 500ms delay in between
                            if (String.IsNullOrEmpty(modernSiteUrl))
                            {
                                Thread.Sleep(TimeSpan.FromMilliseconds(delay * (retryCount - driveRetryCount)));
                                driveRetryCount--;
                            }
                        }

                        group.SiteUrl = modernSiteUrl;
                    }
                }

                #region Handle group's owners

                if (owners != null && owners.Length > 0)
                {
                    // For each and every owner
                    foreach (var o in owners)
                    {
                        // Search for the user object
                        var ownerQuery = await graphClient.Users
                                         .Request()
                                         .Filter($"userPrincipalName eq '{o}'")
                                         .GetAsync();

                        var owner = ownerQuery.FirstOrDefault();

                        if (owner != null)
                        {
                            try
                            {
                                // And if any, add it to the collection of group's owners
                                await graphClient.Groups[addedGroup.Id].Owners.References.Request().AddAsync(owner);
                            }
                            catch (ServiceException ex)
                            {
                                if (ex.Error.Code == "Request_BadRequest" &&
                                    ex.Error.Message.Contains("added object references already exist"))
                                {
                                    // Skip any already existing owner
                                }
                                else
                                {
                                    throw ex;
                                }
                            }
                        }
                    }
                }

                #endregion

                #region Handle group's members

                if (members != null && members.Length > 0)
                {
                    // For each and every owner
                    foreach (var m in members)
                    {
                        // Search for the user object
                        var memberQuery = await graphClient.Users
                                          .Request()
                                          .Filter($"userPrincipalName eq '{m}'")
                                          .GetAsync();

                        var member = memberQuery.FirstOrDefault();

                        if (member != null)
                        {
                            try
                            {
                                // And if any, add it to the collection of group's owners
                                await graphClient.Groups[addedGroup.Id].Members.References.Request().AddAsync(member);
                            }
                            catch (ServiceException ex)
                            {
                                if (ex.Error.Code == "Request_BadRequest" &&
                                    ex.Error.Message.Contains("added object references already exist"))
                                {
                                    // Skip any already existing member
                                }
                                else
                                {
                                    throw ex;
                                }
                            }
                        }
                    }
                }

                #endregion

                return(group);
            }).GetAwaiter().GetResult();

            return(result);
        }
Example #23
0
 public Microsoft365GroupPipeBind(UnifiedGroupEntity group)
 {
     _group = group;
 }
        /// <summary>
        /// Creates a new Office 365 Group (i.e. Unified Group) with its backing Modern SharePoint Site
        /// </summary>
        /// <param name="displayName">The Display Name for the Office 365 Group</param>
        /// <param name="description">The Description for the Office 365 Group</param>
        /// <param name="mailNickname">The Mail Nickname for the Office 365 Group</param>
        /// <param name="accessToken">The OAuth 2.0 Access Token to use for invoking the Microsoft Graph</param>
        /// <param name="owners">A list of UPNs for group owners, if any</param>
        /// <param name="members">A list of UPNs for group members, if any</param>
        /// <param name="groupLogo">The binary stream of the logo for the Office 365 Group</param>
        /// <param name="isPrivate">Defines whether the group will be private or public, optional with default false (i.e. public)</param>
        /// <param name="retryCount">Number of times to retry the request in case of throttling</param>
        /// <param name="delay">Milliseconds to wait before retrying the request. The delay will be increased (doubled) every retry</param>
        /// <returns>The just created Office 365 Group</returns>
        public static UnifiedGroupEntity CreateUnifiedGroup(string displayName, string description, string mailNickname,
                                                            string accessToken, string[] owners = null, string[] members = null, Stream groupLogo = null,
                                                            bool isPrivate = false, int retryCount = 10, int delay = 500)
        {
            UnifiedGroupEntity result = null;

            if (String.IsNullOrEmpty(displayName))
            {
                throw new ArgumentNullException(nameof(displayName));
            }

            if (String.IsNullOrEmpty(description))
            {
                throw new ArgumentNullException(nameof(description));
            }

            if (String.IsNullOrEmpty(mailNickname))
            {
                throw new ArgumentNullException(nameof(mailNickname));
            }

            if (String.IsNullOrEmpty(accessToken))
            {
                throw new ArgumentNullException(nameof(accessToken));
            }

            try
            {
                // Use a synchronous model to invoke the asynchronous process
                result = Task.Run(async() =>
                {
                    var group = new UnifiedGroupEntity();

                    var graphClient = CreateGraphClient(accessToken, retryCount, delay);

                    // Prepare the group resource object
                    var newGroup = new Microsoft.Graph.Group
                    {
                        DisplayName     = displayName,
                        Description     = description,
                        MailNickname    = mailNickname,
                        MailEnabled     = true,
                        SecurityEnabled = false,
                        Visibility      = isPrivate == true ? "Private" : "Public",
                        GroupTypes      = new List <string> {
                            "Unified"
                        },
                    };

                    Microsoft.Graph.Group addedGroup = null;
                    String modernSiteUrl             = null;

                    // Add the group to the collection of groups (if it does not exist
                    if (addedGroup == null)
                    {
                        addedGroup = await graphClient.Groups.Request().AddAsync(newGroup);

                        if (addedGroup != null)
                        {
                            group.DisplayName  = addedGroup.DisplayName;
                            group.Description  = addedGroup.Description;
                            group.GroupId      = addedGroup.Id;
                            group.Mail         = addedGroup.Mail;
                            group.MailNickname = addedGroup.MailNickname;

                            int imageRetryCount = retryCount;

                            if (groupLogo != null)
                            {
                                using (var memGroupLogo = new MemoryStream())
                                {
                                    groupLogo.CopyTo(memGroupLogo);

                                    while (imageRetryCount > 0)
                                    {
                                        bool groupLogoUpdated = false;
                                        memGroupLogo.Position = 0;

                                        using (var tempGroupLogo = new MemoryStream())
                                        {
                                            memGroupLogo.CopyTo(tempGroupLogo);
                                            tempGroupLogo.Position = 0;

                                            try
                                            {
                                                groupLogoUpdated = UpdateUnifiedGroup(addedGroup.Id, accessToken, groupLogo: tempGroupLogo);
                                            }
                                            catch
                                            {
                                                // Skip any exception and simply retry
                                            }
                                        }

                                        // In case of failure retry up to 10 times, with 500ms delay in between
                                        if (!groupLogoUpdated)
                                        {
                                            // Pop up the delay for the group image
                                            await Task.Delay(delay * (retryCount - imageRetryCount));
                                            imageRetryCount--;
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                }
                            }

                            int driveRetryCount = retryCount;

                            while (driveRetryCount > 0 && String.IsNullOrEmpty(modernSiteUrl))
                            {
                                try
                                {
                                    modernSiteUrl = GetUnifiedGroupSiteUrl(addedGroup.Id, accessToken);
                                }
                                catch
                                {
                                    // Skip any exception and simply retry
                                }

                                // In case of failure retry up to 10 times, with 500ms delay in between
                                if (String.IsNullOrEmpty(modernSiteUrl))
                                {
                                    await Task.Delay(delay * (retryCount - driveRetryCount));
                                    driveRetryCount--;
                                }
                            }

                            group.SiteUrl = modernSiteUrl;
                        }
                    }

                    #region Handle group's owners

                    if (owners != null && owners.Length > 0)
                    {
                        await UpdateOwners(owners, graphClient, addedGroup);
                    }

                    #endregion

                    #region Handle group's members

                    if (members != null && members.Length > 0)
                    {
                        await UpdateMembers(members, graphClient, addedGroup);
                    }

                    #endregion

                    return(group);
                }).GetAwaiter().GetResult();
            }
            catch (ServiceException ex)
            {
                Log.Error(Constants.LOGGING_SOURCE, CoreResources.GraphExtensions_ErrorOccured, ex.Error.Message);
                throw;
            }
            return(result);
        }
        /// <summary>
        /// Returns all the Office 365 Groups in the current Tenant based on a startIndex. IncludeSite adds additional properties about the Modern SharePoint Site backing the group
        /// </summary>
        /// <param name="accessToken">The OAuth 2.0 Access Token to use for invoking the Microsoft Graph</param>
        /// <param name="displayName">The DisplayName of the Office 365 Group</param>
        /// <param name="mailNickname">The MailNickname of the Office 365 Group</param>
        /// <param name="startIndex">Not relevant anymore</param>
        /// <param name="endIndex">Not relevant anymore</param>
        /// <param name="includeSite">Defines whether to return details about the Modern SharePoint Site backing the group. Default is true.</param>
        /// <param name="retryCount">Number of times to retry the request in case of throttling</param>
        /// <param name="delay">Milliseconds to wait before retrying the request. The delay will be increased (doubled) every retry</param>
        /// <returns>An IList of SiteEntity objects</returns>
        public static List <UnifiedGroupEntity> ListUnifiedGroups(string accessToken,
                                                                  String displayName = null, string mailNickname = null,
                                                                  int startIndex     = 0, int endIndex = 999, bool includeSite = true,
                                                                  int retryCount     = 10, int delay   = 500)
        {
            if (String.IsNullOrEmpty(accessToken))
            {
                throw new ArgumentNullException(nameof(accessToken));
            }

            List <UnifiedGroupEntity> result = null;

            // Use a synchronous model to invoke the asynchronous process
            result = Task.Run(async() =>
            {
                List <UnifiedGroupEntity> groups = new List <UnifiedGroupEntity>();

                var graphClient = CreateGraphClient(accessToken, retryCount, delay);

                // Apply the DisplayName filter, if any
                var displayNameFilter  = !String.IsNullOrEmpty(displayName) ? $" and startswith(DisplayName,'{displayName}')" : String.Empty;
                var mailNicknameFilter = !String.IsNullOrEmpty(mailNickname) ? $" and startswith(MailNickname,'{mailNickname}')" : String.Empty;

                var pagedGroups = await graphClient.Groups
                                  .Request()
                                  .Filter($"groupTypes/any(grp: grp eq 'Unified'){displayNameFilter}{mailNicknameFilter}")
                                  .Top(endIndex)
                                  .GetAsync();

                Int32 pageCount    = 0;
                Int32 currentIndex = 0;

                while (true)
                {
                    pageCount++;

                    foreach (var g in pagedGroups)
                    {
                        currentIndex++;

                        if (currentIndex >= startIndex)
                        {
                            var group = new UnifiedGroupEntity
                            {
                                GroupId      = g.Id,
                                DisplayName  = g.DisplayName,
                                Description  = g.Description,
                                Mail         = g.Mail,
                                MailNickname = g.MailNickname,
                            };

                            if (includeSite)
                            {
                                group.SiteUrl = GetUnifiedGroupSiteUrl(g.Id, accessToken);
                            }

                            groups.Add(group);
                        }
                    }

                    if (pagedGroups.NextPageRequest != null && groups.Count < endIndex)
                    {
                        pagedGroups = await pagedGroups.NextPageRequest.GetAsync();
                    }
                    else
                    {
                        break;
                    }
                }

                return(groups);
            }).GetAwaiter().GetResult();

            return(result);
        }
 public UnifiedGroupPipeBind(UnifiedGroupEntity group)
 {
     _group = group;
 }
        /// <summary>
        /// Creates a new Office 365 Group (i.e. Unified Group) with its backing Modern SharePoint Site
        /// </summary>
        /// <param name="displayName">The Display Name for the Office 365 Group</param>
        /// <param name="description">The Description for the Office 365 Group</param>
        /// <param name="mailNickname">The Mail Nickname for the Office 365 Group</param>
        /// <param name="accessToken">The OAuth 2.0 Access Token to use for invoking the Microsoft Graph</param>
        /// <param name="owners">A list of UPNs for group owners, if any</param>
        /// <param name="members">A list of UPNs for group members, if any</param>
        /// <param name="isPrivate">Defines whether the group will be private or public, optional with default false (i.e. public)</param>
        /// <param name="retryCount">Number of times to retry the request in case of throttling</param>
        /// <param name="delay">Milliseconds to wait before retrying the request. The delay will be increased (doubled) every retry</param>
        /// <returns>The just created Office 365 Group</returns>
        public static UnifiedGroupEntity CreateUnifiedGroup(string displayName, string description, string mailNickname,
                                                            string accessToken, string[] owners = null, string[] members = null,
                                                            bool isPrivate = false, int retryCount = 10, int delay = 500)
        {
            UnifiedGroupEntity result = null;

            if (String.IsNullOrEmpty(displayName))
            {
                throw new ArgumentNullException("displayName");
            }

            if (String.IsNullOrEmpty(description))
            {
                throw new ArgumentNullException("description");
            }

            if (String.IsNullOrEmpty(mailNickname))
            {
                throw new ArgumentNullException("mailNickname");
            }

            if (String.IsNullOrEmpty(accessToken))
            {
                throw new ArgumentNullException("accessToken");
            }

            // Use a synchronous model to invoke the asynchronous process
            result = Task.Run(async() =>
            {
                var group = new UnifiedGroupEntity();

                var graphClient = CreateGraphClient(accessToken, retryCount, delay);

                // Prepare the group resource object
                var newGroup = new Microsoft.Graph.Group
                {
                    DisplayName     = displayName,
                    Description     = description,
                    MailNickname    = mailNickname,
                    MailEnabled     = true,
                    SecurityEnabled = false,
                    GroupTypes      = new List <string> {
                        "Unified"
                    },
                };

                Microsoft.Graph.Group addedGroup = null;
                String modernSiteUrl             = null;

                // Add the group to the collection of groups (if it does not exist
                if (addedGroup == null)
                {
                    addedGroup = await graphClient.Groups.Request().AddAsync(newGroup);

                    // Just to add a short delay :-) ...
                    Thread.Sleep(TimeSpan.FromSeconds(5));

                    if (addedGroup != null)
                    {
                        group.DisplayName  = addedGroup.DisplayName;
                        group.Description  = addedGroup.Description;
                        group.GroupId      = addedGroup.Id;
                        group.Mail         = addedGroup.Mail;
                        group.MailNickname = addedGroup.MailNickname;

                        try
                        {
                            modernSiteUrl = GetUnifiedGroupSiteUrl(addedGroup.Id, accessToken);
                        }
                        catch
                        {
                            // NOOP, we simply need to wakeup the OD4B/Site creation
                        }
                    }
                }

                #region Handle group's owners

                if (owners != null && owners.Length > 0)
                {
                    // For each and every owner
                    foreach (var o in owners)
                    {
                        // Search for the user object
                        var ownerQuery = await graphClient.Users
                                         .Request()
                                         .Filter($"userPrincipalName eq '{o}'")
                                         .GetAsync();

                        var owner = ownerQuery.FirstOrDefault();

                        if (owner != null)
                        {
                            try
                            {
                                // And if any, add it to the collection of group's owners
                                await graphClient.Groups[addedGroup.Id].Owners.References.Request().AddAsync(owner);
                            }
                            catch (ServiceException ex)
                            {
                                if (ex.Error.Code == "Request_BadRequest" &&
                                    ex.Error.Message.Contains("added object references already exist"))
                                {
                                    // Skip any already existing owner
                                }
                                else
                                {
                                    throw ex;
                                }
                            }
                        }
                    }
                }

                #endregion

                #region Handle group's members

                if (members != null && members.Length > 0)
                {
                    // For each and every owner
                    foreach (var m in members)
                    {
                        // Search for the user object
                        var memberQuery = await graphClient.Users
                                          .Request()
                                          .Filter($"userPrincipalName eq '{m}'")
                                          .GetAsync();

                        var member = memberQuery.FirstOrDefault();

                        if (member != null)
                        {
                            try
                            {
                                // And if any, add it to the collection of group's owners
                                await graphClient.Groups[addedGroup.Id].Members.References.Request().AddAsync(member);
                            }
                            catch (ServiceException ex)
                            {
                                if (ex.Error.Code == "Request_BadRequest" &&
                                    ex.Error.Message.Contains("added object references already exist"))
                                {
                                    // Skip any already existing member
                                }
                                else
                                {
                                    throw ex;
                                }
                            }
                        }
                    }
                }

                #endregion

                int driveRetryCount = 10;

                while (driveRetryCount > 0 && String.IsNullOrEmpty(modernSiteUrl))
                {
                    modernSiteUrl = GetUnifiedGroupSiteUrl(addedGroup.Id, accessToken);

                    // In case of failure retry up to 10 times, with 500ms delay in between
                    if (String.IsNullOrEmpty(modernSiteUrl))
                    {
                        Thread.Sleep(TimeSpan.FromMilliseconds(500));
                        driveRetryCount--;
                    }
                }

                group.SiteUrl = modernSiteUrl;

                return(group);
            }).GetAwaiter().GetResult();

            return(result);
        }