Custom compliance discovery scripts for Microsoft Intune

Before you can use custom settings for compliance with Microsoft Intune, you must define a script for discovery of custom compliance settings 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 script deploys to devices as part of your custom compliance policies. When compliance runs, 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 have been assigned to a compliance policy can't be deleted until the script has been 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.

Sample discovery script for Windows

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

The following is an example of the output of the sample script above:

{"BiosVersion":"1.24","Manufacturer":"Microsoft Corporation","TPMChipPresent":true}

Sample discovery script for Linux


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 interpeter 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 intepreter 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: Implementing graceful termination mechanisms in your scripts enables them to handle scenarios such as interrups or cancellation signals. By caching and handling these signals properly, your 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 be executed when these signals are received. These actions may include closing open files, releasing acquired locks, or cleaning up temporary resources. Properly handling signals helps to maintain script integrity and improve overall user experience.

For more information, the following guides might be of use:

Add a discovery script to Intune

Before deploying your script in production, test it in an isolated environment to ensure the syntax you use behaves as expected.

  1. Sign into Microsoft Intune admin center and go to Endpoint security > Device compliance > Scripts > Add > (choose your platform).

  2. On Basics, provide a Name.

  3. On Settings, add your script to Detection script. Review your script carefully. Intune doesn’t validate the script for syntax or programmatic errors.

  4. 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.
  5. 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.

Also, note that the workflow for uploading these scripts to the Microsoft Intune admin center does not support scope tags at this time. You must be targeted with the default scope tag to create, edit, or see custom compliance discovery scripts.

Next steps