For detailed steps on creating and scheduling a Custom Policy, please see this article:

Creating a Custom Policy

For an overview on how Custom Policies work, see this article:

How to Use Custom Policies

The Scripts

The following Evaluation and Remediation scripts can be used to enforce BitLocker encryption.


Evaluation Code

# PowerShell 4.0 and Above
# Windows 8 and later

#Get BitLocker status for All Drives
try { $encryption = Get-BitLockerVolume -ErrorAction Stop }
catch { Write-Output "Unable to determine BitLocker status" }

# Count Drives and initialize lists for later output
$numDrives = $encryption.Count
$encCount = 0
$encrypted = @()
$unencrypted = @()

# Loop through each drive and see if it is Protected or Note
# Add to the appropriate list, Encrypted or Unencrypted
foreach ($drive in $encryption) {
    $encStatus = $drive.ProtectionStatus
    $encInProgress = $drive.VolumeStatus
    if ( ($encStatus -match 'On') -or ($encInProgress -match "EncryptionInProgress") ) {
        $encrypted += $drive.MountPoint
        $encCount++
    } else {
        $unencrypted += $drive.MountPoint
    }
}

# Output drive statuses so the can be seen in the Activity Log
Write-Output "Encrypted Drives: $encrypted`n"
Write-Output "Unencrypted Drives: $unencrypted`n"

# Determine Compliant based on if the number of Encrypted
# Drives matches the number of Total Drives
if ($encCount -eq $numDrives) {
    Write-Output "Compliant"
    exit 0
} else {
    Write-Output "Non-Compliant"
    exit 1
}


This evaluation requests BitLocker status for all physical disk drives on the target device. It then compares the count of encrypted drives to the total number present. If all drives are encrypted then return Compliant (Exit 0). Otherwise return Non-Compliant (Exit 1).

Remediation Code

# PowerShell 4.0 and Above
# Windows 8 and later

# Define where you want your Recovery Key to be exported
# Note that this needs to be a local (non-network) drive.
$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 Aes128 -RecoveryPasswordProtector | Out-Null
       
        #Export Key and Key ID to a File
        $recID = (Get-BitLockerVolume -MountPoint $driveLetter).KeyProtector.KeyProtectorID
        $recKey = (Get-BitLockerVolume -MountPoint $driveLetter).KeyProtector.RecoveryPassword
        Set-Content -Path "$keyPath\BitlockerRecoveryKey_$driveLetter.txt" -Force -Value "Recovery Key ID: $recID"
        Add-Content -Path "$keyPath\BitlockerRecoveryKey_$driveLetter.txt" -Value "Recovery Key: $recKey"
    } catch {
        Write-Output "Unable to Encrypt $($drive.MountPoint)"
    }
}


The Remediation code has one editable variable ($keyPath). Use this to define where the Recovery Key will be stored. The Recovery Key is necessary to decrypt the drive should that become necessary in the future.

This script initially runs a similar check as the Evaluation Code to enumerate each physical drive that is not encrypted. Using this information, it starts encryption on each of these drives and exports the Recovery Key to a text file in the previously specified location.

Did this answer your question?