Public/Build-IntuneConfigReport.ps1

function Build-IntuneConfigReport {
    [cmdletbinding()]
    param (
        [Parameter(mandatory = $true)]
        [System.Uri]$Tenant,

        [Parameter(mandatory = $true)]
        [System.IO.FileInfo]$OutputFolder,

        [Parameter(mandatory = $false)]
        [ValidateSet('admx','autopilot','deviceCompliance','deviceConfiguration','endpointSecurityPolicy','enrollmentStatus','featureUpdate','scripts','office365','proactiveRemediation','win32Apps')]
        [string[]]$Filter
    )
    try {
        #region authentication
        if (!($PSVersionTable.PSEdition -eq 'core')) {
            throw "Needs to be run in PWSH 7."
        }
        $auth = Get-MsalToken -ClientId $script:applicationId -Tenant $Tenant -DeviceCode
        $authToken = @{
            'Content-Type'  = 'application/json'
            'Authorization' = $auth.CreateAuthorizationHeader()
            'ExpiresOn'     = $($auth.ExpiresOn.LocalDateTime)
        }
        #endregion
        #region Grab the endpoint data
        if ($null -eq $Filter) {
            [string[]]$Filter = 'all'
        }
        Write-Host "Grabbing configuration.. ☕" -ForegroundColor Yellow
        $config = @{
            admxConfiguration      = $Filter -match "all|admx" ? (Get-DeviceManagementPolicy -AuthToken $authToken -ManagementType ADMX) : $null
            autopilot              = $Filter -match "all|autopilot" ? (Get-DeviceManagementPolicy -AuthToken $authToken -ManagementType AutoPilot) : $null
            deviceCompliance       = $Filter -match "all|deviceCompliance" ? (Get-DeviceManagementPolicy -AuthToken $authToken -ManagementType Compliance) : $null
            deviceConfiguration    = $Filter -match "all|deviceConfiguration" ? (Get-DeviceManagementPolicy -AuthToken $authToken -ManagementType Configuration) : $null
            endpointSecurityPolicy = $Filter -match "all|endpointSecurityPolicy" ? (Get-DeviceManagementPolicy -AuthToken $authToken -ManagementType EndpointSecurity) : $null
            enrollmentStatus       = $Filter -match "all|enrollmentStatus" ? (Get-DeviceManagementPolicy -AuthToken $authToken -ManagementType EnrollmentStatus) : $null
            featureUpdate          = $Filter -match "all|featureUpdate" ? (Get-DeviceManagementPolicy -AuthToken $authToken -ManagementType FeatureUpdate) : $null
            scripts                = $Filter -match "all|scripts" ? (Get-DeviceManagementPolicy -AuthToken $authToken -ManagementType Script) : $null
            office365              = $Filter -match "all|office365" ? (Get-MobileAppConfigurations -AuthToken $authToken -MobileAppType Office365) : $null
            proactiveRemediation     = $Filter -match "all|proactiveRemediation" ? (Get-DeviceManagementPolicy -AuthToken $authToken -ManagementType ProactiveRemediation) : $null
            win32Apps              = $Filter -match "all|win32Apps" ? (Get-MobileAppConfigurations -AuthToken $authToken -MobileAppType Win32) : $null
        }
        #endregion
        #region configuration
        $outputPath = "$outputFolder\$Tenant"
        $paths = @{
            admx              = (($config.admxConfiguration) ? "$outputPath\admx" : $null)
            apps              = (($config.win32Apps) ? "$outputPath\apps" : $null)
            autopilotPath     = (($config.autoPilot) ? "$outputPath\autopilot" : $null)
            compliancePath    = (($config.deviceCompliance) ? "$outputPath\compliance-policies" : $null)
            configurationPath = (($config.deviceConfiguration) ? "$outputPath\config-profiles" : $null)
            endpointSecurity  = (($config.endpointSecurityPolicy) ? "$outputPath\endpoint-security-policies" : $null)
            esp               = (($config.enrollmentStatus) ? "$outputPath\esp" : $null)
            fu                = (($config.featureUpdate) ? "$outputPath\feature-update" : $null)
            o365              = (($config.office365) ? "$outputPath\o365" : $null)
            prScripts         = (($config.proactiveRemediation) ? "$outputPath\proactive-remediation-scripts" : $null)
            scriptPath        = (($config.scripts) ? "$outputPath\scripts" : $null)
        }
        $markdownReport = "$outputPath\$Tenant`_report.md"
        #endregion
        #region prepare folder structure
        foreach ($p in ($paths.values | Where-Object { $null -ne $_ })) {
            if (!(Test-Path $p)) {
                New-Item -Path $p -ItemType Directory -Force | Out-Null
            }
        }
        if (!(Test-Path $markdownReport)) {
            New-Item -Path $markdownReport -ItemType File -Force | Out-Null
        }
        else {
            Remove-Item -Path $markdownReport -Force | Out-Null
            New-Item -Path $markdownReport -ItemType File -Force | Out-Null
        }
        #endregion
        #region Generate Title of report
        #endregion
        #region ADMX
        if ($config.admxConfiguration) {
            Write-Host "`rGenerating Report:" -NoNewline -ForegroundColor Yellow
            Write-Host " ADMX Policies " -NoNewline -ForegroundColor Green
            "## ADMX Policies`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            foreach ($gpc in $config.admxConfiguration) {
                "`n### $($gpc.displayName)`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
                $folderName = Format-String -inputString $gpc.displayName
                New-Item "$($paths.admx)\$folderName" -ItemType Directory -Force | Out-Null
                $gpcDefinitionValues = Get-GroupPolicyConfigurationsDefinitionValues -GroupPolicyConfigurationID $gpc.id
                foreach ($v in $gpcDefinitionValues) {
                    $definitionValuedefinition = Get-GroupPolicyConfigurationsDefinitionValuesdefinition -GroupPolicyConfigurationID $gpc.id -GroupPolicyConfigurationsDefinitionValueID $v.id
                    $definitionValuedefinitionDisplayName = $definitionValuedefinition.displayName
                    $definitionValuePresentationValues = Get-GroupPolicyConfigurationsDefinitionValuesPresentationValues -GroupPolicyConfigurationID $gpc.id -GroupPolicyConfigurationsDefinitionValueID $v.id
                    $outdef = [PSCustomObject]@{
                        enabled = $($v.enabled.tostring().tolower())
                    }
                    if ($definitionValuePresentationValues.values.count -gt 1) {
                        $presvalues = foreach ($pres in $definitionValuePresentationValues.values) {
                            $pres | Select-Object -Property * -ExcludeProperty id, createdDateTime, lastModifiedDateTime, version, '*@odata*'
                        }
                        $outdef | Add-Member -MemberType NoteProperty -Name "presentationValues" -Value $presvalues
                    }
                    $filename = Format-String -inputString "$($DefinitionValuedefinition.categoryPath)-$definitionValuedefinitionDisplayName"
                    $outdef | ConvertTo-Json -Depth 10 | Out-File -FilePath "$($paths.admx)\$($folderName)\$filename.json" -Encoding ascii
                    $tmp = @{ }
                    $tmp.jsonResult = Format-NullProperties -InputObject $outdef | ConvertTo-Json -Depth 20
                    $tmp.mdResult = (Convert-JsonToMarkdown -json ($tmp.jsonResult) -title "`n##### $($filename -replace '_', ' ')" ) -replace 'presentationValues.',''
                    $tmp.mdResult | Out-File $markdownReport -Encoding ascii -NoNewline -Append
                }
                Format-Assignment -policy $gpc | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            }
            "`n---`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
        }
        #endregion
        #region AutoPilot
        if ($config.autoPilot) {
            Write-Host "`rGenerating Report:" -NoNewline -ForegroundColor Yellow
            Write-Host " AutoPilot Policies " -NoNewline -ForegroundColor Green
            "`n## AutoPilot Policies`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            foreach ($a in $config.autoPilot) {
                Format-Policy -policy $a -markdownReport $markdownReport -outFile "$($paths.autopilotPath)\$(Format-String -inputString $a.displayName)`.json"
                Format-Assignment -policy $a | Out-File $markdownReport -Encoding ascii -NoNewline -Append

            }
            "`n---`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
        }
        #endregion
        #region Compliance
        if ($config.deviceCompliance) {
            Write-Host "`rGenerating Report:" -NoNewline -ForegroundColor Yellow
            Write-Host " Device Compliance Policies " -NoNewline -ForegroundColor Green
            "`n## Device Compliance Policies`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            foreach ($d in $config.deviceCompliance) {
                Format-Policy -policy $d -markdownReport $markdownReport -outFile "$($paths.compliancePath)\$(Format-String -inputString $d.displayName)`.json"
                Format-Assignment -policy $d | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            }
            "`n---`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
        }
        #endregion
        #region Configuration
        if ($config.deviceConfiguration) {
            Write-Host "`rGenerating Report:" -NoNewline -ForegroundColor Yellow
            Write-Host " Device Configuration Policies" -NoNewline -ForegroundColor Green
            "`n## Device Configuration Policies`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            foreach ($d in $config.deviceConfiguration) {
                Format-Policy -policy $d -markdownReport $markdownReport -outFile "$($paths.configurationPath)\$(Format-String -inputString $d.displayName)`.json"
                Format-Assignment -policy $d | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            }
            "`n---`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
        }
        #endregion
        #region Endpoint Security Policies
        if ($config.endpointSecurityPolicy) {
            Write-Host "`rGenerating Report:" -NoNewline -ForegroundColor Yellow
            Write-Host " Endpoint Security Policies " -NoNewline -ForegroundColor Green
            "`n## Endpoint Security Policy`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            foreach ($e in $config.endpointSecurityPolicy) {
                "`n### $($e.displayName)`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
                $folderName = Format-String -inputString $e.displayName
                New-Item "$($paths.endpointSecurity)\$folderName" -ItemType Directory -Force | Out-Null
                # store template
                $e | Select-Object templateId, displayName, description | ConvertTo-Json -Depth 10 | Out-File -FilePath "$($paths.endpointSecurity)\$folderName\template.json" -Encoding ascii
                #store intents
                $intents = $($e.settings | Select-Object '*@odata*', definitionId, ValueJson | ConvertTo-Json -Depth 10)
                @{
                    "settings" = $intents
                } | ConvertTo-Json | Out-File -FilePath "$($paths.endpointSecurity)\$folderName\intent.json" -Encoding ascii
                #expand setting values
                Get-EndpointSecurityPolicyDetails -AuthToken $authToken -ESPolicies $e
                foreach ($s in $e.settings) {
                    if (!($s.valueJson -eq '"notConfigured"' -or $s.valueJson -eq 'null')) {
                        Write-Verbose "$($s.DisplayName): $($s.valueJson)"
                        $tmp = @{}
                        if ((($s.valueJson | ConvertFrom-Json).psobject.members | Where-Object { $_.membertype -eq "NoteProperty" }).count -eq 0) {
                            $tmp.jsonResult = $s | Select-Object @{ Name = $s.DisplayName; Expression = { $_.valueJson | ConvertFrom-Json } } | ConvertTo-Json -Depth 10
                        }
                        else {
                            $tmp.jsonResult = $s | Select-Object @{ Name = 'Value'; Expression = { $_.valueJson | ConvertFrom-Json } } | ConvertTo-Json -Depth 10
                        }
                        $tmp.mdResult = (Convert-JsonToMarkdown -json $tmp.jsonResult -title "#### $($s.DisplayName)") -replace 'Value\.'
                        $tmp.mdResult | Out-File $markdownReport -Encoding ascii -NoNewline -Append
                    }
                    else {
                        Write-Verbose "$($s.DisplayName): $($s.valueJson)"
                    }
                }
                Format-Assignment -policy $e | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            }
            "`n---`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
        }
        #endregion
        #region Enrollment Status Page
        if ($config.enrollmentStatus) {
            Write-Host "`rGenerating Report:" -NoNewline -ForegroundColor Yellow
            Write-Host " Enrollment Status Policies " -NoNewline -ForegroundColor Green
            "`n## Enrollment Status Policy`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            foreach ($e in $config.enrollmentStatus) {
                Format-Policy -policy $e -markdownReport $markdownReport -outFile "$($paths.esp)\$(Format-String -inputString $e.displayName)`.json"
                Format-Assignment -policy $e | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            }
            "`n---`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
        }
        #endregion
        #region Feature Update
        if ($config.featureUpdate) {
            Write-Host "`rGenerating Report:" -NoNewline -ForegroundColor Yellow
            Write-Host " Feature Updates " -NoNewline -ForegroundColor Green
            "`n## Feature Update Policy`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            foreach ($f in $config.featureUpdate) {
                Format-Policy -policy $f -markdownReport $markdownReport -outFile "$($paths.fu)\$(Format-String -inputString $f.displayName)`.json"
                Format-Assignment -policy $f | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            }
            "`n---`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
        }
        #endregion
        #region Scripts
        if ($config.scripts) {
            Write-Host "`rGenerating Report:" -NoNewline -ForegroundColor Yellow
            Write-Host " PowerShell Scripts " -NoNewline -ForegroundColor Green
            "`n## PowerShell Scripts`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            foreach ($s in $config.scripts) {
                $displayName = $null
                $displayName = Format-String -inputString $s.displayName
                #store the script contents locally
                New-Item "$($paths.scriptPath)\$displayName" -ItemType Directory -Force | Out-Null
                [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String("$($s.scriptContent)")) |
                Out-File -FilePath "$($paths.scriptPath)\$displayName\$displayName`.ps1" -Encoding ascii -Force

                $fpParam = @{
                    policy         = $($s | Select-Object displayName, description, runAsAccount, enforceSignatureCheck, fileName, runAs32Bit, '*@odata*', assignments)
                    markdownReport = $markdownReport
                    outFile        = "$($paths.scriptPath)\$displayName\$displayName`.json"
                }
                Format-Policy @fpParam
                Format-Assignment -policy $s | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            }
            "`n---`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
        }
        #endregion
        #region Office 365 Applications
        if ($config.office365) {
            Write-Host "`rGenerating Report:" -NoNewline -ForegroundColor Yellow
            Write-Host " Office 365 " -NoNewline -ForegroundColor Green
            "`n## Office 365 Configuration`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            foreach ($o in $config.office365) {
                Format-Policy -policy $o -markdownReport $markdownReport -outFile "$($paths.o365)\$(Format-String -inputString $o.displayName)`.json"
                Format-Assignment -policy $o | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            }
            "`n---`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
        }
        #endregion
        #region Proactive Remediation Scripts
        if ($config.proactiveRemediation) {
            Write-Host "`rGenerating Report:" -NoNewline -ForegroundColor Yellow
            Write-Host " Remediation Scripts " -NoNewline -ForegroundColor Green
            "`n## Proactive Remediation Scripts`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            foreach ($s in $config.proactiveRemediation) {
                $displayName = $null
                $displayName = Format-String -inputString $s.displayName
                #store the script contents locally
                New-Item "$($paths.prScripts)\$displayName" -ItemType Directory -Force | Out-Null
                #TODO: finish this section
                [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String("$($s.detectionScriptContent)")) |
                Out-File -FilePath "$($paths.prScripts)\$displayName\detection.ps1" -Encoding ascii -Force
                [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String("$($s.remediationScriptContent)")) |
                Out-File -FilePath "$($paths.prScripts)\$displayName\remediation`.ps1" -Encoding ascii -Force

                $fpParam = @{
                    policy         = $($s | Select-Object * -ExcludeProperty detectionScriptContent,remediationScriptContent)
                    markdownReport = $markdownReport
                    outFile        = "$($paths.prScripts)\$displayName\$displayName`.json"
                }
                Format-Policy @fpParam
                Format-Assignment -policy $s | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            }
            "`n---`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
        }
        #endregion
        #region win32 Applications
        if ($config.win32Apps) {
            Write-Host "`rGenerating Report:" -NoNewline -ForegroundColor Yellow
            Write-Host " Win32 Applications " -NoNewline -ForegroundColor Green
            "`n## Win32 Applications`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            foreach ($a in $config.win32Apps) {
                Format-Policy -policy $a -markdownReport $markdownReport -outFile "$($paths.apps)\$(Format-String -inputString $a.displayName)`.json"
                Format-Assignment -policy $a | Out-File $markdownReport -Encoding ascii -NoNewline -Append
            }
            "`n---`n" | Out-File $markdownReport -Encoding ascii -NoNewline -Append
        }
        #endregion
    }
    catch {
        Write-Warning $_.Exception.Message
    }
    finally {
        if (Test-Path $markdownReport -ErrorAction SilentlyContinue) {
            Write-Host "`rReport Generated:" -NoNewline -ForegroundColor Green
            Write-Host " $markdownReport 🍻`n" -ForegroundColor Yellow
        }
    }
}