top of page
  • Writer's pictureWill Francillette

Intune: Custom BitLocker Assessment



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


References

  1. Use custom compliance settings for Linux and Windows devices in Microsoft Intune | Microsoft Learn

  2. Create a JSON file for custom compliance settings in Microsoft Intune | Microsoft Learn

  3. Create a discovery script for custom compliance policy in Microsoft Intune | Microsoft Learn

  4. Get-BitLockerVolume (BitLocker) | Microsoft Learn







1,404 views0 comments
bottom of page