Skip to main content

Remediating BitLocker DMA Exception Errors with Microsoft Intune

· loading ·
Intune BitLocker PowerShell Windows 10 and later Security
Author
Nick Benton
Principal Cloud Endpoint Consultant and Intune Blogger
Table of Contents

Silently encrypting Windows 10 and later devices in Microsoft Intune isn’t anything new, removing reliance on Administrator permissions to encrypt a device during either Windows Autopilot or otherwise, as long as your configuration meets the pre-requisites and you’re only using a TPM (Trusted Platform Module) as a pre-boot authentication method.

What happens when you have devices that don’t want to silently or automatically encrypt with them complaining about the detection of Un-allowed DMA capable bus/device(s) in the event log. With the Microsoft recommendation solution to add registry items to allow for these exceptions on the failing devices, we should see if a bit of PowerShell and Microsoft Intune can do to fix this issue.

Direct Memory Access Exceptions
#

If you are subject to this DMA-based issue, and if you’ve got either Dell, HP or Lenovo devices you probably are, with the BitLocker-API Management event log complaining about these Un-allowed DMA exceptions in Event ID 4112, with text similar to the below:

The following DMA (Direct Memory Access) capable devices are not declared as protected from external access, which can block security features such as BitLocker automatic device encryption:

LPC Controller:
    PCI\VEN_8086&DEV_519D (Intel(R) LPC Controller - 519D)

PCI-to-PCI Bridge:
    PCI\VEN_8086&DEV_51B1 (Intel(R) PCI Express Root Port #10 - 51B1)

And System Information showing something like this:

BitLocker System Info
Screenshot of System Information showing DMA Exceptions

Instead of having to manually create the recommended registry settings, only after changing permissions on the Key to allow for these exceptions detailed in the Microsoft Support Article, we should find a way to do this automatically.

Platform Scripts
#

You might be wondering why we’re going for a “dumb” PowerShell script instead of the fancy remediation approach that I am fond of? Well the simple answer is that Platform scripts, running under the required SYSTEM context, will run during Windows Autopilot, so we can ensure that devices with the DMA issue are resolved during the deployment process instead of after it, allowing for BitLocker encryption to complete in flight. You know for security and that.

So there.

Registry Settings
#

We need a way to easily add the required registry entries to allow for the exceptions, taking into consideration that a single model, or manufacture, of device could have multiple exceptions. For this, we can just build a new pscustomobject as part of an array variable $dmaDevices, and as the actual name of the registry value doesn’t matter, our main focus is the value.

$dmaDevices = @()
$dmaDevices += [pscustomobject]@{name = 'Intel(R) LPC Controller - 519D'; value = 'PCI\VEN_8086&DEV_519D'}
$dmaDevices += [pscustomobject]@{name = 'Intel(R) PCI Express Root Port #10 - 51B1'; value = 'PCI\VEN_8086&DEV_51B1'}

With the $dmaDevices array variable, we can then loop through each item in the array, and add the required data to the registry key HKLM:\SYSTEM\CurrentControlSet\Control\DmaSecurity\AllowedBuses with a New-ItemProperty command:

$regPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\DmaSecurity\AllowedBuses'
foreach ($dmaDevice in $dmaDevices) {
    New-ItemProperty -Path $regPath -Name $dmaDevice.name -Value $dmaDevice.value -PropertyType String -Force
}

Great, we have to a way to add in these exceptions, but as they are exceptions, we should be more sniper and less shotgun.

Device Model Queries
#

Instead of this blanket set of new registry items assigned to all devices, which from a security stance isn’t the best look, we should make sure that make and model specific settings are applying.

We can achieve this granularity of model specific settings by using a quick (Get-WmiObject -Class:Win32_ComputerSystem).Model to pull back the model of the device, before we start fiddling with it’s registry.

$dmaDevices = @()

$deviceModel = (Get-WmiObject -Class:Win32_ComputerSystem).Model

if ($deviceModel -in 'Latitude 1', 'Latitude 2') {
    $dmaDevices += [pscustomobject]@{name = 'Intel(R) LPC Controller - 519D'; value = 'PCI\VEN_8086&DEV_519D'}
    $dmaDevices += [pscustomobject]@{name = 'Intel(R) PCI Express Root Port #10 - 51B1'; value = 'PCI\VEN_8086&DEV_51B1'}
}
elseif ($deviceModel -in 'Lenovo 1', 'Lenovo 2') {
    $dmaDevices += [pscustomobject]@{name = 'Intel(R) PCI Express Root Port #20 - A343'; value = 'PCI\VEN_8086&DEV_A343'}
    $dmaDevices += [pscustomobject]@{name = 'Intel(R) PCI Express Root Port #9 - A330'; value = 'PCI\VEN_8086&DEV_A330'}
    $dmaDevices += [pscustomobject]@{name = 'Intel(R) Xeon(R) E3 - 1200/1500 v5/6th Gen Intel(R) Core(TM) PCIe Controller (x16) - 1901'; value = 'PCI\VEN_8086&DEV_1901'}
    $dmaDevices += [pscustomobject]@{name = 'Intel(R) PCI Express Root Port #15 - A336'; value = 'PCI\VEN_8086&DEV_A336'}
}

The if and subsequent elseif statements allow us to ensure that only the DMA exceptions per model, or groups of models, are going to be applied, with the statement allowing for a lookup of multiple models using the -in operator.

So if you have multiple models with the same PCI\VEN_8086&DEV_A30D exception for example, these can be grouped together. Nice eh?

PowerShell Example
#

Combining both the device model logic, and the creation of new registry items in the correct location, we have the below, which can act as a template or example for the rest of your devices with these issues.

$regPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\DmaSecurity\AllowedBuses'
$dmaDevices = @()

$devicesLenovo = @('20UACTO1WW', '20KG0005AU')
$devicesDell = @('Latitude 7320','Latitude 5320')
$devicesHP = @('HP EliteBook 8540p')

Try {

    $deviceModel = (Get-WmiObject -Class:Win32_ComputerSystem).Model

    if ($deviceModel -in $devicesDell) {
        $dmaDevices += [pscustomobject]@{name = 'Intel(R) LPC Controller - 519D'; value = 'PCI\VEN_8086&DEV_519D'}
        $dmaDevices += [pscustomobject]@{name = 'Intel(R) PCI Express Root Port #10 - 51B1'; value = 'PCI\VEN_8086&DEV_51B1'}
    }
    elseif ($deviceModel -in $devicesLenovo) {
        $dmaDevices += [pscustomobject]@{name = 'Intel(R) PCI Express Root Port #20 - A343'; value = 'PCI\VEN_8086&DEV_A343'}
        $dmaDevices += [pscustomobject]@{name = 'Intel(R) PCI Express Root Port #9 - A330'; value = 'PCI\VEN_8086&DEV_A330'}
        $dmaDevices += [pscustomobject]@{name = 'Intel(R) Xeon(R) E3 - 1200/1500 v5/6th Gen Intel(R) Core(TM) PCIe Controller (x16) - 1901'; value = 'PCI\VEN_8086&DEV_1901'}
        $dmaDevices += [pscustomobject]@{name = 'Intel(R) PCI Express Root Port #15 - A336'; value = 'PCI\VEN_8086&DEV_A336'}
    }
    elseif ($deviceModel -in $devicesHP ){
        $dmaDevices += [pscustomobject]@{name = 'PCI Express Upstream Switch Port - 15EF'; value = 'PCI\VEN_8086&DEV_15EF'}
        $dmaDevices += [pscustomobject]@{name = 'Intel(R) PCI Express Root Port #17 - A340'; value = 'PCI\VEN_8086&DEV_A340'}
    }

    foreach ($dmaDevice in $dmaDevices) {
        New-ItemProperty -Path $regPath -Name $dmaDevice.name -Value $dmaDevice.value -PropertyType String -Force
    }

}
Catch {
    Write-Error $_.ErrorDetails
}

This can be modified based on your own device estate, grouping devices by manufacturer or model, or just by which exceptions need to be made.

You can update or modify the variables used for each of the manufacturers $devicesLenovo, $devicesDell, and $devicesHP, as the likelihood is that you may need more granularity across the manufacturers.

Script Testing
#

Now as the registry key has restrictive permissions, you can modify these manually for testing as per the article, or you can use PsExec to run PowerShell as SYSTEM using PsExec.exe -s -i powershell.exe.

Allowing you to test locally on devices before deploying using Microsoft Intune, and with a bit of luck, you should see something like the below:

Registry DMA Exceptions
Screenshot of the Registry showing DMA Exception values

After successful testing, you’re now ready to deploy this as a Platform Script in Microsoft Intune, using the below configuration.

Item Detail
Name BitLocker DMA Exceptions
Description https://memv.ennbee.uk/posts/bitlocker-dma-exceptions/
PowerShell script Set-BitLockerDMAExceptions.ps1
Run this script using the logged on credentials No
Enforce script signature check No
Run script in 64 bit PowerShell Host Yes
Included groups Dynamic Autopilot Group

Now your devices should happily encrypt with BitLocker automatically, without hitting one of these DMA exceptions.

Summary
#

Once you’ve captured the DMA exceptions of devices failing to silently and automatically encrypt with BitLocker, along with the model of device that is effected, you can update the PowerShell script, taking care with the model names, this can then be deployed using Microsoft Intune to a dynamic group of Autopilot devices.

As we’ve gone to the effort of being specific with our exceptions, in the event that a device model is not in the list, then nothing will happen, but if a model is in the list of effected devices, the registry will get updated, and BitLocker will stop being a little whinge about not being able to start encryption due to some kind of security issue.

Related

Enabling BitLocker and WinRE on failed Windows Devices
· loading
Intune Windows 10 and later BitLocker Security Encryption PowerShell
You may have enabled and configure BitLocker for silent encryption on your Windows 10 Autopilot joined devices, but have you had the headache of devices that don’t have a Windows Recovery Environment (WinRE) configured? Yep? Me too… What you’ll see in either the BitLocker-API event log, or within the Encryption Readiness reporting in Microsoft Intune the following, glorious error:
Creating Reusable Groups of Firewall Settings for Microsoft Online Services
· loading
Intune Security PowerShell Graph API Settings Catalog Windows 10 and later
If you’ve been living under a rock, or you don’t have to deal with firewall and proxy requirements for accessing Microsoft Online services, you probably won’t be aware that Microsoft publish their URLs and IP addresses for their services using a web service.
Keeping Windows Store Apps Updated with Microsoft Intune
· loading
Intune Windows 10 and later Updates Remediation Apps PowerShell Windows Autopilot Security
So we’re all onboard with the New Microsoft Store, and deploying both UWP and Win32 apps from Microsoft Intune is an absolute breeze, and reduces the effort of deploying applications to a click click next OK exercise. What about the UWP apps that are already installed on a Windows Autopilot device, shouldn’t we give them a bit of love?