Over on the r/PowerShell subreddit, user u/3rddegreeofIT asked for assistance with using PowerShell to enable Bitlocker on systems with no TPM. They defined their criteria as:
- Modifies registry to allow Advanced Startup
- Modifies registry to allow BitLocker Drive Encryption without TPM
- Set encryption to AES 256
- Require a password on boot
- Encrypt Used Space Only
- Skip Hardware Test, No Reboot Required.
While I would prefer to manage via MEMCM (see my series on this) or GPO, I know this is not always possible. I considered including my PowerShell function to inject into LGPO, but that has a dependency on LGPO.exe and I assume u/3rddegreeofIT would like to keep this as simple as possible.
I made the assumption that the devices would be domain joined and based on that I create a recovery key and backup to AD. If not domain joined, I would highly recommend some other method to backup recovery keys.
As always, my code is written with an attempt at readability for those not as familiar with PowerShell. I am fully aware there are ways to write this all with less code at the cost of readability.
# Microsoft provides programming examples for illustration only,
# without warranty either expressed or implied, including, but not
# limited to, the implied warranties of merchantability and/or
# fitness for a particular purpose.
#
# This sample assumes that you are familiar with the programming
# language being demonstrated and the tools used to create and debug
# procedures. Microsoft support professionals can help explain the
# functionality of a particular procedure, but they will not modify
# these examples to provide added functionality or construct
# procedures to meet your specific needs. If you have limited
# programming experience, you may want to contact a Microsoft
# Certified Partner or the Microsoft fee-based consulting line at
# (800) 936-5200.
#
# For more information about Microsoft Certified Partners, please
# visit the following Microsoft Web site:
# https://partner.microsoft.com/global/30000104
Param(
[parameter(Mandatory=$True,Position=0)][string]$password
)
#Verify FVE path exists and create if needed
if(!(test-path HKLM:\SOFTWARE\Policies\Microsoft\FVE)){
New-Item -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE
}
#get value of UseAdvancedStartup (wrapped in try/catch to hide error if doesn't exist)
try{
$UseAdvancedStartup = Get-ItemPropertyValue -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE -Name UseAdvancedStartup -ErrorAction SilentlyContinue
}
catch{}
#verify UseAdvancedStartup is set to 1 and create/change value if needed
if($UseAdvancedStartup -ne 1){
New-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE -Name UseAdvancedStartup -Value 1 -Force | Out-Null
}
#get value of EnableBDEWithNoTPM (wrapped in try/catch to hide error if doesn't exist)
try{
$EnableBDEWithNoTPM = Get-ItemPropertyValue -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE -Name EnableBDEWithNoTPM -ErrorAction SilentlyContinue
}
catch{}
#verify EnableBDEWithNoTPM is set to 1 and create/change value if needed
if($EnableBDEWithNoTPM -ne 1){
New-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\FVE -Name EnableBDEWithNoTPM -Value 1 | Out-Null
}
#Get OS Drive Bitlocker Info
$BLV = Get-BitLockerVolume -MountPoint $ENV:SystemDrive
#Verify OS drive is Fully Encrypted
If($BLV.VolumeStatus -ne "FullyEncrypted"){
#create securestring from plaintext password (hardcoded example left in place, do not enable if using parameter)
#$password = "C0mpl3x!"
$pwss = ConvertTo-SecureString -String $password -AsPlainText -Force
#enable BDE using xtsaes256, password protector, used space only, and skipping HW test
Enable-BitLocker -MountPoint $ENV:SystemDrive -EncryptionMethod XtsAes256 -UsedSpaceOnly -PasswordProtector $pwss -SkipHardwareTest | out-null
#update bitlocker info in variable
$BLV = Get-BitLockerVolume -MountPoint $ENV:SystemDrive
#get recovery password kepyprotector
$RP = $BLV.KeyProtector | where-object{$_.KeyProtectorType -eq "RecoveryPassword"}
#backup recovery key to Active Directory
Backup-BitLockerKeyProtector -MountPoint $ENV:SystemDrive -KeyProtectorId $RP.KeyProtectorId
}
#testing support
#remove password keyprotector
#$PWKP = $BLV.KeyProtector | where-object{$_.KeyProtectorType -eq "Password"}
#Remove-BitLockerKeyProtector -MountPoint $ENV:SystemDrive -KeyProtectorId $PWKP.KeyProtectorId