functions/Invoke-SPPermissionScan.ps1
function Invoke-SPPermissionScan { <# .SYNOPSIS Executes a managed and logged sharepoint permission scan. .DESCRIPTION Executes a managed and logged sharepoint permission scan. This scan then matches the result against specified users, resolving the effective access rights of a user. This includes simplified logging options (for more options, see https://psframework.org). It can also at stages export data to csv as it comes in. This command is designed to be able to handle any Sharepoint site scale. More sites means longer runtimes, but should not affect quality of result. Connect via Connect-Sharepoint before running this command. .PARAMETER UserIdentity IDs or UserPrincipalName of users to match against the Sharepoint permissions. Group memberships are taken into account recursively. .PARAMETER SiteUrl Sharepoint sites to scan. If this parameter is not specified, all Sharepoint sites in the tenant will be scanned. .PARAMETER LogPath The path to the file into which the command should log actions. The output will be in a CSV format and include detailed information on what information was retrieved against what site. .PARAMETER ExportPathRaw Path to which raw Sharepoint permission results should be written as CSV. Specify this path if you want an export of all permissions in their raw state without matching it against users. .PARAMETER ExportPathResult Path to which processed permission results should be written as CSV. This content is equal to the output objects of this command. .PARAMETER RawExclude Whether the raw export should exclude specific permissions. By default, Sharepoint internal permissions are excluded. .PARAMETER LogLevel How detailed a log should be written. .EXAMPLE PS C:\> Invoke-SPPermissionScan -UserIdentity (Get-Content .\users.txt) Scan all sharepoint sites for their permissions and match them against the users stored in the "users.txt" text file. #> [CmdletBinding()] param ( [string[]] $UserIdentity, [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [string[]] $SiteUrl, [string] $LogPath, [PsfValidateScript('PSFramework.Validate.FSPath.FileOrParent', ErrorString = 'PSFramework.Validate.FSPath.FileOrParent')] [string] $ExportPathRaw, [PsfValidateScript('PSFramework.Validate.FSPath.FileOrParent', ErrorString = 'PSFramework.Validate.FSPath.FileOrParent')] [string] $ExportPathResult, [ValidateSet('None', 'System', 'SPRole', 'SPUser', 'AAD', 'AADRole', 'Unknown')] [string[]] $RawExclude = @('System', 'SPRole', 'SPUser'), [LogLevel] $LogLevel = 'Medium' ) begin { if (-not $script:adminUrl) { throw "Not connected yet, call 'Connect-Sharepoint' to connect!" } Connect-Sharepoint -TenantID $script:TenantID -ClientID $script:ClientID -Thumbprint $script:Thumbprint -AdminUrl $script:adminUrl if ($LogPath) { Set-PSFLoggingProvider -Name logfile -InstanceName SPPermissionScan -FilePath $LogPath -Enabled $true } else { $LogLevel = 'None' } $userData = Resolve-SPGraphUser -Identity $UserIdentity -LogLevel $LogLevel Write-PSFMessage -Level Host -Message 'Starting Sharepoint Permission Scan' -Tag progress } process { if ($SiteUrl) { $SiteUrl | Get-SPSitePermission -Exclude $RawExclude -LogLevel $LogLevel | Export-CsvData -Path $ExportPathRaw | ConvertTo-UserSitePermission -UserData $userData -LogLevel $LogLevel | Export-CsvData -Path $ExportPathResult } else { $urlCache = Join-Path -Path (Get-PSFPath -Name Temp) -ChildPath "ssp-$(Get-Random).txt" try { # Get-PnPTenantSite keeps all sites in memory before returning them # Writing them to file and then reading from file minimizes memory impact Get-PnPTenantSite | ForEach-Object Url | Set-Content -Path $urlCache Get-Content -Path $urlCache | Get-SPSitePermission -Exclude $RawExclude -LogLevel $LogLevel | Export-CsvData -Path $ExportPathRaw | ConvertTo-UserSitePermission -UserData $userData -LogLevel $LogLevel | Export-CsvData -Path $ExportPathResult } finally { Remove-Item -Path $urlCache -Force -ErrorAction Ignore } } } end { Write-PSFMessage -Level Host -Message 'Sharepoint Permission Scan Concluded' -Tag progress if ($LogPath) { Wait-PSFMessage Set-PSFLoggingProvider -Name logfile -InstanceName SPPermissionScan -Enabled $false } Connect-Sharepoint -TenantID $script:TenantID -ClientID $script:ClientID -Thumbprint $script:Thumbprint -AdminUrl $script:adminUrl } } |