Intune allows you to create Custom Compliance policies, to configure additional assessments or having more controls over existing settings.
BitLocker is one of those settings I have experienced some inconsistencies in production environments where it was enabled using different methods such as for example using MBAM or enabled manually but Intune was unable to return the status. It would return an error code with little to no information. This could be a blocker to deploy device-based Conditional Access policies.
Overview
Custom Compliance policy's deployment is fairly easy if you have prior experience with PowerShell and JSON.
It is available for Windows and Linux Azure AD Joined device (or hybrid Azure AD joined)
The policy consists of 2 components:
The discovery script (PowerShell for Windows and POSIX shell script for Linux):
This script runs the script on the device using the Intune Management Extension and can retrieve any information. The only gotcha is that it must return the hash variable inline and convert it as a compressed JSON
hash=@{OsVolumeEncryptionStatus=$isOSDrivesFullyEncrypted;}
return $hash |ConvertTo-Json -Compress
In our case, we will use Get-BitLockerVolume and split the results between Data and Operating System drives
If any of those drives isn't completely encrypted, the compliance status will return false and return the list of drives not encrypted
The JSON setting file:
This file is used to determine what are the required setting's values for the policy to be compliant and also configure the URL help link and the remediation steps.
Deployment
1- The first step to deploy our custom compliance policy is to create our PS script and JSON file
You can download those 2 files from my Git Hub repo: French365Connection (github.com)
$btVolumes=Get-BitLockerVolume
$btOSVolumes=$btVolumes|where-object -filter {$_.VolumeType -eq 'OperatingSystem'}
$btDataVolumes=$btVolumes|where-object -filter {$_.VolumeType -eq 'Data'}
$isOSDrivesFullyEncrypted=$true
$nonEncryptedOsVolumesString=""
foreach($volume in $btOSVolumes )
{
if($volume.VolumeStatus -ne "FullyEncrypted")
{
$isOSDrivesFullyEncrypted=$false
if(-not [String]::isNullOrEmpty($nonEncryptedOsVolumesString))
{
$nonEncryptedOsVolumesString+=","
}
$nonEncryptedOsVolumesString+=$volume.MountPoint.replace(":","")
}
}
$isDataDrivesFullyEncrypted=$true
$nonEncryptedDataVolumesString=""
foreach($volume in $btDataVolumes )
{
if($volume.VolumeStatus -ne "FullyEncrypted")
{
$isDataDrivesFullyEncrypted=$false
if(-not [String]::isNullOrEmpty($nonEncryptedDataVolumesString))
{
$nonEncryptedDataVolumesString+=","
}
$nonEncryptedDataVolumesString+=$volume.MountPoint.replace(":","")
}
}
$hash=@{OsVolumeEncryptionStatus=$isOSDrivesFullyEncrypted; NonEncryptedOsVolumes=$nonEncryptedOsVolumesString;DataVolumeEncryptionStatus=$isDataDrivesFullyEncrypted; NonEncryptedDataVolumes=$nonEncryptedDataVolumesString}
return $hash |ConvertTo-Json -Compress
{
"Rules":[
{
"SettingName":"OsVolumeEncryptionStatus",
"Operator":"IsEquals",
"DataType":"Boolean",
"Operand":true,
"MoreInfoUrl":"https://bing.com",
"RemediationStrings":[
{
"Language":"en_US",
"Title":"Operating System volumes encryption status",
"Description": "The Operating System volumes are not completely encrypted. Please verify the status of the Operating System volumes"
}
]
},
{
"SettingName":"NonEncryptedOsVolumes",
"Operator":"IsEquals",
"DataType":"String",
"Operand":"",
"MoreInfoUrl":"https://bing.com",
"RemediationStrings":[
{
"Language":"en_US",
"Title":"Non encrypted Operating System volumes list",
"Description": "The following Operating System Volumes are not completely encrypted: {ActualValue}."
}
]
},
{
"SettingName":"DataVolumeEncryptionStatus",
"Operator":"IsEquals",
"DataType":"Boolean",
"Operand":true,
"MoreInfoUrl":"https://bing.com",
"RemediationStrings":[
{
"Language":"en_US",
"Title":"Data volumes encryption status",
"Description": "The Data volumes are not completely encrypted. Please verify the status of the Data volumes"
}
]
},
{
"SettingName":"NonEncryptedDataVolumes",
"Operator":"IsEquals",
"DataType":"String",
"Operand":"",
"MoreInfoUrl":"https://bing.com",
"RemediationStrings":[
{
"Language":"en_US",
"Title":"Non encrypted Data volumes list",
"Description": "The following Data volumes are not completely encrypted: {ActualValue}."
}
]
}
]
}
2- Upload the script to Intune: keep in mind that a script can only be used for a single compliance policy.
Intune portal > Devices > Compliance policies > Scripts
Press Add - Windows 10 or later
Enter the general settings and Next
Paste your script and keep the other settings as default - the Get-BitLockerVolume has to run using the system/administrator context
And finally press Create
3- It's time now to create your compliance policy
Go to Intune portal > Devices > Windows > Compliance policies > Create policy > Windows 10 and later
Expand Custom Compliance, toggle Require Custom compliance policy, choose your discovery script and upload for JSON file
To be compliant our script should return:
OsVolumeEncryptionStatus = true
NonEncryptedOsVolumes = ""
DataVolumeEncryptionStatus = true
NonEncryptedDataVolumes = ""
If <driveType>VolumeEncryptionStatus returns false, NonEncrypted<driveType>Volumes will return the list of non compliant drives (mount points)
The description or title can use the variable {ActualValue} to return the script parameter and the notification supports language cultures.
Monitoring
To monitor or troubleshoot the status of your device compliance you can use the Company Portal to return the result of the assessment:
| |
Non Compliant | Compliant |
Or from the IntuneManagementExtension logs
C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\IntuneManagementExtension.log
Non Compliant | |
Compliant |
Your policy scripts are located:
C:\Windows\IMECache\HealthScripts\{GUID}
The discovery script runs every 8 hours and can be pushed on-demand on the device opening
https://portal.manage.microsoft.com/ > Device > Check status
Conclusion
This feature should help deploying device-based Conditional Access policies and ensure sensitive/privileged devices are monitored accordingly. It can be used to retrieve 3rd party AntiVirus for example and so much more use cases. You should check Eric Mannon post about Custom Compliance and his MDE-QuickStart
Comments