Public/Export-SPPermissionMatrix.ps1
|
function Export-SPPermissionMatrix { <# .SYNOPSIS Exports a scan (from Invoke-SPPermissionScan) as an Excel workbook in the classic permission-matrix style. .DESCRIPTION Per site the workbook contains a "Groups" sheet (columns = principals as assigned in SharePoint) and/or a "People" sheet (columns = resolved individuals with their highest effective permission). Cells use the same color scheme as the HTML report: hue = permission level (FC red, W blue, C violet, R read green), intensity = inheritance (pale = inherited, bold/tinted = assigned here). Requires the ImportExcel module (Install-Module ImportExcel). .PARAMETER InputPath Path to the scan JSON file. .PARAMETER ScanData Scan object (from Invoke-SPPermissionScan -PassThru) or scan JSON FileInfo - pipeline capable. .PARAMETER OutputPath Path of the .xlsx output file. Default: input path with .xlsx extension. .PARAMETER View Groups, People or Both (default). .PARAMETER IncludeSharingLinks Also include sharing-link groups as columns (hidden by default). .PARAMETER Open Opens the workbook afterwards. .EXAMPLE Export-SPPermissionMatrix -InputPath .\scan.json -Open .EXAMPLE Invoke-SPPermissionScan -SiteUrl $url -Depth 2 -ClientId $appId -Interactive | Export-SPPermissionMatrix #> [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'Path')] [OutputType([System.IO.FileInfo])] param( [Parameter(Mandatory, ParameterSetName = 'Path', Position = 0)] [string]$InputPath, [Parameter(Mandatory, ParameterSetName = 'Data', ValueFromPipeline)] [psobject]$ScanData, [string]$OutputPath, [ValidateSet('Groups', 'People', 'Both')] [string]$View = 'Both', [switch]$IncludeSharingLinks, [switch]$Open ) process { if (-not (Get-Module -ListAvailable -Name ImportExcel)) { throw "The Excel export requires the 'ImportExcel' module. Install it with: Install-Module ImportExcel -Scope CurrentUser" } Import-Module ImportExcel -ErrorAction Stop $source = if ($PSCmdlet.ParameterSetName -eq 'Path') { $InputPath } else { $ScanData } $scan = Get-SPMScanObject -InputObject $source if (-not $OutputPath) { if ($PSCmdlet.ParameterSetName -eq 'Path') { $OutputPath = [System.IO.Path]::ChangeExtension((Resolve-Path -Path $InputPath).Path, '.xlsx') } elseif ($ScanData -is [System.IO.FileInfo]) { $OutputPath = [System.IO.Path]::ChangeExtension($ScanData.FullName, '.xlsx') } else { $OutputPath = Join-Path (Get-Location) ('SPPermissionMatrix_{0:yyyyMMdd_HHmmss}.xlsx' -f (Get-Date)) } } if (-not $PSCmdlet.ShouldProcess($OutputPath, 'Create Excel workbook')) { return } if (Test-Path -Path $OutputPath) { Remove-Item -Path $OutputPath -Force } $pkg = Open-ExcelPackage -Path $OutputPath -Create try { $usedNames = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase) foreach ($site in @($scan.sites)) { if ($View -in 'Groups', 'Both') { Add-SPMGroupSheet -Package $pkg -Site $site -UsedNames $usedNames -IncludeSharingLinks:$IncludeSharingLinks } if ($View -in 'People', 'Both') { Add-SPMPeopleSheet -Package $pkg -Site $site -UsedNames $usedNames -IncludeSharingLinks:$IncludeSharingLinks } } $info = Add-Worksheet -ExcelPackage $pkg -WorksheetName 'Info' $info.Cells[1, 1].Value = 'SPPermissionMatrix export' $info.Cells[1, 1].Style.Font.Bold = $true $info.Cells[2, 1].Value = "Generator: $($scan.generator)" $info.Cells[3, 1].Value = "Scan date (UTC): $($scan.scanDate)" $info.Cells[4, 1].Value = "Depth: $($scan.depth) - Sites: $(@($scan.sites).Count)" $info.Cells[5, 1].Value = "Exported: $(Get-Date -Format 'yyyy-MM-dd HH:mm')" $info.Column(1).Width = 70 } finally { Close-ExcelPackage $pkg } Write-Verbose "Workbook saved: $OutputPath" if ($Open) { Invoke-Item -Path $OutputPath } return (Get-Item -Path $OutputPath) } } |