From 4205a457c125acf9ac025b325fd1d4c8f9c0e955 Mon Sep 17 00:00:00 2001 From: Jorge Raastroem Date: Sat, 15 Aug 2020 11:15:55 -0700 Subject: [PATCH 1/3] Added new flag to include all classteams --- Teams Scripts/Add-GroupOwners-To-Teams.ps1 | 39 ++++++++++++++-------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/Teams Scripts/Add-GroupOwners-To-Teams.ps1 b/Teams Scripts/Add-GroupOwners-To-Teams.ps1 index 3f258851..b6307f73 100644 --- a/Teams Scripts/Add-GroupOwners-To-Teams.ps1 +++ b/Teams Scripts/Add-GroupOwners-To-Teams.ps1 @@ -17,21 +17,24 @@ .\Add-Group-Owners-To-Teams.ps1 -EducatorUPN john.smith@school.edu -For all SDS Teams .\Add-Group-Owners-To-Teams.ps1 + -For all Teams, including non-SDS provisioned teams + .\Add-Group-Owners-To-Teams.ps1 -IncludeNonSDSGroups #> Param ( - [Parameter(Mandatory = $false)][string]$EducatorUPN) + [Parameter(Mandatory = $false)][string]$EducatorUPN, + [Parameter(Mandatory = $false)][Switch]$IncludeNonSDSGroups) function Initialize() { import-module Microsoft.Graph.Authentication -MinimumVersion 0.9.1 - Write-Output "If prompted, please use a tenant admin-account to grant access to 'TeamMember.ReadWrite.All', 'Group.Read.All' and 'Directory.AccessAsUser.All' privileges" + Write-Output "If prompted, please use a tenant admin-account to grant access to 'TeamMember.ReadWrite.All' and 'Group.Read.All' privileges" Refresh-Token } $lastRefreshed = $null function Refresh-Token() { if ($lastRefreshed -eq $null -or (get-date - $lastRefreshed).Minutes -gt 10) { - connect-graph -scopes TeamMember.ReadWrite.All,Group.Read.All,Directory.AccessAsUser.All + connect-graph -scopes TeamMember.ReadWrite.All,Group.Read.All $lastRefreshed = get-date } } @@ -127,12 +130,19 @@ function PageAll-GraphRequest($initialUrl, $logFilePath) { $groupSelectClause = "`$select=id,mailNickname,emailAddress,displayName,resourceProvisioningOptions" -function Check-Team($group) { +function Check-Team($IncludeNonSDSGroups, $group) { if (($group.resourceProvisioningOptions -ne $null) -and $group.resourceProvisioningOptions.Contains("Team") -and $group.mailNickname.StartsWith("Section_")) { try { Refresh-Token $groupId = $group.id - $result = invoke-graphrequest -Method GET -Uri "https://graph.microsoft.com/beta/teams/$groupId/?`$select=id" -ContentType "application/json" -SkipHttpErrorCheck + $result = invoke-graphrequest -Method GET -Uri "https://graph.microsoft.com/beta/teams/$groupId/?`$select=isMembershipLimitedToOwners,id,classSettings" -ContentType "application/json" -SkipHttpErrorCheck + if($IncludeNonSDSGroups){ + # This will only include class teams in the filtered batch, when including nonSDS groups + if($result.classSettings && $result.isMembershipLimitedToOwners -eq $false){ + return $result + } + return $false + } return ($result -ne $null -and (-Not $result.ContainsKey("error"))) } catch { @@ -141,21 +151,22 @@ function Check-Team($group) { } } -function Get-SDSTeams($logFilePath) { - $initialSDSGroupUri = "https://graph.microsoft.com/beta/groups?`$filter=groupTypes/any(c:c+eq+'Unified')+and+startswith(mailNickname,'Section_')+and+resourceProvisioningOptions/Any(x:x+eq+'Team')&$groupSelectClause" +function Get-SDSTeams($IncludeNonSDSGroups, $logFilePath) { + $initialSDSGroupUri = "https://graph.microsoft.com/beta/groups?`$filter=groupTypes/any(c:c+eq+'Unified')" + $(if(-Not $IncludeNonSDSGroups) {"+and+startswith(mailNickname,'Section_')"}) + "+and+resourceProvisioningOptions/Any(x:x+eq+'Team')&$groupSelectClause" + $unfilteredSDSGroups = PageAll-GraphRequest $initialSDSGroupUri $logFilePath write-output "Retrieve $($unfilteredSDSGroups.Count) groups." | out-file $logFilePath -Append $i = 0 - $filteredSDSTeams = $unfilteredSDSGroups | Where-Object { (Write-Progress "Validating groups..." -Status "Progress" -PercentComplete (($i++ / $unfilteredSDSGroups.count) * 100)) -or (Check-Team $_) } + $filteredSDSTeams = $unfilteredSDSGroups | Where-Object { (Write-Progress "Validating groups..." -Status "Progress" -PercentComplete (($i++ / $unfilteredSDSGroups.count) * 100)) -or (Check-Team $IncludeNonSDSGroups $_) } write-output "Filtered to $($filteredSDSTeams.Count) groups." | out-file $logFilePath -Append return $filteredSDSTeams } -function Get-SDSTeams-ForUser($EducatorUPN, $logFilePath) { +function Get-SDSTeams-ForUser($EducatorUPN, $IncludeNonSDSGroups, $logFilePath) { $initialOwnedObjectsUri = "https://graph.microsoft.com/beta/users/$EducatorUPN/ownedObjects?$groupSelectClause" $unfilteredOwnedGroups = PageAll-GraphRequest $initialOwnedObjectsUri $logFilePath $i = 0 - $filteredOwnedGroups = $unfilteredOwnedGroups | Where-Object { (Write-Progress "Validating groups..." -Status "Progress" -PercentComplete (($i++ / $unfilteredOwnedGroups.count) * 100)) -or (Check-Team $_) } + $filteredOwnedGroups = $unfilteredOwnedGroups | Where-Object { (Write-Progress "Validating groups..." -Status "Progress" -PercentComplete (($i++ / $unfilteredOwnedGroups.count) * 100)) -or (Check-Team $IncludeNonSDSGroups $_) } return $filteredOwnedGroups } @@ -166,7 +177,7 @@ function Get-Owners-ForGroup($groupId) { return $filteredOwners } -function Execute($EducatorUPN, $recordedGroups, $logFilePath) { +function Execute($EducatorUPN, $IncludeNonSDSGroups, $recordedGroups, $logFilePath) { $processedTeams = $null Initialize @@ -175,7 +186,7 @@ function Execute($EducatorUPN, $recordedGroups, $logFilePath) { Write-Host "Obtaining list of SDS Created Teams. Please wait..." Write-Output "Obtaining list of SDS Created Teams. Please wait..." | out-file $logFilePath -append - $SDSTeams = Get-SDSTeams $logFilePath + $SDSTeams = Get-SDSTeams $IncludeNonSDSGroups $logFilePath Write-Host "Identified $($SDSTeams.count) teams that are provisioned." Write-Output "Identified $($SDSTeams.count) teams that are provisioned." | Out-File $logFilePath -Append @@ -190,7 +201,7 @@ function Execute($EducatorUPN, $recordedGroups, $logFilePath) { else { Write-Output "Obtaining list of SDS Teams for user $($EducatorUPN), Please wait..." | Out-File $logFilePath -Append Write-Host "Obtaining list of SDS Teams for user $($EducatorUPN), Please wait..." - $SDSTeams = Get-SDSTeams-ForUser $EducatorUPN $logFilePath + $SDSTeams = Get-SDSTeams-ForUser $EducatorUPN $IncludeNonSDSGroups $logFilePath Write-Output "Identified $($SDSTeams.count) teams that are provisioned." | Out-File $logFilePath -Append Write-Host "Identified $($SDSTeams.count) teams that are provisioned." @@ -213,7 +224,7 @@ $logFilePath = ".\Add-Group-Owners-To-Teams.log" $recordedGroups = ".\Updated-Teams.csv" try { - Execute $EducatorUPN $recordedGroups $logFilePath + Execute $EducatorUPN $IncludeNonSDSGroups $recordedGroups $logFilePath } catch { Write-Error "Terminal Error occurred in processing." From bbfd372ee75dff72377b97fe1b4730b00830604b Mon Sep 17 00:00:00 2001 From: Jorge Raastroem Date: Sat, 15 Aug 2020 11:19:20 -0700 Subject: [PATCH 2/3] Merged to head --- Teams Scripts/Add-GroupOwners-To-Teams.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Teams Scripts/Add-GroupOwners-To-Teams.ps1 b/Teams Scripts/Add-GroupOwners-To-Teams.ps1 index b6307f73..535e48f8 100644 --- a/Teams Scripts/Add-GroupOwners-To-Teams.ps1 +++ b/Teams Scripts/Add-GroupOwners-To-Teams.ps1 @@ -27,14 +27,14 @@ Param ( function Initialize() { import-module Microsoft.Graph.Authentication -MinimumVersion 0.9.1 - Write-Output "If prompted, please use a tenant admin-account to grant access to 'TeamMember.ReadWrite.All' and 'Group.Read.All' privileges" + Write-Output "If prompted, please use a tenant admin-account to grant access to 'TeamMember.ReadWrite.All', 'Group.Read.All' and 'Directory.AccessAsUser.All' privileges" Refresh-Token } $lastRefreshed = $null function Refresh-Token() { if ($lastRefreshed -eq $null -or (get-date - $lastRefreshed).Minutes -gt 10) { - connect-graph -scopes TeamMember.ReadWrite.All,Group.Read.All + connect-graph -scopes TeamMember.ReadWrite.All,Group.Read.All,Directory.AccessAsUser.All $lastRefreshed = get-date } } From 1d691152ba02d5e7419d1aec8d820263b551673e Mon Sep 17 00:00:00 2001 From: Jorge Raastroem Date: Sat, 15 Aug 2020 12:44:54 -0700 Subject: [PATCH 3/3] Addressed PR comments --- Teams Scripts/Add-GroupOwners-To-Teams.ps1 | 28 ++++++++++++---------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/Teams Scripts/Add-GroupOwners-To-Teams.ps1 b/Teams Scripts/Add-GroupOwners-To-Teams.ps1 index 535e48f8..e62f006d 100644 --- a/Teams Scripts/Add-GroupOwners-To-Teams.ps1 +++ b/Teams Scripts/Add-GroupOwners-To-Teams.ps1 @@ -130,19 +130,20 @@ function PageAll-GraphRequest($initialUrl, $logFilePath) { $groupSelectClause = "`$select=id,mailNickname,emailAddress,displayName,resourceProvisioningOptions" -function Check-Team($IncludeNonSDSGroups, $group) { - if (($group.resourceProvisioningOptions -ne $null) -and $group.resourceProvisioningOptions.Contains("Team") -and $group.mailNickname.StartsWith("Section_")) { +function Check-Team($includeNonSDSGroups, $group) { + if (($group.resourceProvisioningOptions -ne $null) -and $group.resourceProvisioningOptions.Contains("Team") -and ($group.mailNickname.StartsWith("Section_") -or $includeNonSDSGroups)) { try { Refresh-Token $groupId = $group.id - $result = invoke-graphrequest -Method GET -Uri "https://graph.microsoft.com/beta/teams/$groupId/?`$select=isMembershipLimitedToOwners,id,classSettings" -ContentType "application/json" -SkipHttpErrorCheck - if($IncludeNonSDSGroups){ + $result = invoke-graphrequest -Method GET -Uri "https://graph.microsoft.com/beta/teams/$groupId/?`$select=id,classSettings" -ContentType "application/json" -SkipHttpErrorCheck + if($includeNonSDSGroups){ # This will only include class teams in the filtered batch, when including nonSDS groups - if($result.classSettings && $result.isMembershipLimitedToOwners -eq $false){ + if($result.classSettings){ return $result } return $false } + Write-Host return ($result -ne $null -and (-Not $result.ContainsKey("error"))) } catch { @@ -151,22 +152,23 @@ function Check-Team($IncludeNonSDSGroups, $group) { } } -function Get-SDSTeams($IncludeNonSDSGroups, $logFilePath) { - $initialSDSGroupUri = "https://graph.microsoft.com/beta/groups?`$filter=groupTypes/any(c:c+eq+'Unified')" + $(if(-Not $IncludeNonSDSGroups) {"+and+startswith(mailNickname,'Section_')"}) + "+and+resourceProvisioningOptions/Any(x:x+eq+'Team')&$groupSelectClause" +function Get-SDSTeams($includeNonSDSGroups, $logFilePath) { + $initialSDSGroupUri = "https://graph.microsoft.com/beta/groups?`$filter=groupTypes/any(c:c+eq+'Unified')+and+resourceProvisioningOptions/Any(x:x+eq+'Team')" + $(if(-Not $includeNonSDSGroups) {"+and+startswith(mailNickname,'Section_')"}) + "&$groupSelectClause" $unfilteredSDSGroups = PageAll-GraphRequest $initialSDSGroupUri $logFilePath + write-output "Retrieve $($unfilteredSDSGroups.Count) groups." | out-file $logFilePath -Append $i = 0 - $filteredSDSTeams = $unfilteredSDSGroups | Where-Object { (Write-Progress "Validating groups..." -Status "Progress" -PercentComplete (($i++ / $unfilteredSDSGroups.count) * 100)) -or (Check-Team $IncludeNonSDSGroups $_) } + $filteredSDSTeams = $unfilteredSDSGroups | Where-Object { (Write-Progress "Validating groups..." -Status "Progress" -PercentComplete (($i++ / $unfilteredSDSGroups.count) * 100)) -or (Check-Team $includeNonSDSGroups $_) } write-output "Filtered to $($filteredSDSTeams.Count) groups." | out-file $logFilePath -Append return $filteredSDSTeams } -function Get-SDSTeams-ForUser($EducatorUPN, $IncludeNonSDSGroups, $logFilePath) { +function Get-SDSTeams-ForUser($EducatorUPN, $includeNonSDSGroups, $logFilePath) { $initialOwnedObjectsUri = "https://graph.microsoft.com/beta/users/$EducatorUPN/ownedObjects?$groupSelectClause" $unfilteredOwnedGroups = PageAll-GraphRequest $initialOwnedObjectsUri $logFilePath $i = 0 - $filteredOwnedGroups = $unfilteredOwnedGroups | Where-Object { (Write-Progress "Validating groups..." -Status "Progress" -PercentComplete (($i++ / $unfilteredOwnedGroups.count) * 100)) -or (Check-Team $IncludeNonSDSGroups $_) } + $filteredOwnedGroups = $unfilteredOwnedGroups | Where-Object { (Write-Progress "Validating groups..." -Status "Progress" -PercentComplete (($i++ / $unfilteredOwnedGroups.count) * 100)) -or (Check-Team $includeNonSDSGroups $_) } return $filteredOwnedGroups } @@ -177,7 +179,7 @@ function Get-Owners-ForGroup($groupId) { return $filteredOwners } -function Execute($EducatorUPN, $IncludeNonSDSGroups, $recordedGroups, $logFilePath) { +function Execute($EducatorUPN, $includeNonSDSGroups, $recordedGroups, $logFilePath) { $processedTeams = $null Initialize @@ -186,7 +188,7 @@ function Execute($EducatorUPN, $IncludeNonSDSGroups, $recordedGroups, $logFilePa Write-Host "Obtaining list of SDS Created Teams. Please wait..." Write-Output "Obtaining list of SDS Created Teams. Please wait..." | out-file $logFilePath -append - $SDSTeams = Get-SDSTeams $IncludeNonSDSGroups $logFilePath + $SDSTeams = Get-SDSTeams $includeNonSDSGroups $logFilePath Write-Host "Identified $($SDSTeams.count) teams that are provisioned." Write-Output "Identified $($SDSTeams.count) teams that are provisioned." | Out-File $logFilePath -Append @@ -201,7 +203,7 @@ function Execute($EducatorUPN, $IncludeNonSDSGroups, $recordedGroups, $logFilePa else { Write-Output "Obtaining list of SDS Teams for user $($EducatorUPN), Please wait..." | Out-File $logFilePath -Append Write-Host "Obtaining list of SDS Teams for user $($EducatorUPN), Please wait..." - $SDSTeams = Get-SDSTeams-ForUser $EducatorUPN $IncludeNonSDSGroups $logFilePath + $SDSTeams = Get-SDSTeams-ForUser $EducatorUPN $includeNonSDSGroups $logFilePath Write-Output "Identified $($SDSTeams.count) teams that are provisioned." | Out-File $logFilePath -Append Write-Host "Identified $($SDSTeams.count) teams that are provisioned."