Get BitLocker Keys and store them against the asset

We find this very useful so we dont have to refer to AD for recovery keys each time a customer gets locked out.

#TODO - MAKE SURE YOU SETUP YOUR ASSET CUSTOM FIELD CALLED "Bitlocker_Key_<drive>" for each drive as a "Text Field" on your
# Syncro Device asset type. Assets -> Manage Types -> Syncro Device -> New Field
# Based on the Syncro Staff product keys script.

#TO Script - check if just encrypted by TPM and has no Recovery password and set so on Syncro

Import-Module $env:SyncroModule

#Creates temp directory if it does not exist
if (!(Test-Path -Path C:\Temp)) {
    Set-Location C:\
    md temp
}

#Set the location to C:\
Set-Location C:\Temp

if (Test-Path -Path C:) {
	#Is BL Enabled?
	$BLinfoC = Get-Bitlockervolume -MountPoint "C:"
	if($blinfoC.ProtectionStatus -EQ 'On'){

        Set-Asset-Field -Subdomain "alamo" -Name "Bitlocker_Enabled_C" -Value "BitLocker is enabled"

		#Puts keys into text files	
		(Get-BitLockerVolume -MountPoint C:).KeyProtector.recoverypassword > C:\Temp\bitlockerkeyc.txt
		
		#Gets keys from text files
		[string] $textC = Get-Content C:\Temp\bitlockerkeyc.txt -raw
		
		#Adds keys to Syncro
		Set-Asset-Field -Subdomain "alamo" -Name "Bitlocker_Key_C" -Value $textC
		
		#Removes text files with keys from PC for security
		Set-Location C:\Temp
		Del bitlockerkeyc.txt
	} else {
	Set-Asset-Field -Subdomain "alamo" -Name "Bitlocker_Enabled_C" -Value "BitLocker is NOT enabled"
	}
	
} else {}

if (Test-Path -Path D:) {
	#Is BL Enabled?
	$BLinfoD = Get-Bitlockervolume -MountPoint "D:"
	if($blinfoD.ProtectionStatus -EQ 'On'){
		#Puts keys into text files	
		(Get-BitLockerVolume -MountPoint D:).KeyProtector.recoverypassword > C:\Temp\bitlockerkeyD.txt
		
		#Gets keys from text files
		[string] $textD = Get-Content C:\Temp\bitlockerkeyD.txt -raw
		
		#Adds keys to Syncro
		Set-Asset-Field -Subdomain "alamo" -Name "Bitlocker_Key_D" -Value $textD
		
		#Removes text files with keys from PC for security
		Set-Location C:\Temp
		Del bitlockerkeyD.txt
	} else {}
	
} else {}

if (Test-Path -Path E:) {
	#Is BL Enabled?
	$BLinfoE = Get-Bitlockervolume -MountPoint "E:"
	if($blinfoE.ProtectionStatus -EQ 'On'){
		#Puts keys into text files	
		(Get-BitLockerVolume -MountPoint E:).KeyProtector.recoverypassword > C:\Temp\bitlockerkeyE.txt
		
		#Gets keys from text files
		[string] $textE = Get-Content C:\Temp\bitlockerkeyE.txt -raw
        #write-host "E:\ BitLocker Key $textE"
		
		#Adds keys to Syncro
		Set-Asset-Field -Name "Bitlocker_Key_E" -Value $textE
		
		#Removes text files with keys from PC for security
		Set-Location C:\Temp
		Del bitlockerkeyE.txt
	} else {}
	
} else {}

Rhodes,
The script is completing but the value is not being returned [BLK or “BitLocker is NOT enabled”]

Here’s another version that I put together:

<############################

How to use:

This script gather the BitLocker volumes, gather the keys, and write the keys for each drive to an asset custom field.

Asset fields should be created with this format: BitLocker_key_[drive letter]
For example, BitLocker_key_C (case sensitive) would be for drive C. Each drive will need an asset field.
The script output will also state what field the key was saved to.

############################>

Import-Module $env:SyncroModule

$drives = (Get-BitLockerVolume).MountPoint.Replace(":","")
Write-Host "These BitLocker volumes were found: $drives `nGetting keys..."
Foreach ($i in $drives)
{
    $key = (Get-BitLockerVolume -MountPoint $i).keyprotector.recoverypassword
        If ($key) {
        Write-Host "BitLocker Key for Drive $i`: $key `nWritten to 'BitLocker_Key_$i' asset custom field"
        Set-Asset-Field -Name "BitLocker_Key_$i" -Value $key

    } else {
        Write-Host "No BitLocker keys found for Drive $i"
        Set-Asset-Field -Name "BitLocker_Key_$i" -Value "No BitLocker keys found for Drive $i"
    }
}

I’ve tried both of these scripts. They output the recovery key perfectly, but I can’t seem to get it to add to a custom asset field.

I can’t seem to find anywhere to create a custom asset field for anything.

Here’s the code that finishes building the string I use and writes it to a “text area” field:

$writeBack = $writeBack + "Snapshot: " + (Get-Date -Format "yyyy-MM-dd HH:mm`n") + $builtKeys
Set-Asset-Field -Name "BitLocker Keys" -Value $writeBack

What does your code look like for the Set-Asset-Field chunk? (You said “add.” Are you trying to append to the existing value perchance?)

Here’s my overly-elaborate script:

1 Like

Here’s my attempt at a script. Not writing any output to terminal, no files are stored to prevent leakage storing the volume id’s and keys for all volumes found attached when the script runs. The information is put into a comment in the ticket, and prepended to the previous run. The system drive key is recorded and saved as an independent field. All my scripts create tickets and comments, etc. Since the volume IDs are stored in the comments, you can search for it.

Need to have some custom asset fields:

  • $BillRMMTicket - Customer custom field checkbox - will either set ticket to billable or not when it creates the time entry.
  • $BitLocker_HomeDrive_Key - Pull from asset to compare
  • $BitLocker_Info - Pull history so that we can prepend the run
  • $BitLocker_HomeDrive_Active - Is BitLocker active on the endpoint systemdrive
<#
Powershell Script to retrieve BitLocker Keys and settings
Expecting to receive the following parameters
- $BillRMMTicket - Customer custom field checkbox
- $BitLocker_HomeDrive_Key - Pull from asset to compare
- $BitLocker_Info - Pull history so that we can prepend the run
- $BitLocker_HomeDrive_Active - Is BitLocker active on the endpoint systemdrive
#>

$tls = "Tls";
[System.Net.ServicePointManager]::SecurityProtocol = $tls;

Import-Module $env:SyncroModule

$localfolder = "$Env:AllUsersProfile\RMM"
$TicketSubject = 'BitLocker Status and Key Retrieval'
$TicketType = 'Software'
$TicketTime = '15'
$NewTicket = Create-Syncro-Ticket -Subject $TicketSubject -IssueType $TicketType -Status "New"
$TicketID = $NewTicket.ticket.id
$TicketUser = "syncrouseremail"
$startAt = (Get-Date).AddMinutes(-$TicketTime).toString("o")

$OperationSummary = Get-Date -Format u
$BLStatusChanged = $False

#Ensure that our working folder is present
If ((Test-Path -Path $localfolder) -eq $False) {
	New-Item -Path $localfolder -ItemType "directory"
}
#Convert Parameters from Syncro to Boolean
If ($BitLocker_HomeDrive_Active -eq "yes") {
    $BitLocker_HomeDrive_Active = $true
} ElseIf ($BitLocker_HomeDrive_Active -eq "no"){
	$BitLocker_HomeDrive_Active = $False
}

If ($BillRMMTicket -eq "yes") {
    $BillRMMTicket = $true
} ElseIf ($BillRMMTicket -eq "no"){
	$BillRMMTicket = $false
}

$BitlockerVolumes = Get-BitLockerVolume

$BitlockerVolumes |
    ForEach-Object {
        $MountPoint = $_.MountPoint 
        $Protected = $_.ProtectionStatus
        $RecoveryKey = [string]($_.KeyProtector).RecoveryPassword
        $BitLocker = Get-WmiObject -Namespace "Root\cimv2\Security\MicrosoftVolumeEncryption" -Class "Win32_EncryptableVolume" -Filter "DriveLetter = '$MountPoint'"
        $DeviceID = $BitLocker.DeviceID
        if ($Protected) {
            #Write-Output "Encrypted : $MountPoint | VolumeID : $DeviceID | Key : $RecoveryKey"
            $OperationSummary = $OperationSummary + "`n" + "Encrypted : $MountPoint | VolumeID : $DeviceID | Key : $RecoveryKey"
        } else {
            #Write-Output "Not Encrypted : $MountPoint | VolumeID : $DeviceID"
            $OperationSummary = $OperationSummary + "`n" + "Not Encrypted : $MountPoint | VolumeID : $DeviceID | Key : None"
        }      

        if ($Env:SystemDrive.ToLower().contains($MountPoint.ToLower())) {
            if (-not $Protected ) {
                #We need to see if it was previously active
                if ($BitLocker_HomeDrive_Active) {
                    #Status has changed
                    $BLStatusChanged = $true
                }
                #Now we need to uncheck the Active flag
                Set-Asset-Field -Name "BitLocker_HomeDrive_Active" -Value $false
            } else {
                #Make sure the active box is checked
                Set-Asset-Field -Name "BitLocker_HomeDrive_Active" -Value $true
            }
            #We found the System Drive, let's compare to what was sent, and compare. 
            if ($RecoveryKey -eq $BitLocker_HomeDrive_Key) {
                #Recovery Key is the same, no need to update
                $OperationSummary = $OperationSummary + "`n" + "No change in System Drive Key"
            } elseif ($BitLocker_HomeDrive_Key -eq $null) {
                #Recovery key is not present, so we're going to store
                Set-Asset-Field -Name "BitLocker_HomeDrive_Key" -Value $RecoveryKey
                $OperationSummary = $OperationSummary + "`n" + "Storing System Drive Key in Asset"
            } else {
                #Recovery key is different, so we need to update
                Set-Asset-Field -Name "BitLocker_HomeDrive_Key" -Value $RecoveryKey
                $OperationSummary = $OperationSummary + "`n" + "Updating System Drive Key in Asset"
            }
        }
    }
#Now that we're done, let's write the information to the ticket notes.
Create-Syncro-Ticket-Comment -TicketIdOrNumber $TicketID -Subject "Update" -Body "$OperationSummary" -Hidden "true" -DoNotEmail "true"
Create-Syncro-Ticket-TimerEntry -TicketIdOrNumber $TicketID -StartTime $startAt -DurationMinutes $TicketTime -Notes "Finished scanning system for Bitlocker volumes." -UserIdOrEmail $TicketUser -ChargeTime $BillRMMTicket
$AssetNote = $OperationSummary + "`n" + $BitLocker_Info
Set-Asset-Field -Name "BitLocker_Info" -Value $AssetNote

if ($BLStatusChanged) {
    Create-Syncro-Ticket-Comment -TicketIdOrNumber $TicketID -Subject "Update" -Body "Encryption status of System Drive has been disabled" -Hidden "true" -DoNotEmail "true"
    Update-Syncro-Ticket -TicketIdOrNumber $TicketID -Status "RMM Issue"
    exit 1
}
Update-Syncro-Ticket -TicketIdOrNumber $TicketID -Status "Resolved"```
1 Like

Two comments:

  1. If you’re worried about “leakage”, check the alert emails you get about the asset – they include the text of all the custom fields, including the BitLocker keys.

  2. Currently, ticket comments aren’t searchable.