Wednesday, 11 June 2025

BitLocker Remediation Script for SCCM & Intune

 

This blog walks you through a PowerShell script that automates BitLocker encryption, validates TPM status, and logs all activity to a file—perfect for automated deployments via SCCM, Intune, or GPO.


Key Features of the Script

  • 🔍 Checks TPM presence and status
  • 🔐 Verifies BitLocker encryption and protection status
  • 🔄 Enables encryption and protection if required
  • ☁️ Backs up BitLocker recovery keys to Azure AD
  • 📃 Logs actions with timestamps and severity levels

🧩 PowerShell Script Breakdown

Below is the complete PowerShell script. You can save this as Enable-BitLocker.ps1 and deploy it as needed.

Function Get-LoggedInUser {

    [CmdletBinding()]

    param(

        [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]

        [string[]] $ComputerName = $env:COMPUTERNAME,

 

        [Parameter(Mandatory = $false)]

        [Alias("SamAccountName")]

        [string]   $UserName

    )

    PROCESS {

        foreach ($Computer in $ComputerName) {

            try {

                $Computer = $Computer.ToUpper()

                $SessionList = quser /Server:$Computer 2>$null

                if ($SessionList) {

                    $UserInfo = foreach ($Session in ($SessionList | select -Skip 1)) {

                        $Session = $Session.ToString().trim() -replace '\s+', ' ' -replace '>', ''

                        if ($Session.Split(' ')[3] -eq 'Active') {

                            [PSCustomObject]@{

                                ComputerName = $Computer

                                UserName     = $session.Split(' ')[0]

                                SessionName  = $session.Split(' ')[1]

                                SessionID    = $Session.Split(' ')[2]

                                SessionState = $Session.Split(' ')[3]

                                IdleTime     = $Session.Split(' ')[4]

                                LogonTime    = $session.Split(' ')[5, 6, 7] -as [string] -as [datetime]

                            }

                        } else {

                            [PSCustomObject]@{

                                ComputerName = $Computer

                                UserName     = $session.Split(' ')[0]

                                SessionName  = $null

                                SessionID    = $session.Split(' ')[1]

                                SessionState = 'Disconnected'

                                IdleTime     = $Session.Split(' ')[3]

                                LogonTime    = $session.Split(' ')[4, 5, 6] -as [string] -as [datetime]

                            }

                        }

                    }

                    if ($PSBoundParameters.ContainsKey('Username')) {

                        $UserInfo | Where-Object {$_.UserName -eq $UserName}

                    } else {

                        $UserInfo | Sort-Object LogonTime

                    }

                }

            } catch {

                Write-Error $_.Exception.Message

            }

        }

    }

}

 

Function Out-LogFile {

    Param(

        [Parameter(Mandatory = $false)] $Text,

        $Mode,

        [Parameter(Mandatory = $false)][ValidateSet(1, 2, 3, 'Information', 'Warning', 'Error')]$Severity = 1

    )

 

    switch ($Severity) {

        'Information' {$Severity = 1}

        'Warning' {$Severity = 2}

        'Error' {$Severity = 3}

    }

 

    $clientpath = 'C:\Windows'

    $Logfile = "$clientpath\temp\BitlockerAzure.log"

 

    foreach ($item in $text) {

        $item = '<![LOG[' + $item + ']LOG]!>'

        $time = 'time="' + (Get-Date -Format HH:mm:ss.fff) + '+000"'

        $date = 'date="' + (Get-Date -Format MM-dd-yyyy) + '"'

        $component = 'component="BitlockerScript"'

        $context = 'context=""'

        $type = 'type="' + $Severity + '"'

        $thread = 'thread="' + $PID + '"'

        $file = 'file=""'

        $logblock = ($time, $date, $component, $context, $type, $thread, $file) -join ' '

        $logblock = '<' + $logblock + '>'

        $item + $logblock | Out-File -Encoding utf8 -Append $logFile

    }

}

 

function Get-TPMStatus {

    try {

        $tpm = Get-WmiObject -Namespace "Root\CIMv2\Security\MicrosoftTpm" -Class Win32_Tpm

        if ($tpm) {

            if ($tpm.IsEnabled -eq $false) {

                return "TPM is turned off"

            } elseif ($tpm.IsPresent -eq $false) {

                return "No TPM present"

            } else {

                return "TPM is enabled"

            }

        } else {

            return "No TPM information available"

        }

    } catch {

        return "Error retrieving TPM status"

    }

}


 

💡 Deployment Tips

  • Run as Administrator – TPM and BitLocker commands require elevated privileges.
  • Log Review – Review C:\Windows\Temp\BitlockerAzure.log for audit and debugging.
  • Use with Intune or Task Scheduler for zero-touch deployments.
  • Test on a VM or staging environment before deploying widely.

BitLocker Remediation Script for SCCM & Intune

  This blog walks you through a PowerShell script that automates BitLocker encryption, validates TPM status, and logs all activity to a fil...