Archive

Posts Tagged ‘SCCM 1806 bitlocker powershell’

Config Manager 1806 – OSD with full disk encryption not working correctly

26th November, 2018 Leave a comment

When using a ConfigMgr Task Sequence to deploy an Operating System, there are a couple of steps that relate to BitLocker. These steps are “Pre-provision BitLocker” and “Enable BitLocker” and they both have an option to “Use full disk encryption”. Although the faster, default option of only encrypting used space would be adequate for most, some organisations prefer IT to deliver a device with a fully encrypted disk to the end user.

So the answer seems quite straight forward, simply tick the “Use full disk encryption” on both task sequence tasks. This seems quite logical – the “Pre-provision BitLocker” step encrypts the entire drive, and implements a “clear” protector (so that no key/PIN/USB device is required to read the drive). This means that any data written to the drive after this step is encrypted. Once the Task Sequence has written the WIM, drivers and any other applications and packages, the “Enable BitLocker” step removes the “clear” protector and implements your chosen protector type (i.e. TPM or PIN).

However, when I was testing full disk encryption, I got errors similar to the below (the steps worked correctly when “Use full disk encryptions” was not ticked):

==============================[ OSDBitLocker.exe ]==============================
Command line: "OSDBitLocker.exe" /enable /wait:True /mode:TPM /pwd:AD /full:True
Initialized COM
Command line for extension .exe is "%1" %*
Set command line: "OSDBitLocker.exe" /enable /wait:True /mode:TPM /pwd:AD /full:True
Target volume not specified, using current OS volume
Current OS volume is 'C:'
Succeeded loading resource DLL 'C:\Windows\CCM\1033\TSRES.DLL'
Protection is OFF
FALSE, HRESULT=80004005 (..\bitlocker.cpp,1541)
Encryption in progress
pBitLocker->Enable( argInfo.keyMode, argInfo.passwordMode, argInfo.sStartupKeyVolume, argInfo.bWait, argInfo.bFull), HRESULT=80004005 (..\main.cpp,401)

The error doesn’t seem very helpful and even googling doesn’t give a definitive answer. After a bit of head scratching, it occurred to me that the logs were indicating the error, but the message was a bit vague. The penultimate line (“Encryption in progress”) should really say “Cannot enable BitLocker because encryption is still in progress”.

So, you cannot apply a new protector until the encryption progress has completed. Indeed, the “Enable BitLocker” step even has a tick box that states “Wait for BitLocker to complete the drive encryption process on all drives before Configuration Manager continues to run the task sequence” that you would expect would resolve the above situation. Unfortunately it does not appear to do anything, at least with my testing. So in that case a bit of PowerShell to the rescue!

I created a “Run Command Line” step to check and wait for BitLocker to complete:

powershell "while ( (Get-BitLockerVolume | where { $_.VolumeType -eq 'OperatingSystem' }).EncryptionPercentage -ne 100 ) { sleep 20 }"

This worked perfectly – so it could either be a bug with the “Wait for BitLocker to complete the drive encryption process on all drives before Configuration Manager continues to run the task sequence” or I’ve misinterpreted on how the command is meant to function.

As an aside, when running the basic Powershell command, the Task Sequence appears to hang until the finished encrypting the disk. As the Get-BitLockerVolume command returns the percentage complete we can update the Task Sequent progress indicator with this information. Here’s the PowerShell on how to do that:

$objTSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment;
$uStep = $objTSEnv.Value('_SMSTSNextInstructionPointer');
$uMaxStep = $objTSEnv.Value('_SMSTSInstructionTableSize');
$objProgress = New-Object -ComObject Microsoft.SMS.TSProgressUI;
$intBitLockerPercentage = 0;
while ( (Get-BitLockerVolume | where { $_.VolumeType -eq 'OperatingSystem' }).EncryptionPercentage -ne 100 )
{
$intBitLockerPercentage = (Get-BitLockerVolume | where { $_.VolumeType -eq 'OperatingSystem' }).EncryptionPercentage;
$strMessage = 'BitLocker Encryption Processs: '+$intBitLockerPercentage+'%';
$objProgress.ShowActionProgress($objTSEnv._SMSTSOrgName, $objTSEnv._SMSTSPackageName, $objTSEnv._SMSTSCustomProgressDialogMessage, $objTSEnv._SMSTSCurrentActionName, $uStep, $uMaxStep, $strMessage, $intBitLockerPercentage, 100);
Sleep 30
}

As a one-line in the Task Sequence use:

powershell "$objTSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment; $uStep = $objTSEnv.Value('_SMSTSNextInstructionPointer'); $uMaxStep = $objTSEnv.Value('_SMSTSInstructionTableSize'); $objProgress = New-Object -ComObject Microsoft.SMS.TSProgressUI; $intBitLockerPercentage = 0; while ( (Get-BitLockerVolume | where { $_.VolumeType -eq 'OperatingSystem' }).EncryptionPercentage -ne 100 ) { $intBitLockerPercentage = (Get-BitLockerVolume | where { $_.VolumeType -eq 'OperatingSystem' }).EncryptionPercentage; $strMessage = 'BitLocker Encryption Processs: '+$intBitLockerPercentage+'%'; $objProgress.ShowActionProgress($objTSEnv._SMSTSOrgName, $objTSEnv._SMSTSPackageName, $objTSEnv._SMSTSCustomProgressDialogMessage, $objTSEnv._SMSTSCurrentActionName, $uStep, $uMaxStep, $strMessage, $intBitLockerPercentage, 100); Sleep 30 }"

Hope this is helpful.