Functions/Export-AHPolicyExemption.ps1
<# .Synopsis Exports Azure Policy Exemptions .DESCRIPTION Exports Azure Policy Exemptions .EXAMPLE Export-AHPolicyExemption -outputDir C:\MyExemptions\ .PARAMETER outputDir The directory to write policy exemptions to .PARAMETER IncludeEmpty Write empty files if there are no exemptions for the policy #> function Export-AHPolicyExemption { [CmdletBinding()] Param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] [ValidateScript({ Test-Path $_ -PathType Container })] $outputDir, [switch] $IncludeEmpty ) Begin { If ($PSVersionTable.PSVersion.Major -lt 7) { throw 'This cmdlet requires PowerShell 7 or greater' } If ('System.Management.Automation.ServerRemoteDebugger' -eq [System.Management.Automation.Runspaces.Runspace]::DefaultRunspace.Debugger.GetType().FullName) { throw 'This cmdlet can only be used on a local host and cannot be used from a remote session.' return } elseif ((get-item env:/).Name -contains 'AZURE_HTTP_USER_AGENT') { throw 'This cmdlet can only be used on a local host and cannot be used from Azure Cloud Shell.' return } <# I moved it to the \Private folder so I could use it in other functions Function Remove-InvalidFileNameChars { param( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [string]$Name ) $invalidChars = [IO.Path]::GetInvalidFileNameChars() -join '' $re = '[{0}]' -f [regex]::escape($invalidChars) return ($Name -replace $re) } #> } Process { $ManagementGroups = Get-AzManagementGroup $ManagementGroupLookup = $ManagementGroups | ForEach-Object { @{$_.Id = $_.DisplayName } } $policy = Get-AzPolicyAssignment | Select-Object @{N = 'DisplayName'; e = { $_.Properties.DisplayName } }, ` @{N = 'ManagementGroup'; E = { $ManagementGroupLookup."$($_.Properties.Scope)" } }, ` * -WarningAction SilentlyContinue | Out-GridView -passthru -Title 'Select policies to export exemptions for' #now that I know what to export, export it ForEach ($PolicyToExport in $policy) { $exemptions = get-azpolicyExemption -PolicyAssignmentIdFilter $PolicyToExport.ResourceId If (($Null -eq $exemptions -and $IncludeEmpty) -or ($Null -ne $exemptions)) { $filename = Remove-InvalidFileNameChars $PolicyToExport.Properties.DisplayName If ($filename.Length -gt 59) { $filename = $filename.substring(0, 59) } $filename += '.json' $outFile = join-path $outputDir $filename $exemptions | ConvertTo-Json -Depth 99 | out-file -LiteralPath $outFile } } } End { } } |