/// <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); }
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); } }
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)); } }
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); } }
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()); } }
protected override void ExecuteCmdlet() { UnifiedGroupEntity group = null; if (Identity != null) { group = Identity.GetGroup(AccessToken); } if (group != null) { UnifiedGroupsUtility.RemoveUnifiedGroupOwners(group.GroupId, Users, AccessToken); } }
protected override void ExecuteCmdlet() { UnifiedGroupEntity group = null; if (Identity != null) { group = Identity.GetGroup(AccessToken); } if (group != null) { UnifiedGroupsUtility.ClearUnifiedGroupMembers(group.GroupId, AccessToken); } }
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); } }
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()); } }
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); } }
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); }
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); }