public/get-TeamPermissions.ps1
Function get-TeamPermissions{ <# Author = "Jos Lieben (jos@lieben.nu)" CompanyName = "Lieben Consultancy" Copyright = "https://www.lieben.nu/liebensraum/commercial-use/" Parameters: -teamName: the name of the Team to scan -teamSiteUrl: the URL of the Team (or any sharepoint location) to scan (e.g. if name is not unique) -expandGroups: if set, group memberships will be expanded to individual users -outputFormat: HTML XLSX CSV Default (output to Out-GridView) Any combination of above is possible #> Param( [parameter(Mandatory=$true, ParameterSetName="ByName")] [String] $teamName, [parameter(Mandatory=$true, ParameterSetName="BySite")] [String] $teamSiteUrl, [Switch]$expandGroups, [parameter(Mandatory=$true)] [ValidateSet('HTML','XLSX','CSV','Default')] [String[]]$outputFormat ) if(!$global:LCCachedToken){ get-AuthorizationCode } $global:tenantName = (New-GraphQuery -Method GET -Uri 'https://graph.microsoft.com/v1.0/domains?$top=999' -NoPagination | Where-Object -Property isInitial -EQ $true).id.Split(".")[0] $currentUser = New-GraphQuery -Uri 'https://graph.microsoft.com/v1.0/me' -NoPagination -Method GET Write-Host "Performing scan using: $($currentUser.userPrincipalName)" $spoBaseAdmUrl = "https://$($tenantName)-admin.sharepoint.com" Write-Host "Using Sharepoint base URL: $spoBaseAdmUrl" $sites = Get-PnPTenantSite -Connection (Get-SpOConnection -Type Admin -Url $spoBaseAdmUrl) | Where-Object {` $_.Template -NotIn ("SRCHCEN#0", "SPSMSITEHOST#0", "APPCATALOG#0", "POINTPUBLISHINGHUB#0", "EDISC#0", "STS#-1","EHS#1","POINTPUBLISHINGTOPIC#0") -and ($Null -ne $teamName -and $_.Title -eq $teamName) -or ($Null -ne $teamSiteUrl -and $_.Url -eq $teamSiteUrl) } if($sites.Count -gt 1){ Throw "Failed to find a single Team using $teamName. Found: $($sites.Url -join ","). Please use the Url to specify the correct Team" }elseif($sites.Count -eq 0 -or $Null -eq $sites){ Throw "Failed to find a Team using $teamName $teamSiteUrl. Please check the name and try again" }else{ $site = $sites[0] } $wasOwner = $False if($site.Owners -notcontains $currentUser.userPrincipalName){ Write-Host "Adding you as site collection owner to ensure all permissions can be read..." Set-PnPTenantSite -Identity $site.Url -Owners $currentUser.userPrincipalName -Connection (Get-SpOConnection -Type Admin -Url $spoBaseAdmUrl) -WarningAction Stop -ErrorAction Stop Write-Host "Owner added and marked for removal upon scan completion" }else{ $wasOwner = $True Write-Host "Site collection ownership verified :)" } if($site.GroupId.Guid -eq "00000000-0000-0000-0000-000000000000"){ $groupId = $Null Write-Warning "Site is not connected to a group and is likely not a Team site." }else{ $groupId = $site.GroupId.Guid Write-Host "Site is connected to a group with ID: $groupId" } $spoWeb = Get-PnPWeb -Connection (Get-SpOConnection -Type User -Url $site.Url) -ErrorAction Stop Write-Host "Scanning root $($spoWeb.Url)..." $spoSiteAdmins = Get-PnPSiteCollectionAdmin -Connection (Get-SpOConnection -Type User -Url $site.Url) $global:permissions = @{ $spoWeb.Url = @() } #language specific permission name translation switch($currentUser.preferredLanguage){ "nl-NL" { $fullControl = "Volledig beheer"} Default { $fullControl = "Full Control"} } foreach($spoSiteAdmin in $spoSiteAdmins){ if($spoSiteAdmin.PrincipalType -ne "User" -and $expandGroups){ $members = $Null; $members = Get-PnPGroupMembers -name $spoSiteAdmin.Title -parentId $spoSiteAdmin.Id -siteConn (Get-SpOConnection -Type User -Url $site.Url) | Where-Object {$_} foreach($member in $members){ New-PermissionEntry -Path $spoWeb.Url -Permission (get-permissionEntry -entity $member -object $spoWeb -permission $fullControl -Through "GroupMembership" -parent $spoSiteAdmin.Title) } }else{ New-PermissionEntry -Path $spoWeb.Url -Permission (get-permissionEntry -entity $spoSiteAdmin -object $spoWeb -permission $fullControl -Through "DirectAssignment") } } get-PnPObjectPermissions -Object $spoWeb $permissionRows = @() foreach($row in $global:permissions.Keys){ foreach($permission in $global:permissions.$row){ $permissionRows += [PSCustomObject]@{ "ID" = $permission.RowId "Path" = $row "Object" = $permission.Object "Name" = $permission.Name "Identity" = $permission.Identity "Email" = $permission.Email "Type" = $permission.Type "Permission" = $permission.Permission "Through" = $permission.Through "Parent" = $permission.Parent } } } if((get-location).Path){ $basePath = Join-Path -Path (get-location).Path -ChildPath "TeamPermissions.@@@" }else{ $basePath = Join-Path -Path (Split-Path -Path $MyInvocation.MyCommand.Definition -Parent) -ChildPath "TeamPermissions.@@@" } foreach($format in $outputFormat){ switch($format){ "HTML" { $targetPath = $basePath.Replace("@@@","html") if((Test-Path -Path $targetPath)){ $curHtml = Get-Content -Path $targetPath }else{ $curHtml = "<html><head><style>table {border-collapse: collapse;}table, th, td {border: 1px solid black;}</style></head><body><h1>Team Permissions Report</h1></body></html>" } $table = $permissionRows | ConvertTo-Html -Property "ID","Path","Object","Name","Identity","Email","Type","Permission","Through","Parent" -Fragment $curHtml -replace "</body>","<p><h2>$($spoWeb.Url)</h2>$table</body>" | Out-File -FilePath $targetPath -Force -Encoding UTF8 -Confirm:$False Write-Host "HTML report saved to $targetPath" } "XLSX" { $targetPath = $basePath.Replace("@@@","xlsx") $permissionRows | Export-Excel -Path $targetPath -WorksheetName "TeamPermissions" -TableName "TeamPermissions" -TableStyle Medium10 -Append -AutoSize Write-Host "XLSX report saved to $targetPath" } "CSV" { $targetPath = $basePath.Replace("@@@","csv") $permissionRows | Export-Csv -Path "TeamPermissions.csv" -NoTypeInformation -Append Write-Host "CSV report saved to $targetPath" } "Default" { $permissionRows | out-gridview } } } if(!$wasOwner){ Write-Host "Cleanup: Removing you as site collection owner..." Remove-PnPSiteCollectionAdmin -Owners $currentUser.userPrincipalName -Connection (Get-SpOConnection -Type User -Url $site.Url) Write-Host "Cleanup: Owner removed" } } |