Modules/M365DSCPermissions.psm1
using namespace System.Management.Automation.Language function Get-M365DSCCompiledPermissionList { [CmdletBinding(DefaultParametersetName = 'None')] [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory = $true, Position = 0)] [System.String[]] $ResourceNameList ) $results = @{ UpdatePermissions = @() ReadPermissions = @() } foreach ($resourceName in $ResourceNameList) { $settingsFilePath = $null try { $settingsFilePath = Join-Path -Path $PSScriptRoot ` -ChildPath "..\DSCResources\MSFT_$resourceName\settings.json" ` -Resolve ` -ErrorAction Stop } catch { Write-Verbose -Message "File settings.json was not found for resource {$resourceName}" } if ($null -ne $settingsFilePath) { $fileContent = Get-Content $settingsFilePath -Raw $jsonContent = ConvertFrom-Json -InputObject $fileContent foreach ($updatePermission in $jsonContent.permissions.update) { if (-not $results.UpdatePermissions.Contains($updatePermission.name)) { Write-Verbose -Message "Found new Update permission {$($updatePermission.name)}" $results.UpdatePermissions += $updatePermission.name } else { Write-Verbose -Message "Update permission {$($updatePermission.name)} was already added" } } foreach ($readPermission in $jsonContent.permissions.read) { if (-not $results.ReadPermissions.Contains($readPermission.name)) { Write-Verbose -Message "Found new Read permission {$($readPermission.name)}" $results.ReadPermissions += $readPermission.name } else { Write-Verbose -Message "Read permission {$($readPermission.name)} was already added" } } } } return $results } function Update-M365DSCAllowedGraphScopes { [CmdletBinding()] [OutputType()] param ( [Parameter()] [System.String[]] $ResourceNameList, [Parameter()] [Switch] $All, [Parameter(Mandatory = $true)] [ValidateSet('Read', 'Update')] [System.String] $Type ) if ($All) { Write-Verbose -Message 'All parameter specified' $dscResourcesRoot = Join-Path -Path $PSScriptRoot -ChildPath '..\DSCResources' $resourceNames = (Get-ChildItem -Path $dscResourcesRoot -Directory).Name -replace "MSFT_", '' $permissions = Get-M365DSCCompiledPermissionList -ResourceNameList $resourceNames } else { if ($PSBoundParameters.ContainsKey('ResourceNameList') -eq $false) { throw "You have to specify either the All or ResourceNameList parameter!" } Write-Verbose -Message "Specified resources: $($ResourceNameList -join ", ")" $permissions = Get-M365DSCCompiledPermissionList -ResourceNameList $ResourceNameList } if ($Type -eq 'Read') { Write-Verbose -Message 'Specified type: Read' Write-Verbose -Message "Found permissions: $($permissions.ReadPermissions -join ", ")" $params = @{ Scopes = $permissions.ReadPermissions } } else { Write-Verbose -Message 'Specified type: Update' Write-Verbose -Message "Found permissions: $($permissions.UpdatePermissions -join ", ")" $params = @{ Scopes = $permissions.UpdatePermissions } } Write-Verbose -Message 'Connecting to MS Graph to update permissions' $result = Connect-MgGraph @params if ($result -eq 'Welcome To Microsoft Graph!') { Write-Output 'Allowed Graph scopes updated!' } else { Write-Output 'Error during updating allowed Graph scopes!' } } function Update-M365DSCResourcesSettingsJSON { [CmdletBinding()] [OutputType()] param() Write-Verbose "Determining DSCResources path" $dscResourcesRoot = Join-Path -Path $PSScriptRoot -ChildPath '..\DSCResources' Write-Verbose " DSCResouces path: $dscResourcesRoot" Write-Verbose "Getting all psm1 files" $files = Get-ChildItem -Path "$dscResourcesRoot\*.psm1" -Recurse Write-Verbose " Found $($files.Count) psm1 files" foreach ($file in $files) { $readPermissions = @() $updatePermissions = @() if ($file -notlike "*Intune*") { Write-Verbose "Processing file: $($file.BaseName)" $content = Get-Content $file -Raw $sb = [ScriptBlock]::Create($content) $Predicate = { param( [Ast] $AstObject ) return ( $AstObject -is [FunctionDefinitionAst] ) } $functions = $sb.Ast.FindAll($Predicate, $true) $functions = $functions | Where-Object { $_.Name -in ("Get-TargetResource", "Set-TargetResource") } foreach ($function in $functions) { Write-Verbose " Function: $($function.Name)" $regex = [Regex]::new('(?<Cmdlet>(Update|Get|Remove|Set)-Mg\w*)') $regexMatches = $regex.Matches($function.Extent.Text) $cmdlets = $regexMatches.Value | Sort-Object | Select-Object -Unique $functionPermissions = @() foreach ($cmdlet in $cmdlets) { $commands = Find-MgGraphCommand -Command $cmdlet $cmdletPermissions = $commands[0].Permissions $functionPermissions += $cmdletPermissions.Name } $cleanFunctionPermissions = $functionPermissions | Sort-Object | Select-Object -Unique if ($null -ne $cleanFunctionPermissions) { switch ($function.Name) { "Get-TargetResource" { $readPermissions = @() foreach ($item in $cleanFunctionPermissions) { $readPermissions += [PSCustomObject]@{ name = $item } } } "Set-TargetResource" { $updatePermissions = @() foreach ($item in $cleanFunctionPermissions) { $updatePermissions += [PSCustomObject]@{ name = $item } } } } } } $settingsFile = Join-Path -Path $file.DirectoryName -ChildPath 'settings.json' if (Test-Path -Path $settingsFile) { Write-Verbose " Updating existing settings.json file" $settingsJson = Get-Content -Path $settingsFile -Raw $settings = ConvertFrom-Json $settingsJson if ($readPermissions.Count -eq 0 -and $settings.permissions.read.Count -ne 0) { [array]$readPermissions = $settings.permissions.read } if ($updatePermissions.Count -eq 0 -and $settings.permissions.update.Count -ne 0) { [array]$updatePermissions = $settings.permissions.update } $settings.permissions = @([PSCustomObject]@{ read = $readPermissions update = $updatePermissions }) } else { Write-Verbose " Creating new settings.json file" $settings = [PSCustomObject]@{ resourceName = $file.BaseName -replace 'MSFT_' description = "" permissions = @([PSCustomObject]@{ read = $readPermissions update = $updatePermissions }) } } $json = ConvertTo-Json -InputObject $settings -Depth 10 Set-Content -Path $settingsFile -Value $json -Encoding UTF8 } else { Write-Verbose "$($file.BaseName) - Skipping Intune resources (unable to process those Graph cmdlets)" } } } |