Support tip: Learn how to simplify JSON file creation for custom compliance
Published Sep 15 2022 08:00 AM 13.4K Views

By: Jack Davis – Sr. Product Manager | Microsoft Endpoint Manager – Intune

 

With the recent general availability of custom compliance, customers now have the ability to further define what device compliance means for their organization's managed Windows devices. Custom compliance uses a PowerShell script and an associated JSON file to define one or more rules. The process works like this:

  1. The PowerShell script runs on a device to discover and report on the settings defined in the JSON file.
  2. Then, the JSON file defines the acceptable values for those settings.

 

Depending on your custom compliance script complexity, manually building a JSON file to evaluate your discovery script results can be an error prone process. It’s critical that the associated JSON file is properly formatted for use in Intune and matches the defined Key/Value pairs. We’ve written a PowerShell module that makes this process easier and less error prone which this blog will cover.

 

If you’re not yet familiar with Intune custom compliance, please review Use custom compliance settings in Microsoft Intune before proceeding.

 

Example walkthrough

In this example we’ll create a single custom compliance rule based on 8 remote assistance Firewall Rules, resulting in 116 lines of JSON required for the rule. We’ll use the Firewall Rules “Name” and “Action” properties to define both the discovery (PowerShell script) and the acceptable values in our detection JSON.

 

Discovery script

 

$hash = @{}

$qr = Get-NetFirewallRule | Where-Object {($PSItem.Direction -eq 'Inbound') -and ($PSitem.Name -like '*RemoteAssistance*') -and ($PSitem.Name -notlike '*query*')} | Select-Object Name, Action

foreach ($rule in $qr) {

    $hash.Add($rule.Name, [int64]($rule.Action.value__))

}

return $hash | ConvertTo-Json -Compress

 

 

To validate our code, the output of the above script should resemble the compressed format in the snippet below.

 

Figure 1: JSON code snippet to validate the discovery script output.Figure 1: JSON code snippet to validate the discovery script output.

The script can then be added to Intune by following the guidance in Custom PowerShell scripts for discovery.

 

Figure 2: A screenshot of the Create custom script setup in Intune to create the Firewall rule detection script.Figure 2: A screenshot of the Create custom script setup in Intune to create the Firewall rule detection script.


Detection JSON

Once the discovery script has been defined and uploaded, we then create the detection JSON file. To assist with this, leverage the Intune custom compliance module available in the PowerShell Gallery (refer to the file path below). This module requires PowerShell 6.1 or above.

 

 

PS C:\> Find-Module IntuneCustomCompliance | Install-Module

 


The module consists of 2 cmdlets:

  • New-IntuneCustomComplianceSetting - for use with properly formatting a single rule setting. This cmdlet will provide the JSON export required for upload into Microsoft Endpoint Manager.
  • New-IntuneCustomComplianceRuleSet - to accept multiple Key/Value pairs defined in a single custom compliance policy. This cmdlet then outputs and transforms each setting and its value into a single JSON ruleset that can be imported into Microsoft Endpoint Manager.

 

For this scenario, we’ll use New-IntuneCustomComplianceRuleSet since our example contains multiple Key/Value pairs. To begin, ensure the query results output to a variable ($qr), as detailed in our discovery script above. Be sure to select the object property Key/Value pair to be used in the custom compliance rule. We will select Name and Action as our chosen properties.

 

Figure 3: The output query script showing Name and Action values.Figure 3: The output query script showing Name and Action values.


The query results can now be used with the New-IntuneCustomComplianceRuleSet cmdlet. Use the
Destination parameter to output the JSON file, as shown below. The Action property will output as an integer when converted to JSON.

 

Figure 4: The custom compliance JSON file     created by the IntuneCustomCompliance cmdlet using the Destination parameter.Figure 4: The custom compliance JSON file created by the IntuneCustomCompliance cmdlet using the Destination parameter.


After you’ve run the cmdlet and automated the creation of your JSON file, you’ll need to upload it in Microsoft Endpoint Manager admin center. Before proceeding, ensure you have already uploaded the discovery script you’ve defined to work alongside the newly created JSON file. Create your new compliance policy by navigating to Endpoint security > Device compliance > Create policy (Windows 10 and later) in the admin center. From the Custom compliance drop-down, select the associated discovery script and then import your newly created JSON file.

 

Figure 5: A screenshot of the Compliance policy settings Custom Compliance options.Figure 5: A screenshot of the Compliance policy settings Custom Compliance options.


After you've successfully imported your JSON file, a preview of it will display each rule in a table (see the example below). Complete setting up the compliance rule to prepare for deployment.

 

Figure 6: A screenshot of the setting rules that appear after the JSON file is uploaded in Custom compliance settings.Figure 6: A screenshot of the setting rules that appear after the JSON file is uploaded in Custom compliance settings.


Once deployed, your compliance results for the newly created compliance rule can be displayed in Per-setting status. Your setup is complete.

 

Figure 7: A screenshot of the Per-setting status page showing the Firewall Rule settings configured using the steps outlined in this document and that there are four devices compliant with each setting.Figure 7: A screenshot of the Per-setting status page showing the Firewall Rule settings configured using the steps outlined in this document and that there are four devices compliant with each setting.


In our example above, we automated the manual effort involved in creating the 116-line JSON detection file and formatted it to easily import it into Intune.

 

Figure 8: A snippet of the Custom Compliance JSON file that includes custom Firewall rules.Figure 8: A snippet of the Custom Compliance JSON file that includes custom Firewall rules.


Using custom compliance opens a world of opportunity to increase your organization’s security posture. Use the IntuneCustomCompliance PowerShell module to easily craft complex JSON detection with minimal effort, saving you time to focus on enhancing security.

 

If you have any questions or comments for the Intune team, reply to this post or reach out to @IntuneSuppTeam on Twitter.

6 Comments
Brass Contributor

Great

Copper Contributor

For int64 & Double values does it require an "" or not?

 

are Int64 = 2 and Int64 = "2" considered the same?

Brass Contributor

Hi, 

 

First a compliment. The learn.microsoft.com has getting better compared to TechNet a few years ago. We as long term partner assume it's what customers want when you directly sell them products and services and not over MS partners? 😉 [Accenture feedback...?]

 

For the JSON:

 

For several target languages at one how would you do that? There is no info regarding that under: 

https://learn.microsoft.com/en-us/mem/intune/protect/compliance-custom-json

 

If we want as example de_DE and en_US same message or different messages for the same rule entry:

 

"RemediationStrings":[
{
"Language":"de_DE",
"Title":"Wir supporten nur bestimmte Marken",
"Description": "Wir supporten nur bestimmte Hardware Marken."
}
]

 

Would it look like this? If yes please include a sample on documentation for non coders 😉

 

"RemediationStrings": [
{
"Language": "de_DE",
"Title": "Wir supporten nur bestimmte Marken",
"Description": "Wir supporten nur bestimmte Hardware Marken."
},
{
"Language": "en_US",
"Title": "We support only specific brands",
"Description": "We support only specific hardware brands."
}
]

 

 

Because if we ONLY include as example German de_DE you see this error:

 

Error_wenn_kein_US.jpg

Microsoft

Hey @bretzeli - you are correct that to have two or more languages for the RemediationStrings would indeed look like this, but as you've discovered, you must at least have en-us included. I've put in a documentation revision to reflect this, and to include an example of more than one language.

Copper Contributor

Hi Ben - Trying to use this for determining if a service has the running status, however when converted to json format "Running" becomes '4' . When this happens should the DataType be set to Int64 or String?  And is it 4 or "4"?  
I was hoping to see an example of (Get-Service ServiceName).status and the resultant DataType and Operand specified because it doesn't appear to work for me for either Int64 or String datatype.  Is (Get-Service ServiceName).status supported?

Microsoft

@Derek_Pickell use the DataType as Int64 with Operand 4 without and quotes.

Version history
Last update:
‎Sep 15 2022 03:36 PM
Updated by: