backup/Backup-GroupPolicyConfigurations.ps1

#Requires -Version 7.0
function Backup-GroupPolicyConfigurations {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)] [string]$BackupPath,
        [Parameter(Mandatory)] [SecureString]$Token,
        [hashtable]$ScopeTagMap = @{}
    )

    try {
        $folder = Join-Path $BackupPath 'Group Policy Configurations'
        $uri = '/beta/deviceManagement/groupPolicyConfigurations'
        $items = Invoke-GraphRequest2 -Uri $uri -Token $Token

        foreach ($item in $items) {
            # fetch definition values with expanded definition metadata
            $defUri = "/beta/deviceManagement/groupPolicyConfigurations/$($item.id)/definitionValues?`$expand=definition(`$select=id,classType,displayName,policyType,hasRelatedDefinitions,version,minUserCspVersion,minDeviceCspVersion)"
            $definitionValues = Invoke-GraphRequest2 -Uri $defUri -Token $Token

            # for each definition value, fetch presentation values
            if ($definitionValues) {
                $definitionValues = @($definitionValues | ForEach-Object {
                    $defValue = $_
                    $presUri = "/beta/deviceManagement/groupPolicyConfigurations/$($item.id)/definitionValues/$($defValue.id)/presentationValues?`$expand=presentation"
                    $presentationValues = Invoke-GraphRequest2 -Uri $presUri -Token $Token

                    if ($presentationValues) {
                        $presentationValues = @($presentationValues | ForEach-Object {
                            Remove-VolatileKeys -InputObject $_
                        })
                        $defValue | Add-Member -MemberType NoteProperty -Name 'presentationValues' -Value $presentationValues -Force
                    }

                    Remove-VolatileKeys -InputObject $defValue
                })
            }

            # attach definition values to the policy
            if ($definitionValues) {
                $item | Add-Member -MemberType NoteProperty -Name 'definitionValues' -Value $definitionValues -Force
            }

            $assignments = Resolve-Assignments -AssignmentsUri "/beta/deviceManagement/groupPolicyConfigurations/$($item.id)/assignments" -Token $Token
            if ($assignments) {
                $item | Add-Member -MemberType NoteProperty -Name 'assignments' -Value $assignments -Force
            }

            $clean = Remove-VolatileKeys -InputObject $item
            Save-BackupItem -Item $clean -Folder $folder -ScopeTagMap $ScopeTagMap
        }
        Write-Verbose "backed up $($items.Count) group policy configurations to $folder"
    }
    catch {
        Write-Error "failed to backup group policy configurations: $_"
        return
    }
}

Export-ModuleMember -Function Backup-GroupPolicyConfigurations