Worklet: Install BitLocker and store keys in device tag

For Anyone still interested in this script I have made a lot of revisions to make the output logs much more clean with no API Junk. Added in checking for enabling Auto-Unlock on secondary drives as this was a common complaint from my users.

In addition, I have done some troubleshooting so I can hopefully provide some input on why some people arent seeing anything in logs.

New Remediation Code:

$apiKey = "*YOUR ORGS API KEY*"
$apiUrl = "https://console.automox.com/api/servers/"
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Bearer $apiKey")

$response = Invoke-RestMethod $apiUrl -Method 'GET' -Headers $headers -Body $body
$response = ConvertTo-Json

$servers = $response | Sort-Object name

$currentMachineName = $env:COMPUTERNAME;

foreach($server in $servers){
	$name = $server.name;	
	if($currentMachineName -eq $name){
		$id = $server.id
		$organization_id = $server.organization_id
		$server_group_id = $server.server_group_id
		#region your bitlocker code start
		$keyPath = 'C:\temp'		
		$toEncrypt = Get-BitLockerVolume | Where-Object { $_.VolumeStatus -match 'Decrypted' }	
		
		# Loop through each Unencrypted Drives
		# Enable Bitlocker and Export their Recovery Keys
		foreach ( $drive in $toEncrypt ) 
		{
		    $driveLetter = $drive.MountPoint.Replace(':','')
		    try {
		        #Enable Bitlocker
		        Enable-BitLocker -MountPoint $driveLetter -EncryptionMethod Aes256 -RecoveryPasswordProtector -SkipHardwareTest | Out-Null
            Start-Sleep -s 15
		        
				#Export Key and Key ID to a File
				$recID = (Get-BitLockerVolume -MountPoint $driveLetter).KeyProtector.KeyProtectorID
				$recKey = (Get-BitLockerVolume -MountPoint $driveLetter).KeyProtector.RecoveryPassword
				$keyAndID = "Recovery Key: $recKey | and Recovery ID: $recID"
				
				#Start of API Modify
				## Now calling modify device API and set recID,recKey in tags
				$headers.Add("Content-Type", "application/json")
				$apiUrl = "https://console.automox.com/api/servers/$($id)?o=$($organization_id)"
				$body = "{
				    `"server_group_id`": $server_group_id,
				    `"tags`": [
				        `"RecoveryID: $recID`",
						`"RecoveryKey: $recKey`"
				    ]
				}"
				 
				$response = Invoke-RestMethod $apiUrl -Method 'PUT' -Headers $headers -Body $body
				$response | ConvertTo-Json
				#End of API Modify
				$KeyProperties = @()
				$KeyObj = @()
				$Computer = $env:Computername
				$Keys = Get-BitlockerVolume -MountPoint C:
				$selected = $Keys | Select-Object -ExpandProperty KeyProtector
				$Selected[1] | select-Object KeyprotectorID, RecoveryPassword
				Foreach ($S in $Selected) {
					$KeyProperties = [pscustomobject]@{
							Computer = $Computer
							KeyProtectorID = $S.KeyProtectorID
							RecoveryPassword = $S.RecoveryPassword
					}
					$KeyObj += $KeyProperties
					}
				$KeyObj[1] | Export-CSV "C:\$($Computer)_Keys.csv" -NoTypeInformation
				Write-host $Keys
		    } catch {
		        Write-Output "Unable to Encrypt $($drive.MountPoint)"
		    }
		}

    Start-Sleep -s 60

    foreach ($drive in $toEncrypt)
		{
    $driveLetter = $drive.MountPoint.Replace(':','')
    Enable-BitLockerAutoUnlock -MountPoint $driveLetter | Out-Null
    }
		#End of Bitlocker Code
	
	}
}

Some issues I’ve discovered while troubleshooting BitLocker in my org:

  • Users must have a compatible version of windows to work with Bitlocker. (Windows Pro, etc)
  • GPO Settings related to enforcing storing BitLocker keys in AD DS will prevent the install from working.
  • Check TPM Compatibility. As TPM 2.0 does not work with a GPT(UEFI) partition, BitLocker won’t be able to initialize if the tpm is not compatible. I believe most dTPMs down aday can downgrade to 1.2 if needed.
  • Make sure the keys are able to save during the process. I have noticed behavior where if the key cannot save locally, to a file server, or anywhere the BitLocker install will get stuck at “Awaiting Activation”.
1 Like

@vukko Saw you reply in the other thread. Might be helpful to you.

1 Like

Thank you, much appreciated!

Per your evaluation code, it looks as though if the drive is already encrypted it will exit and just write output to the activity log. Most of the drives in my organization are already encrypted; how do i get it to write the Key to the tag if this is the case?

I wasn’t able to test this on my own org as I don’t wanna mess with any tags I have set up. But in theory it would look something like this. Essentially removing the encryption part and targeting drives that are encrypted, using the “Get-BitLockerVolume” Powershell function will grab any keys from the machine.

$apiKey = "*YOUR ORGS API KEY*"
$apiUrl = "https://console.automox.com/api/servers/"
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Bearer $apiKey")

$response = Invoke-RestMethod $apiUrl -Method 'GET' -Headers $headers -Body $body
$response = ConvertTo-Json

$servers = $response | Sort-Object name

$currentMachineName = $env:COMPUTERNAME;

foreach($server in $servers){
	$name = $server.name;	
	if($currentMachineName -eq $name){
		$id = $server.id
		$organization_id = $server.organization_id
		$server_group_id = $server.server_group_id
		#region your bitlocker code start
		$keyPath = 'C:\temp'		
		$EncryptedDrives = Get-BitLockerVolume | Where-Object { $_.VolumeStatus -match 'Encrypted' }	
		
		# Loop through each Unencrypted Drives
		# Enable Bitlocker and Export their Recovery Keys
		foreach ( $drive in $EncryptedDrives ) 
		{
		    $driveLetter = $drive.MountPoint.Replace(':','')
		    try {

				#Export Key and Key ID to a File
				$recID = (Get-BitLockerVolume -MountPoint $driveLetter).KeyProtector.KeyProtectorID
				$recKey = (Get-BitLockerVolume -MountPoint $driveLetter).KeyProtector.RecoveryPassword
				$keyAndID = "Recovery Key: $recKey | and Recovery ID: $recID"
				
				#Start of API Modify
				## Now calling modify device API and set recID,recKey in tags
				$headers.Add("Content-Type", "application/json")
				$apiUrl = "https://console.automox.com/api/servers/$($id)?o=$($organization_id)"
				$body = "{
				    `"server_group_id`": $server_group_id,
				    `"tags`": [
				        `"RecoveryID: $recID`",
						`"RecoveryKey: $recKey`"
				    ]
				}"
				 
				$response = Invoke-RestMethod $apiUrl -Method 'PUT' -Headers $headers -Body $body
				$response | ConvertTo-Json
				#End of API Modify
				$KeyProperties = @()
				$KeyObj = @()
				$Computer = $env:Computername
				$Keys = Get-BitlockerVolume -MountPoint $driveLetter
				$selected = $Keys | Select-Object -ExpandProperty KeyProtector
				$Selected[1] | select-Object KeyprotectorID, RecoveryPassword
				Write-host $Keys
		    } catch {
		        Write-Output "Unable to get keys for $($drive.MountPoint)."
		    }
		}
	
	}
}

Do I just put that code in both the Evaluation & Remediation?

That would be the Remediation code. For Evaluation you could do can do something has simple as:
exit 1
or if you want to verify the machine is encrypted you could try something like this for the Evaluation:

$BLinfo = Get-Bitlockervolume

if($blinfo.ProtectionStatus -eq 'On' -and $blinfo.EncryptionPercentage -eq '100'){
    Write-Output "'$env:computername - '$($blinfo.MountPoint)' is encrypted."
    exit 1
} else {
	Write-Output "'$env:computername - '$($blinfo.MountPoint)' is not encrypted."
    exit 0
}

You should also test this on a test group before running it on any production machines.

Sorry…just getting back to testing this as I have been testing other scripts. I put this remediation code in and just put {exit 1} for the evaluation, input our API and tested on a device that has bit locker configured. The activity log shows the device name but the details section is BLANK and there are no tags added in the device info. Is there something i am missing?