Custom compliance discovery scripts for Microsoft Intune
Before you can use custom settings for compliance with Microsoft Intune, you must define a script that can discover the custom compliance settings that are available on devices. The script you use depends on the platform:
- Windows devices use a PowerShell script.
- Linux devices can run scripts in any language as long as the corresponding interpreter is installed and configured on the device.
The discovery script deploys to devices as part of your custom compliance policies. When compliance runs on a device, the script discovers the settings that are defined by the JSON file that you also provide through custom compliance policy.
All discovery scripts:
- Are added to Intune before you create a compliance policy. After being added, scripts are available to select when you create a compliance policy with custom settings.
- Each discovery script can only be used with one compliance policy, and each compliance policy can only include one discovery script.
- Discovery scripts that are assigned to a compliance policy can't be deleted until the script is unassigned from the policy.
- Run on a device that receives the compliance policy. The script evaluates the conditions of the JSON file you upload when creating a custom compliance policy.
- Identify one or more settings, as defined in the JSON, and return a list of discovered values for those settings. A single script can be assigned to each policy, and supports discovery of multiple settings.
In addition, the PowerShell script for Windows:
- Must be compressed to output results in a single line.
- For example:
$hash = @{ Manufacturer = $WMI_ComputerSystem.Manufacturer; BiosVersion = $WMI_BIOS.SMBIOSBIOSVersion; TPMChipPresent = $TPM.TPMPresent}
must include the following line at the end of the script:return $hash | ConvertTo-Json -Compress
The scripts you write must be within the following limits in order to successfully return compliance data to Intune:
- Scripts can be no larger than 1 megabyte (MB) each.
- Output generated by each script can be no larger than 1 MB.
- Scripts must have a limited run time:
- On Linux, scripts must take five minutes or less to run.
- On Windows, scripts must take 10 minutes or less to run.
The following example is a sample PowerShell script that you could use for Windows devices:
$WMI_ComputerSystem = Get-WMIObject -class Win32_ComputerSystem
$WMI_BIOS = Get-WMIObject -class Win32_BIOS
$TPM = Get-Tpm
$hash = @{ Manufacturer = $WMI_ComputerSystem.Manufacturer; BiosVersion = $WMI_BIOS.SMBIOSBIOSVersion; TPMChipPresent = $TPM.TPMPresent}
return $hash | ConvertTo-Json -Compress
Following is an example of the output of the sample script fro Windows:
{"BiosVersion":"1.24","Manufacturer":"Microsoft Corporation","TPMChipPresent":true}
Note
Discovery scripts in Linux are run in the User's context and as such they cannot check for System level settings that require elevation. An example of this is the state/hash
of the /etc/sudoers
file.
Discovery scripts for Linux can call any interpreter that meets your requirements. Ensure that the chosen interpreter is properly installed and configured on the targeted device before the script is deployed. To specify the interpreter for a script, include a shebang line at the top of the script, indicating the path to the interpreter binary.
For example, if your script should use the Bash shell as the interpreter, add the following line at the top of your script:
[ !/bin/bash ]
If you want to use Python for your script, indicate where the interpreter is installed. For example, add the following to the top of your script: [ !/usr/bin/python3 ]
or [ !/usr/bin/env python ]
Recommended best practice: To enable your scripts to handle scenarios like interrupts or cancellation signals, implement graceful termination mechanisms. When a script properly caches and handles these signals, the script can perform cleanup tasks and exist gracefully, ensuring resources are released correctly. For example, you can catch specific signals like SIGINT (interrupt signal) or SIGTERM (termination signal) and define custom actions to run when these signals are received. These actions can include closing open files, releasing acquired locks, or cleaning up temporary resources. Proper handling of signals helps to maintain script integrity and improve overall user experience.
For more information, see the Intune Linux Custom Compliance Samples guide.
Before deploying your script in production, test it in an isolated environment to ensure the syntax you use behaves as expected.
Sign into Microsoft Intune admin center and go to Endpoint security > Device compliance > Scripts > Add > (choose your platform).
On Basics, provide a Name.
On Settings, add your script to Detection script. Review your script carefully. Intune doesn’t validate the script for syntax or programmatic errors.
For Windows only - On Settings, configure the following behavior for the PowerShell script:
- Run this script using the logged on credentials – By default, the script runs in the System context on the device. Set this value to Yes to have it run in the context of the logged-on user. If the user isn’t logged in, the script defaults back to the System context.
- Enforce script signature check – For more information, see about_Signing in the PowerShell documentation.
- Run script in 64 bit PowerShell Host – By default, the script runs using the 32-bit PowerShell host. Set this value to Yes to force the script to run using the 64-bit host instead.
Complete the script creation process. The script is now visible in the Scripts pane of the Microsoft Intune admin center and is available to select when configuring compliance policies.
Because the workflow for uploading these scripts to the Microsoft Intune admin center doesn't support scope tags, you must be assigned the default scope tag to create, edit, or see custom compliance discovery scripts.