public/get-changedPermissions.ps1
Function Get-ChangedPermissions{ <# Author = "Jos Lieben (jos@lieben.nu)" CompanyName = "Lieben Consultancy" Copyright = "https://www.lieben.nu/liebensraum/commercial-use/" Parameters: -oldPermissionsFilePath: the path to the old permissions file. Leave one empty to auto-detect both -newPermissionsFilePath: the path to the new permissions file. Leave one empty to auto-detect both -tabs: the tabs to compare, default is all tabs #> Param( [String]$oldPermissionsFilePath, [String]$newPermissionsFilePath, [String[]]$tabs = @("Onedrive","Teams","O365Group","PowerBI","GroupsAndMembers","Entra","ExoRecipients","ExoRoles") ) if(!$oldPermissionsFilePath -or !$newPermissionsFilePath){ $reportFiles = Get-ChildItem -Path $global:octo.outputFolder -Filter "*.xlsx" | Where-Object { $_.Name -notlike "*delta*" } if($reportFiles.Count -lt 2){ Write-Error "Less than 2 XLSX reports found in $($global:octo.outputFolder). Please run a scan first or make sure you set the output format to XLSX. Comparison is not possible when scanning to CSV format." -ErrorAction Stop } $lastTwoReportFiles = $reportFiles | Sort-Object -Property LastWriteTime -Descending | Select-Object -First 2 $oldPermissionsFile = $lastTwoReportFiles[1] Write-Host "Auto detected old permissions file: $($oldPermissionsFile.FullName)" $newPermissionsFile = $lastTwoReportFiles[0] Write-Host "Auto detected new permissions file: $($newPermissionsFile.FullName)" } Write-Host "" $diffResults = @{} $count = 0 foreach ($tabName in $tabs) { $count++ try{$percentComplete = (($count / ($tabs.Count)) * 100)}catch{$percentComplete = 0} Write-Progress -Id 1 -Activity "Comparing $($oldPermissionsFile.LastWriteTime) and $($newPermissionsFile.LastWriteTime)" -Status "$tabName Loading previous permissions..." -PercentComplete $percentComplete if(!$diffResults.$($tabName)){ $diffResults.$($tabName) = @() } try{ $oldTab = $Null; $oldTab = Import-Excel -Path $oldPermissionsFile.FullName -WorksheetName $tabName -DataOnly }catch{$null} Write-Progress -Id 1 -Activity "Comparing $($oldPermissionsFile.LastWriteTime) and $($newPermissionsFile.LastWriteTime)" -Status "$tabName Loading current permissions..." -PercentComplete $percentComplete try{ $newTab = $Null; $newTab = Import-Excel -Path $newPermissionsFile.FullName -WorksheetName $tabName -DataOnly }catch{$null} #current workload not found in new file if ($null -eq $newTab) { if($oldTab.Count -gt 0){ $diffResults.$($tabName) += [PSCustomObject]@{ "ERROR" = "Worksheet $($tabName) not found in NEW file, did you include this in the latest scan?" } } continue } #current workload not found in old file if ($null -eq $oldTab) { if($newTab.Count -gt 0){ $diffResults.$($tabName) += [PSCustomObject]@{ "ERROR" = "Worksheet $($tabName) not found in OLD file, did you include this in the previous scan?" } } continue } #current workload found, check for removals for($i=0;$i -lt $oldTab.Count;$i++){ try{$percentComplete = ((($i+1) / ($oldTab.Count+1)) * 100)}catch{$percentComplete = 0} Write-Progress -Id 2 -Activity "Processing removals for $tabName" -Status "$($i+1) / $($oldTab.Count))" -PercentComplete $percentComplete $oldRow = $oldTab[$i] | ConvertTo-Json -Depth 10 $exists = $False; $exists = $newTab.Where({ ($_ | ConvertTo-Json -Depth 10) -eq $oldRow }, 'First') if (!$exists) { [PSCustomObject]$diffItem = $oldRow | ConvertFrom-Json $diffItem | Add-Member -MemberType NoteProperty -Name Action -Value "Removed" $diffResults.$($tabName) += $diffItem } } Write-Host "Found $($diffResults.$($tabName).count) removed permissions for $tabName" Write-Progress -Id 2 -Activity "Processing removals for $tabName" -Completed #current workload found, check for additions for($i=0;$i -lt $newTab.Count;$i++){ try{$percentComplete = ((($i+1) / ($newTab.Count+1)) * 100)}catch{$percentComplete = 0} Write-Progress -Id 2 -Activity "Processing additions for $tabName" -Status "$($i+1) / $($newTab.Count))" -PercentComplete $percentComplete $newRow = $newTab[$i] | ConvertTo-Json -Depth 10 $existed = $False; $existed = $oldTab.Where({ ($_ | ConvertTo-Json -Depth 10) -eq $newRow }, 'First') if (!$existed) { [PSCustomObject]$diffItem = $newRow | ConvertFrom-Json $diffItem | Add-Member -MemberType NoteProperty -Name Action -Value "New or Updated" $diffResults.$($tabName) += $diffItem } } Write-Host "Found $($diffResults.$($tabName).count) added or updated permissions for $tabName" Write-Progress -Id 2 -Activity "Processing additions for $tabName" -Completed } Write-Progress -Id 1 -Activity "Comparing $($oldPermissionsFile.LastWriteTime) and $($newPermissionsFile.LastWriteTime)" -Status "Saving data" -PercentComplete 99 Remove-Variable -Name newTab -Force -Confirm:$False Remove-Variable -Name oldTab -Force -Confirm:$False Write-Host "" $targetPath = Join-Path -Path $global:octo.outputFolder -ChildPath "M365Permissions_delta.xlsx" foreach($tab in $diffResults.GetEnumerator().Name){ if($diffResults.$($tab).count -eq 0){ continue } $maxRetries = 60 $attempts = 0 while($attempts -lt $maxRetries){ $attempts++ try{ $diffResults.$($tab) | Export-Excel -Path $targetPath -WorksheetName $tab -TableName $tab -TableStyle Medium10 -Append -AutoSize Write-Host "$($diffResults.$($tab).count) $tab delta's written to $targetPath" $attempts = $maxRetries }catch{ if($attempts -eq $maxRetries){ Throw }else{ Write-Verbose "File locked, waiting..." Start-Sleep -s (Get-Random -Minimum 1 -Maximum 3) } } } } Remove-Variable -Name diffResults -Force -Confirm:$False [System.GC]::Collect() Write-Progress -Id 1 -Activity "Comparing $($oldPermissionsFile.LastWriteTime) and $($newPermissionsFile.LastWriteTime)" -Completed } |