← All scripts

BitLocker & device encryption

Ensure BitLocker Protected (TPM + Entra backup)

Ensures the OS drive has a TPM protector and a recovery-password protector, resumes protection if off, and backs the recovery key up to Entra ID. Never prints the recovery key.

Download .ps198 lines · PowerShell

Replace generic placeholder values (tenant, domain, secrets) for your own environment before running. Read it first and test safely.

<# 
RMM - Ensure BitLocker is protected on C: using TPM (no startup PIN) + Recovery Password fallback.
- Adds TPM protector if missing
- Adds RecoveryPassword protector if missing (does NOT print the 48-digit key)
- Resumes protection if currently Off
- Attempts to back up recovery key to Entra ID (if supported)
Run as SYSTEM, 64-bit PowerShell.
#>

$ErrorActionPreference = "Stop"
$drive = "C:"

function Write-Log([string]$msg) {
    Write-Output $msg
}

try {
    # Pre-flight: must have BitLocker module/cmdlets
    if (-not (Get-Command Get-BitLockerVolume -ErrorAction SilentlyContinue)) {
        throw "BitLocker cmdlets not available on this OS."
    }

    # TPM checks (no TPM = no TPM-only unlock)
    $tpm = Get-Tpm
    if (-not $tpm.TpmPresent) { throw "TPM not present. Cannot enforce TPM protector." }
    if (-not $tpm.TpmReady)   { throw "TPM not ready. Enable/initialize TPM in UEFI/BIOS." }

    $vol = Get-BitLockerVolume -MountPoint $drive

    # Ensure TPM protector exists
    $hasTpm = $false
    if ($vol.KeyProtector) {
        $hasTpm = ($vol.KeyProtector | Where-Object { $_.KeyProtectorType -eq "Tpm" } | Measure-Object).Count -gt 0
    }
    if (-not $hasTpm) {
        Add-BitLockerKeyProtector -MountPoint $drive -TpmProtector | Out-Null
        Write-Log "Added TPM protector."
    } else {
        Write-Log "TPM protector already present."
    }

    # Refresh volume (protectors may have changed)
    $vol = Get-BitLockerVolume -MountPoint $drive

    # Ensure Recovery Password protector exists (backup-only, no startup prompt)
    $hasRecovery = $false
    if ($vol.KeyProtector) {
        $hasRecovery = ($vol.KeyProtector | Where-Object { $_.KeyProtectorType -eq "RecoveryPassword" } | Measure-Object).Count -gt 0
    }
    if (-not $hasRecovery) {
        $kpObj = Add-BitLockerKeyProtector -MountPoint $drive -RecoveryPasswordProtector
        # Do NOT output the recovery password; only log the protector ID
        $kpId = $kpObj.KeyProtectorId
        Write-Log "Added RecoveryPassword protector. KeyProtectorId=$kpId"
    } else {
        $kpId = ($vol.KeyProtector | Where-Object { $_.KeyProtectorType -eq "RecoveryPassword" } | Select-Object -First 1 -ExpandProperty KeyProtectorId)
        if ($kpId) { Write-Log "RecoveryPassword protector already present. KeyProtectorId=$kpId" }
        else { Write-Log "RecoveryPassword protector already present." }
    }

    # Ensure protection is ON (your case was FullyEncrypted but Protection Off)
    $vol = Get-BitLockerVolume -MountPoint $drive
    if ($vol.ProtectionStatus -ne "On") {
        Resume-BitLocker -MountPoint $drive | Out-Null
        Write-Log "Resumed BitLocker protection."
    } else {
        Write-Log "BitLocker protection already ON."
    }

    # Attempt Entra ID backup (safe to fail if not Entra-joined / cmdlet missing)
    $vol = Get-BitLockerVolume -MountPoint $drive
    $recoveryKp = $vol.KeyProtector | Where-Object { $_.KeyProtectorType -eq "RecoveryPassword" } | Select-Object -First 1
    if ($null -ne $recoveryKp) {
        if (Get-Command BackupToAAD-BitLockerKeyProtector -ErrorAction SilentlyContinue) {
            try {
                BackupToAAD-BitLockerKeyProtector -MountPoint $drive -KeyProtectorId $recoveryKp.KeyProtectorId | Out-Null
                Write-Log "Backed up recovery key to Entra (AAD) successfully."
            } catch {
                Write-Log "Entra (AAD) backup attempted but failed: $($_.Exception.Message)"
            }
        } else {
            Write-Log "Entra (AAD) backup cmdlet not available on this system."
        }
    } else {
        Write-Log "No RecoveryPassword protector found - cannot back up to Entra."
    }

    # Final status summary (no secrets)
    $vol = Get-BitLockerVolume -MountPoint $drive
    Write-Log ("Final: MountPoint={0} Protection={1} VolumeStatus={2} EncryptedPct={3}" -f `
        $vol.MountPoint, $vol.ProtectionStatus, $vol.VolumeStatus, $vol.EncryptionPercentage)

    exit 0
}
catch {
    Write-Error "FAILED: $($_.Exception.Message)"
    exit 1
}