Do you backup/export your Intune policies – encrypted?

Posted by

Since a while ago I encountered that Microsoft Graph returns some policies encrypted during an export to JSON. Using these exports in a backup and restore scenario will not work!

More specifially this happens in windows10CustomConfiguration if consists of a row with a string, the export might look something like this while using the Intune samples from Microsoft

Encrypted windows10CustomConfiguration

It was rather frustrating to discover these encrypted rows during an import and having to rewrite everything, so here is a quick post for some background and how to fix. 🙂

I would not say it is that hard, it just requires multiple Graph request – one per row that is encrypted – to return the decrypted information. The documentation will not help you that much as of today: getOmaSettingPlainTextValue function – Microsoft Graph v1.0 | Microsoft Docs, but will give you a couple of hints – such as format of the request

https://graph.microsoft.com/v1.0/deviceManagement/deviceConfigurations/{deviceConfigurationId}/getOmaSettingPlainTextValue(secretReferenceValueId='parameterValue')

The trick here is to call each encrypted row with each rows’ secretReferenceValueId. So the high level code would look like

  1. Get the device configuration policy, today it only affects Windows custom policies
  2. Found out if there is a row with the property: isEncrypted=True
  3. Make a Graph API request with the value of that rows’ secretReferenceValueId

I just pushed an update to DeviceConfiguration_Get.ps1 on Microsofts Git to decrypt the necessary policies, until is might be published you can find the changes here and the full script on my Git

First add this function

Function Get-DecryptedDeviceConfigurationPolicy(){

    <#
    .SYNOPSIS
    This function is used to decrypt device configuration policies from an json array with the use of the Graph API REST interface
    .DESCRIPTION
    The function connects to the Graph API Interface and decrypt Windows custom device configuration policies that is encrypted
    .EXAMPLE
    Decrypt-DeviceConfigurationPolicy -dcps $DCPs
    Returns any device configuration policies configured in Intune in clear text without encryption
    .NOTES
    NAME: Decrypt-DeviceConfigurationPolicy
    #>
    
    [cmdletbinding()]
    
    param
    (
        $dcps
    )
    
    $graphApiVersion = "Beta"
    $DCP_resource = "deviceManagement/deviceConfigurations"
    
    foreach ($dcp in $dcps) {
        if ($dcp.'@odata.type' -eq "#microsoft.graph.windows10CustomConfiguration") {
            # Convert policy of type windows10CustomConfiguration
            foreach ($omaSetting in $dcp.omaSettings) {
                try {

                    if ($omaSetting.isEncrypted -eq $true) {
                        $DCP_resource_function = "$($DCP_resource)/$($dcp.id)/getOmaSettingPlainTextValue(secretReferenceValueId='$($omaSetting.secretReferenceValueId)')"
                        $uri = "https://graph.microsoft.com/$graphApiVersion/$($DCP_resource_function)"
                        $value = ((Invoke-RestMethod -Uri $uri -Headers $authToken -Method Get).Value)

                        #Remove any unnecessary properties
                        $omaSetting.PsObject.Properties.Remove("isEncrypted")
                        $omaSetting.PsObject.Properties.Remove("secretReferenceValueId")
                        $omaSetting.value = $value
                    }

                }            
                catch {
            
                    $ex = $_.Exception
                    $errorResponse = $ex.Response.GetResponseStream()
                    $reader = New-Object System.IO.StreamReader($errorResponse)
                    $reader.BaseStream.Position = 0
                    $reader.DiscardBufferedData()
                    $responseBody = $reader.ReadToEnd();
                    Write-Host "Response content:`n$responseBody" -f Red
                    Write-Error "Request to $Uri failed with HTTP Status $($ex.Response.StatusCode) $($ex.Response.StatusDescription)"
                    write-host
                    break
                
                }
            }
        }
    }
    $dcps

}

And to decrypt all device configuration policies, just add the bold row in the end of the script

$DCPs = Get-DeviceConfigurationPolicy
$DCPs = Get-DecryptedDeviceConfigurationPolicy -dcp $DCPs

write-host

foreach($DCP in $DCPs){

Here are the full script on my Git: DeviceConfiguration_Get.ps1

3 comments

  1. Your script sample does not include an export-json function. Is it possible for you to add that to the code I don’t know how to get the policy written to a Json file

    Like

  2. Thank you for your code. I was able to convert an export my large list of OMAURIs from one tenant to another. Two things I noted was that only Strings seem to be encrypted, Integers were not, but need to have the isEncrypted and referenceid removed. Also, if you use a String XML entry vs. String, you will get a “cannot convert the literal to the expected type ‘edm.binary'” error on importing that is a bit hard to figure out, until you see it’s referencing the .xml file, just switched it to normal string and it worked. Very happy I found this page!

    Like

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.