Skip to main content
COSMICBYTEZLABS
NewsSecurityHOWTOsToolsStudyTraining
ProjectsChecklistsAI RankingsNewsletterStatusTagsAbout
Subscribe

Press Enter to search or Esc to close

News
Security
HOWTOs
Tools
Study
Training
Projects
Checklists
AI Rankings
Newsletter
Status
Tags
About
RSS Feed
Reading List
Subscribe

Stay in the Loop

Get the latest security alerts, tutorials, and tech insights delivered to your inbox.

Subscribe NowFree forever. No spam.
COSMICBYTEZLABS

Your trusted source for IT intelligence, cybersecurity insights, and hands-on technical guides.

429+ Articles
114+ Guides

CONTENT

  • Latest News
  • Security Alerts
  • HOWTOs
  • Projects
  • Exam Prep

RESOURCES

  • Search
  • Browse Tags
  • Newsletter Archive
  • Reading List
  • RSS Feed

COMPANY

  • About Us
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CosmicBytez Labs. All rights reserved.

System Status: Operational
  1. Home
  2. HOWTOs
  3. Enterprise BitLocker Automation with PowerShell
Enterprise BitLocker Automation with PowerShell
HOWTOAdvanced

Enterprise BitLocker Automation with PowerShell

Deploy and manage BitLocker encryption at scale using PowerShell, with automatic TPM validation, recovery key backup to Azure AD and NinjaRMM, and...

Dylan H.

Security Engineering

February 3, 2026
6 min read

Prerequisites

  • PowerShell 5.1+
  • TPM 2.0 hardware
  • Windows 10/11 Pro or Enterprise
  • Admin privileges

Overview

Managing BitLocker encryption across hundreds or thousands of endpoints manually is impractical. This guide walks you through building an enterprise-grade BitLocker automation script that handles TPM validation, encryption deployment, recovery key backup, and progress monitoring.

What You'll Build

  • Automated TPM readiness validation (5-point check)
  • Multi-mode execution (Check, Enable, Disable, Backup)
  • Dual recovery key storage (Azure AD + RMM)
  • Real-time encryption progress monitoring
  • Graceful error handling for mixed environments

Why Automate BitLocker?

ChallengeSolution
Manual deployment doesn't scaleAutomated deployment via RMM/GPO
Recovery keys get lostAutomatic backup to Azure AD + RMM
TPM issues cause failuresPre-flight validation before encryption
No visibility into statusCustom field reporting for inventory

Architecture

The script operates in four distinct modes controlled by an environment variable:

┌───────────────────────────────────────────────────────────┐
│                    BitLocker Automation                   │
├───────────────────────────────────────────────────────────┤
│  Mode: CheckBitlocker    → Report TPM & encryption status │
│  Mode: EnableBitlocker   → Full encryption workflow       │
│  Mode: DisableBitlocker  → Decryption with progress       │
│  Mode: BackupBitlockerKeys → Recovery key backup only     │
└───────────────────────────────────────────────────────────┘
                              │
                              ▼
┌───────────────────────────────────────────────────────────┐
│                    Integration Points                     │
├───────────────────┬───────────────────┬───────────────────┤
│     NinjaRMM      │     Azure AD      │    On-Prem AD     │
│   Custom Fields   │  Key Backup API   │    Key Escrow     │
└───────────────────┴───────────────────┴───────────────────┘

TPM Validation

Before any encryption operation, we perform a comprehensive TPM readiness check:

function Test-TpmReadiness {
    $tpm = Get-Tpm
 
    $checks = @{
        Present   = $tpm.TpmPresent
        Ready     = $tpm.TpmReady
        Enabled   = $tpm.TpmEnabled
        Activated = $tpm.TpmActivated
        Owned     = $tpm.TpmOwned
    }
 
    Write-Host "TPM Status:"
    Write-Host "  Present:   $($checks.Present)"
    Write-Host "  Ready:     $($checks.Ready)"
    Write-Host "  Enabled:   $($checks.Enabled)"
    Write-Host "  Activated: $($checks.Activated)"
    Write-Host "  Owned:     $($checks.Owned)"
 
    # All checks must pass
    $allPassed = $checks.Values | Where-Object { $_ -eq $false } | Measure-Object
 
    if ($allPassed.Count -gt 0) {
        Write-Host "TPM validation FAILED" -ForegroundColor Red
        return $false
    }
 
    Write-Host "TPM validation PASSED" -ForegroundColor Green
    return $true
}

TPM Requirements

CheckPurpose
PresentTPM chip exists in hardware
ReadyTPM is initialized and ready
EnabledTPM is enabled in BIOS
ActivatedTPM is activated (not suspended)
OwnedTPM ownership has been taken

Enable BitLocker Workflow

The encryption workflow follows this process:

function Enable-BitLockerEncryption {
    param(
        [string]$MountPoint = $env:SystemDrive
    )
 
    # Step 1: Validate TPM
    if (-not (Test-TpmReadiness)) {
        Set-BitlockerStatus "NO_ENCRYPTION_POSSIBLE"
        return
    }
 
    # Step 2: Check current status
    $volume = Get-BitLockerVolume -MountPoint $MountPoint
 
    if ($volume.ProtectionStatus -eq "On") {
        Write-Host "BitLocker already enabled"
        Backup-BitlockerKeys -MountPoint $MountPoint
        return
    }
 
    # Step 3: Add recovery password protector
    Write-Host "Adding recovery password protector..."
    Add-BitLockerKeyProtector -MountPoint $MountPoint -RecoveryPasswordProtector
 
    # Step 4: Backup keys before encryption
    Backup-BitlockerKeys -MountPoint $MountPoint
 
    # Step 5: Enable encryption with AES-256
    Write-Host "Starting encryption with AES-256..."
    Enable-BitLocker `
        -MountPoint $MountPoint `
        -EncryptionMethod Aes256 `
        -TpmProtector `
        -SkipHardwareTest
 
    # Step 6: Monitor progress
    Watch-EncryptionProgress -MountPoint $MountPoint
}

Encryption Methods

MethodKey SizeUse Case
Aes128128-bitLegacy compatibility
Aes256256-bitRecommended for enterprise
XtsAes128128-bitWindows 10+ default
XtsAes256256-bitMaximum security

Recovery Key Backup

Recovery keys are backed up to multiple locations for redundancy:

Azure AD Backup

function Backup-ToAzureAD {
    param(
        [string]$MountPoint = $env:SystemDrive
    )
 
    # Check Azure AD join status
    $dsregStatus = dsregcmd /status
    $isAzureADJoined = $dsregStatus -match "AzureAdJoined\s*:\s*YES"
 
    if (-not $isAzureADJoined) {
        Write-Host "Device not Azure AD joined - skipping AAD backup"
        return $false
    }
 
    # Get recovery protector ID
    $volume = Get-BitLockerVolume -MountPoint $MountPoint
    $recoveryProtector = $volume.KeyProtector |
        Where-Object { $_.KeyProtectorType -eq "RecoveryPassword" } |
        Select-Object -First 1
 
    if (-not $recoveryProtector) {
        Write-Host "No recovery protector found"
        return $false
    }
 
    try {
        BackupToAAD-BitLockerKeyProtector `
            -MountPoint $MountPoint `
            -KeyProtectorId $recoveryProtector.KeyProtectorId
 
        Write-Host "Recovery key backed up to Azure AD" -ForegroundColor Green
        return $true
    }
    catch {
        Write-Host "Azure AD backup failed: $_" -ForegroundColor Yellow
        return $false
    }
}

NinjaRMM Custom Field

function Set-NinjaRecoveryKey {
    param(
        [string]$RecoveryKey
    )
 
    # Check if NinjaRMM CLI is available
    $ninjaAvailable = Get-Command Ninja-Property-Set -ErrorAction SilentlyContinue
 
    if (-not $ninjaAvailable) {
        Write-Host "NinjaRMM CLI not available - skipping"
        return
    }
 
    # Update custom field
    Ninja-Property-Set BitlockerKey $RecoveryKey
    Write-Host "Recovery key saved to NinjaRMM" -ForegroundColor Green
}

Progress Monitoring

For large drives, encryption can take hours. Monitor progress in real-time:

function Watch-EncryptionProgress {
    param(
        [string]$MountPoint = $env:SystemDrive,
        [int]$IntervalSeconds = 60
    )
 
    Write-Host "Monitoring encryption progress..."
 
    do {
        $volume = Get-BitLockerVolume -MountPoint $MountPoint
        $percent = $volume.EncryptionPercentage
        $status = $volume.VolumeStatus
 
        $timestamp = Get-Date -Format "HH:mm:ss"
        Write-Host "[$timestamp] Status: $status | Progress: $percent%"
 
        if ($status -eq "FullyEncrypted") {
            Write-Host "Encryption complete!" -ForegroundColor Green
            break
        }
 
        if ($status -eq "EncryptionInProgress") {
            Start-Sleep -Seconds $IntervalSeconds
        }
        else {
            # Unexpected status
            Write-Host "Unexpected status: $status" -ForegroundColor Yellow
            break
        }
 
    } while ($true)
}

Status Values

StatusMeaning
FullyDecryptedNo encryption
EncryptionInProgressCurrently encrypting
FullyEncryptedEncryption complete
DecryptionInProgressCurrently decrypting

Complete Script

Here's the full enterprise-ready script:

#Requires -RunAsAdministrator
#Requires -Version 5.1
 
<#
.SYNOPSIS
    Enterprise BitLocker automation with TPM validation and key backup.
 
.DESCRIPTION
    Manages BitLocker encryption lifecycle with:
    - TPM 5-point validation
    - AES-256 encryption
    - Dual key backup (Azure AD + NinjaRMM)
    - Real-time progress monitoring
 
.PARAMETER Action
    CheckBitlocker | EnableBitlocker | DisableBitlocker | BackupBitlockerKeys
#>
 
param(
    [ValidateSet("CheckBitlocker", "EnableBitlocker", "DisableBitlocker", "BackupBitlockerKeys")]
    [string]$Action = $env:action
)
 
# Main execution
switch ($Action) {
    "CheckBitlocker" {
        Test-TpmReadiness
        Get-BitLockerVolume -MountPoint $env:SystemDrive | Format-List
    }
    "EnableBitlocker" {
        Enable-BitLockerEncryption
    }
    "DisableBitlocker" {
        Disable-BitLocker -MountPoint $env:SystemDrive
        Watch-DecryptionProgress
    }
    "BackupBitlockerKeys" {
        Backup-BitlockerKeys -MountPoint $env:SystemDrive
    }
    default {
        Write-Host "No action specified. Use -Action parameter."
    }
}

Deployment Options

Via NinjaRMM

  1. Create a new script in NinjaRMM
  2. Set action as a script variable
  3. Deploy to device groups via policy

Via Group Policy

  1. Save script to NETLOGON share
  2. Create GPO with scheduled task
  3. Set action via environment variable

Via Intune

  1. Package as Win32 app or PowerShell script
  2. Set detection rules based on BitLocker status
  3. Deploy to Azure AD groups

Troubleshooting

TPM Not Ready

# Clear TPM (requires physical presence)
Clear-Tpm
 
# Initialize TPM
Initialize-Tpm -AllowClear

Encryption Stuck

# Check detailed status
manage-bde -status C:
 
# Resume if paused
Resume-BitLocker -MountPoint C:

Recovery Key Not Found

# List all protectors
(Get-BitLockerVolume -MountPoint C:).KeyProtector
 
# Add new recovery password
Add-BitLockerKeyProtector -MountPoint C: -RecoveryPasswordProtector

Best Practices

  1. Always test in a lab first - Encryption issues can cause data loss
  2. Backup keys to multiple locations - Azure AD + RMM + on-prem AD
  3. Use AES-256 for compliance - Required for many regulations
  4. Monitor encryption progress - Large drives take hours
  5. Document recovery procedures - Know how to recover before you need to

Next Steps

  • Windows Security Baseline Audit
  • SentinelOne Agent Deployment
  • Building a Secure Homelab
#BitLocker#PowerShell#Encryption#Azure AD#NinjaRMM#Security

Related Articles

Windows Server Hardening: Complete Security Guide for

Step-by-step Windows Server hardening covering CIS benchmarks, attack surface reduction, service hardening, firewall rules, credential protection, and...

43 min read

FortiGate Firewall Policy Management with PowerShell

Automate FortiGate firewall policy creation, backup, and auditing using PowerShell and the FortiOS REST API. Includes bulk rule deployment, change...

7 min read

SentinelOne Threat Hunting with Deep Visibility

Master threat hunting using SentinelOne's Deep Visibility query language. Learn to investigate suspicious processes, detect lateral movement, hunt for...

8 min read
Back to all HOWTOs