M365Permissions.psm1
#requires -Modules Microsoft.PowerShell.Utility <# .DESCRIPTION See .psd1 .NOTES AUTHOR : Jos Lieben (jos@lieben.nu) Copyright/License : https://www.lieben.nu/liebensraum/commercial-use/ CREATED : 04/11/2024 UPDATED : See GitHub .LINK https://www.lieben.nu/liebensraum/m365permissions .ROADMAP 1.1.x check defender xdr options 1.1.x support for Sharepoint AsApp authorizations #> $helperFunctions = @{ private = @( Get-ChildItem -Path "$($PSScriptRoot)\private" -Filter '*.ps*1' -ErrorAction SilentlyContinue ) public = @( Get-ChildItem -Path "$($PSScriptRoot)\public" -Filter '*.ps*1' -ErrorAction SilentlyContinue ) } ForEach ($helperFunction in (($helperFunctions.private + $helperFunctions.public) | Where-Object { $null -ne $_ })) { try { Switch -Regex ($helperFunction.Extension) { '\.ps(m|d)1' { $null = Import-Module -Name "$($helperFunction.FullName)" -Scope Global -Force } '\.ps1' { (. "$($helperFunction.FullName)") } default { Write-Warning -Message "[$($helperFunction.Name)] Unable to import module function" } } } catch { Write-Error -Message "[$($helperFunction.Name)] Unable to import function: $($error[1].Exception.Message)" } } if ($helperFunctions.public) { Export-ModuleMember -Alias * -Function @($helperFunctions.public.BaseName) } if ($helperFunctions.private) { Export-ModuleMember -Alias * -Function @($helperFunctions.private.BaseName) } #first load config, subsequent loads will detect global var and skip this section (multi-threading) if(!$global:octo){ $global:octo = [Hashtable]::Synchronized(@{}) $global:octo.ScanJobs = @{} $global:octo.PnPGroupCache = @{} $global:octo.LCRefreshToken = $Null $global:octo.LCCachedTokens = @{} $global:octo.connection = "Pending" if ([Environment]::GetCommandLineArgs().Contains('-NonInteractive') -or $False -eq [System.Environment]::UserInteractive) { $global:octo.interactiveMode=$false } else { $global:octo.interactiveMode=$true Clear-Host } $global:octo.moduleVersion = (Get-Content -Path (Join-Path -Path $($PSScriptRoot) -ChildPath "M365Permissions.psd1") | Out-String | Invoke-Expression).ModuleVersion if((Split-Path $PSScriptRoot -Leaf) -eq "M365Permissions"){ $global:octo.modulePath = $PSScriptRoot }else{ $global:octo.modulePath = (Split-Path -Path $PSScriptRoot -Parent) } #sets default config of user-configurable settings, can be overridden by user calls to set-M365PermissionsConfig $global:octo.userConfig = @{} #create the base reports folder $reportsFolder = Join-Path -Path $env:appdata -ChildPath "LiebenConsultancy\Reports" if(!(Test-Path $reportsFolder)){ New-Item -Path $reportsFolder -ItemType Directory -Force | Out-Null } #create the base temp folder $tempFolder = Join-Path -Path $env:appdata -ChildPath "LiebenConsultancy\Temp" if(!(Test-Path $tempFolder)){ New-Item -Path $tempFolder -ItemType Directory -Force | Out-Null } #configure a temp folder specific for this run $global:octo.outputTempFolder = Join-Path -Path $tempFolder -ChildPath "$((Get-Date).ToString("yyyyMMddHHmm"))" if(!(Test-Path $global:octo.outputTempFolder)){ $Null = New-Item -Path $global:octo.outputTempFolder -ItemType Directory -Force } set-M365PermissionsConfig #run verbose log to file if verbose is on if($global:octo.userConfig.LogLevel -eq "Full"){ Start-Transcript -Path $(Join-Path -Path $global:octo.outputTempFolder -ChildPath "M365PermissionsVerbose.log") -Force -Confirm:$False } $global:runspacePool = [runspacefactory]::CreateRunspacePool(1, $global:octo.userConfig.maxThreads, ([system.management.automation.runspaces.initialsessionstate]::CreateDefault()), $Host) $global:runspacePool.ApartmentState = "STA" $global:runspacepool.Open() Write-Host "----------------------------------" Write-Host "Welcome to M365Permissions v$($global:octo.moduleVersion)!" Write-Host "Visit https://www.lieben.nu/liebensraum/m365permissions/ for documentation" Write-Host "Free for non-commercial use, see https://www.lieben.nu/liebensraum/commercial-use/ for commercial use" Write-Host "----------------------------------" Write-Host "" if($global:octo.userConfig.autoConnect -eq $true){ connect-M365 }else{ Write-Host "Before you can run a scan, please run connect-M365" Write-Host "" Write-Host "If you do not want to see this message in the future, run `"set-M365PermissionsConfig -autoConnect `$True`"" Write-Host "" } } #automatically block display of progress bars in non-interactive mode if(!$global:octo.interactiveMode){ $ProgressPreference -eq "SilentlyContinue" } if($global:octo.userConfig.logLevel -eq "Full"){ $global:VerbosePreference = "Continue" $global:InformationPreference = "Continue" $global:DebugPreference = "Continue" }else{ $global:VerbosePreference = "SilentlyContinue" $global:InformationPreference = "SilentlyContinue" $global:DebugPreference = "SilentlyContinue" } |