Enabling BitLocker on non-HSTI devices with Intune

BitLocker-Drive

This is a post about enabling BitLocker on non-HSTI devices with Windows 10 version 1809 and standard user permissions.

First of all a little background on HSTI. HSTI is a Hardware Security Testability Interface. It is an interface to report the results of security-related self-tests. Its purpose is to provide high assurance validation of proper security configuration.

The enhancement with Windows 10 version 1809 is that we are able to activate BitLocker with a MDM policy (Intune), even for non-HSTI devices and on Windows 10 Pro Edition. This was not working with Windows 10 version 1803 or lower and the community came up with custom solutions to handle this like custom PowerShell scripts deployed via Intune Management Extension. If we wanted to use Intune native MDM policies via the BitLocker CSP we needed HSTI compliant devices like the Surface devices or newer hardware devices which are mostly delivered as HSTI compliant devices now. To successful start the encryption as a standard user, a Windows 10 version 1803 was the minimum as the feature was introduced with this version.

The prerequisites for Intune BitLocker configuration are:

  • Windows 10 version 1809 Enterprise and Pro
  • Azure Active Directory joined devices
  • Microsoft Intune
  • non-HSTI device

Older devices can be protected by Intune BitLocker policy now?

Yes, as long as they are running Windows 10 version 1809. The most common problem is that we do not replace all devices in every Windows 10 project to have only latest HSTI compliant devices in the environment. We have to support older devices purchased maybe not long ago but not HSTI compliant. These devices can now be managed by an Intune device configuration policy to turn on BitLocker silently without administrative permissions as long as the device is a Windows 10 version 1809 device.

What do we need to do?

Currently at the time of writing we need two configuration policies. One endpoint protection profile and a custom profile.

The endpoint protection profile configures the silent BitLocker enforcement and other parameters like encryption strength. Go to Microsoft Intune > Device configuration – Profiles > yourpolicyname – Properties > Endpoint protection > Windows Encryption

Set Encrypt devices to Require
Set Warning for other disk encryption to Block

Sure you can set other parameters like encryption methods as well, but for a functional test this is enough.

These two settings make sure the encryption starts and it starts silently as we block the warning dialog for other disk encryption software.

Example shown below:

BitLockerIntuneEndpointProtection

The second profile is a custom profile (at time of writing it was not available in the UI) and it configures the ability to enforce the BitLocker encryption even when standard users are logging in. For example when the Windows 10 device is enrolled with an Autopilot profile where the user account type is set to standard user. AllowStandardUserEncryption is a new setting introduced with Windows 10 version 1809 BitLocker CSP and must be used in conjunction with the setting “Warning for other disk encryption set to Block” otherwise it is not functional!

The custom OMA-URI configuration must be configured like this:

OMA-URI: ./Vendor/MSFT/BitLocker/AllowStandardUserEncryption
Data type: integer
Value: 1

Example shown below:

BitLockerIntuneCustom

See the Update section below for a new UI setting available in Intune 1901 release.

The two policies must be assigned to a user group or device group to test the new policies. To force the user type to a standard user after enrollment we need an Autopilot profile and assign it to our device.

AutopilotStandardUser

If we now enroll a new Windows 10 version 1809 non-HSTI device it must be encrypted silently and the recovery key must be backed up to Azure AD.

How can I easily verify this?

I used a Hyper-V VM Generation 2 with an enabled TPM module:

BitLockerHyperVVMTPM

To test if the VM is reporting as a non-HSTI compliant device I downloaded the Device Guard and Credential Guard hardware readiness tool and verified the HSTI status with the following PowerShell command:

.\DG_Readiness_Tool_v3.5.ps1 -Capable

The result is displayed like this:

HyperVVMHSTICheck

During my test I had to make sure that after the first restart, the Windows 10 version 1809 ISO is ejected, otherwise silent BitLocker encryption will fail. This is because the system does not have the normal start parameters during the BitLocker and TPM provisioning. The platform would take into account the additional media as the normal platform verification parameter. Which means after ejecting the ISO it would have prompted us for the recovery key. Microsoft takes care of this situation and does not start the BitLocker provisioning process at all. So, the generation of the platform default configuration parameters for later verification to unlock the TPM is prevented, as long as a removable media is inserted. See the failure event here:

BitLockerSilentEncryptionErrorIso

Without an ISO it will successfully starts the encryption and key backup to Azure AD. A success event is shown below:

BitLockerVMeventlog

The BitLocker state can be verified with the PowerShell command on the client:

Get-BitLockerVolume | fl
BitLockerVMPSStatus

In the Intune portal we can see the recovery key appended to the AAD device object:

BitLockerIntuneAADDeviceRK

UPDATE

Since Intune January 21th 2019 Release (aka 1901) we are able to configure the BitLocker Allow Standard User setting via UI element:

Further information

What’s new in Windows 10, version 1809 for IT Pros
https://docs.microsoft.com/en-us/windows/whats-new/whats-new-windows-10-version-1809#bitlocker

Device Guard and Credential Guard hardware readiness tool
https://www.microsoft.com/en-us/download/details.aspx?id=53337

Hardware Security Testability Specification
https://docs.microsoft.com/en-us/windows-hardware/test/hlk/testref/hardware-security-testability-specification

Go ahead and start encrypting all your Windows 10 devices to strengthen your security level πŸ‘

Deep dive Microsoft Intune Management Extension – PowerShell Scripts

Microsoft made a big step forward in the Modern Management field. Limitations like custom configurations or even Win32 App installs can be addressed now. Microsoft developed an EMS agent (aka SideCar) and released it as a new Intune feature called Intune Management Extension. This agent is able to manage and execute PowerShell scripts on Windows 10 devices and it does this quite well.

IntuneManagementExtensionMSIProperties

We can simply upload our own PowerShell scripts for device configuration:

PowerShellScriptsIntune

Part 2 of this article answers common questions I’ve seen, when working with the Intune Management Extension – Part 2, Deep dive Microsoft Intune Management Extension – PowerShell Scripts.

Part 3 of this series will dive into the Microsoft Intune Management Extension – Win32 Apps deployment capabilities – Part 3, Deep dive Microsoft Intune Management Extension – Win32 Apps

How do we get the agent installed on the devices?

The ability to deploy basic MSI packages via MDM OMA-DM channel, is provided by Microsoft since the beginning of Windows 10. This is achieved by using the EnterpriseDesktopAppManagement CSP.

Microsoft is using this mechanism to deploy the agent to Windows 10 devices. Beginning with Windows 10 Version 1607 we have support of the Intune Management Extension now. The device must be AAD joined and the automatic MDM enrollment must be enabled (see Prerequisites).

The workflow is basically like this. If a PowerShell script is assigned to a user group (device groups are not supported since 22th of Oct.) and the agent is not installed, it will be pushed down automatically to the device via EnterpriseDesktopAppManagement CSP by Intune. This can be verified and traced in the “Advanced Diagnostics Report” of the MDM management.

Open Settings > Accounts > Access work or school > Connected to TenantName’s Azure AD > Info > scroll down to the bottom and click “Create report”

AdvancedDiagnosticsReport

Now you get an report about all MDM configurations including the desktop app installations. Here we can see the EnterpriseDesktopAppManagement msi install of the EMSAgent with the ProductCode: {25212568-E605-43D5-9AA2-7AE8DB2C3D09}

EMSAgentInstallReport

./device/Vendor/MSFT/EnterpriseDesktopAppManagement/MSI/%7B25212568-E605-43D5-9AA2-7AE8DB2C3D09%7D

The instruction can be translated into more human readable form with ProductCode and curly brackets, as the yellow marked resource uses URL encoding and here %7B = { and %7D = }

./device/Vendor/MSFT/EnterpriseDesktopAppManagement/MSI/{25212568-E605-43D5-9AA2-7AE8DB2C3D09}

If the device encounters any error during installation of the agent, we can troubleshoot this with the eventlog:

Start event viewer > Applications and Services Logs > Microsoft > Windows > DeviceManagement-Enterprise-Diagnostics-Provider > Admin

An example where the agent installation went wrong with an error event id 1924 looks like this:

Event ID 1924, Error

EnterpriseDesktopAppManagement CSP: An application install has failed. 
Examine the MSI log (C:\Windows\system32\config\systemprofile\AppData\
Local\mdm\{25212568-E605-43D5-9AA2-7AE8DB2C3D09}.log) for more details. 
Install command: ("C:\Windows\system32\msiexec.exe" /quiet /l*v 
C:\Windows\system32\config\systemprofile\AppData\Local\mdm\
{25212568-E605-43D5-9AA2-7AE8DB2C3D09}.log /qn /i "C:\Windows\system32\
config\systemprofile\AppData\Local\mdm\
{BD19E4D8-D6C9-48B2-A53C-579D03B29FE9}.msi" ), 
MSI ProductCode: {25212568-E605-43D5-9AA2-7AE8DB2C3D09}, 
User SID: (S-0-0-00-0000000000-0000000000-000000000-000), 
Result: (User cancelled installation.).

Here we can see the original MSI install command including logfile path for further analysis:

C:\Windows\system32\config\systemprofile\AppData\Local\mdm\ {25212568-E605-43D5-9AA2-7AE8DB2C3D09}.log

The agent will get installed in the 32-bit Program Files path:

C:\Program Files (x86)\Microsoft Intune Managment Extension

IntuneManagementExtension

How does the agent gets it’s policy?

The agent will start to figure out the service endpoint via Service Discovery. A common approach in Microservices architecture in modern cloud platforms. After getting the Intune Service URL (https://somemssubdomain.manage.microsoft.com/SideCar/StatelessSideCarGatewayService) the agent can start to communicate and will receive its assigned policies.

All this can be traced in the logfiles here:

C:\ProgramData\Microsoft\IntuneManagementExtension\Logs

IntuneManagementExtensionLogs

The agent will start to download and execute the assigned PowerShell script here:

C:\Program Files (x86)\Microsoft Intune Managment Extension\Policies\Scripts\UserGUID_ScriptGUID.ps1

and the results are written here:

C:\Program Files (x86)\Microsoft Intune Managment Extension\Policies\Results\UserGUID_ScriptGUID.output|.error|.timeout

After successful execution the script and results are cleaned up and nothing is left on the device. Corresponding registry entries for the assigned scripts and execution results are here:

HKLM\SOFTWARE\Microsoft\IntuneManagementExtension\Policies\UserGUID\ScriptGUID

IntuneManagementExtensionRegistry

How often does the agent check for new policies?

The default is every 60 minutes.

What are the PowerShell script execution options?

We can execute scripts in system context or user context. Optional we can enforce a signature check.

ScriptSettings

The current file size limit is 10KB for ASCII scripts and 5KB for unicode scripts. The current file size limit is max. 200KB.

How do I enforce next agent check for policies?

Simply restart the Windows Service “Microsoft Intune Management Extension”.

IntuneManagementExtensionWindowsService

Is there a particular order in which multiple scripts are executed?

No, they are executed in random order.

What can be done with the PowerShell script execution?

Some examples and potentially pitfalls with the usage of the Intune Management Extension are listed below:

Install Win32 application

Install Win32 applications can be done easily by using a web request to get sources for the installation and finally execution of the sources. This technique is used a lot in the Chocolatey space. A simple example with 7-zip is shown below and can be modified to your needs:

# Author: Oliver Kieselbach
# Date: 11/28/2017
# Description: Download executable or msi and execute to install.

# The script is provided "AS IS" with no warranties.
$url = "http://www.7-zip.org/a/7z1701-x64.msi"
$filePath = "c:\windows\temp\7z1701-x64.msi"
$ProgressPreference = 0
Invoke-WebRequest $url -OutFile $filePath -UseBasicParsing
& $filePath /quiet

To use Chocolatey you should follow the install instructions from the Chocolatey website:

iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

After Chocolatey Framework installation you can use choco.exe install Package in additional PS scripts to install Chocolatey software. An excellent post from Peter van der Woude regarding Chocolatey and Intune Management Extension can be found here: Combining the powers of the Intune Management Extension and Chocolatey

Write registry keys in x64 hive and not WOW6432Node

As the agent is an 32-bit agent every PowerShell script execution will be in the 32-bit agent process. If we write a registry key on a x64 device from a 32-bit process it will be redirected to the WOW6432Node in the registry. This is often not the desired behavior. To solve this we can restart the script as a 64-bit process for script execution. An example to write a registry key to the x64 hive with this technique is shown below:

# Author: Oliver Kieselbach
# Date: 11/28/2017
# Description: Write to registry and ensure execution from x64 process environment.

# The script is provided "AS IS" with no warranties.

Param([switch]$Is64Bit = $false)

Function Restart-As64BitProcess
{
If ([System.Environment]::Is64BitProcess) { return }
$Invocation = $($MyInvocation.PSCommandPath)
if ($Invocation -eq $null) { return }
$sysNativePath = $psHome.ToLower().Replace("syswow64", "sysnative")
Start-Process "$sysNativePath\powershell.exe" -ArgumentList "-ex bypass -file `"$Invocation`" -Is64Bit" -WindowStyle Hidden -Wait
}

Function New-RegistryKey
{
Param([Parameter(Mandatory = $true)]
[string]$Key,
[Parameter(Mandatory = $true)]
[string]$Name,
[Parameter(Mandatory = $true)]
[string]$Value,
[ValidateSet("String", "ExpandString", "Binary", "DWord", "Multistring", "QWord", ignorecase=$true)]
[string]$Type = "String")
try
{
$subkeys = $Key.split("\")

foreach ($subkey in $subkeys)
{
$currentkey += ($subkey + '\')
if (!(Test-Path $currentkey))
{
New-Item -Type String -Path $currentkey | Out-Null
}
}

Set-ItemProperty -Path $currentkey -Name $Name -Value $Value -Type $Type -ErrorAction SilentlyContinue
}
catch [system.exception]
{
$message = "{0} threw an exception: `n{0}" -f $MyInvocation.MyCommand, $_.Exception.ToString()
Write-Host $message
}
}

if (!$Is64Bit) { Restart-As64BitProcess }
else
{
# Enable Potentially Unwanted Application protection
New-RegistryKey -Key "hklm:\SOFTWARE\Microsoft\Windows Defender" -Name "PUAProtection" -Value "1" -Type DWord
}

Please see my GitHub account for Intune Management Extension Samples for a enhanced and maintained PowerShell Template (IntunePSTemplate.ps1) which takes care of x64 restarting, logging and so on!

UPDATE
With the Intune February 18, 2019 Update the ability to run a script in a 64-bit process was added. The template script to restart in a 64-bit process is therefore not necessary anymore when running PowerShell scripts with Intune, but in case of Win32 apps and potential install wrapper scripts, it might still be necessary to re-start the wrapper for the Win32 apps installation.

Execute in user context and show dialog

To show a simple example to execute scripts in user context we can use the following script to present a Message Box to the user:

Add-Type -AssemblyName PresentationFramework
[System.Windows.MessageBox]::Show('Hello World from Sid-Car!')
HelloSideCar

I hope this explains the technical implementation of the Microsoft Intune Management Extension and the extension addresses some road blockers you might have in the past with Intune regarding advanced configurations.

See also my follow up post Part 2, Deep dive Microsoft Intune Management Extension – PowerShell Scripts for even more details and common questions around architecture and troubleshooting.

Part 3 of this series will dive into the Microsoft Intune Management Extension – Win32 Apps deployment capabilities – Part 3, Deep dive Microsoft Intune Management Extension – Win32 Apps