Artykuł

Backing up Bitlocker Keys and LAPS passwords from Active Directory

Having a modern, secure infrastructure in 2019 is a requirement. You should implement BitLocker to make sure that in the event of stolen laptop data is not readily extractable and implementing LAPS is a must in a fast changing IT world. But I'm not here to convince you to those two security features. I'm here to show you an easy way to backup LAPS and BitLocker. While having everything stored in Active Directory is excellent, things can get complicated when you don't have access to your Active Directory, or you restore an older version of it. You see, LAPS, for example, keeps only last Administrator password. This is great and all but what happens if you restore the machine from backup from 6 months back? Your password has already changed multiple times. During our testing of DR scenarios, we wanted to access the computer via their local Administrator credentials and we just couldn't because that password was already gone.

Extracting Bitlocker and LAPS passwords is very risky
Please be aware that exporting Bitlocker and LAPS is considered a risk if you mishandle the data. You shouldn't extract that data unless you have a valid reason and you store that data safely somewhere in a safe place. Saving it on your file share isn't the best idea!
Extracting Bitlocker from Active Directory

Below code should allow you to extract all BitLocker Keys available in Active Directory for all computers. Keep in mind it will get it all. Not only the latest one.

function Get-WinADDomainBitlocker {
    param(
        [string] $Domain = $Env:USERDNSDOMAIN,
        [Array] $Computers
    )
    $Properties = @(
        'Name',
        'OperatingSystem',
        'DistinguishedName'
    )
    #[DateTime] $CurrentDate = Get-Date

    if ($null -eq $Computers) {
        $Computers = Get-ADComputer -Filter * -Properties $Properties -Server $Domain
    }
    foreach ($Computer in $Computers) {
        $Bitlockers = Get-ADObject -Filter 'objectClass -eq "msFVE-RecoveryInformation"' -SearchBase $Computer.DistinguishedName -Properties 'WhenCreated', 'msFVE-RecoveryPassword' #|  Sort-Object whenCreated -Descending #| Select-Object whenCreated, msFVE-RecoveryPassword
        
        foreach ($Bitlocker in $Bitlockers) {
            [PSCustomObject] @{
                'Name'                        = $Computer.Name
                'Operating System'            = $Computer.'OperatingSystem'
                'Bitlocker Recovery Password' = $Bitlocker.'msFVE-RecoveryPassword'
                'Bitlocker When'              = $Bitlocker.WhenCreated
                'DistinguishedName'           = $Computer.'DistinguishedName'
            }
        }
    }
}

Usage is quite simple

$MyBitlocker = Get-WinADDomainBitlocker
$MyBitlocker | Format-Table -AutoSize


# Exporting to  Excel 
# Install-Module PSWriteExcel # is required
ConvertTo-Excel -FilePath 'C:\myFile.xlsx' -DataTable $MyBitlocker -AutoFilter -AutoFit -ExcelWorkSheetName 'Bitlocker Keys'
Extracting LAPS from Active Directory

Below code is able to deliver extracted LAPS passwords for each, and every computer in Active Directory. It also shows Expiration Time and Days to Expire.

function Get-WinADDomainLAPS {
    [CmdletBinding()]
    param(
        [string] $Domain = $Env:USERDNSDOMAIN,
        [Array] $Computers
    )
    $Properties = @(
        'Name',
        'OperatingSystem',
        'DistinguishedName',
        'ms-Mcs-AdmPwd',
        'ms-Mcs-AdmPwdExpirationTime'
    )
    [DateTime] $CurrentDate = Get-Date

    if ($null -eq $Computers -or $Computers.Count -eq 0) {
        $Computers = Get-ADComputer -Filter * -Properties $Properties
    }
    foreach ($Computer in $Computers) {
        [PSCustomObject] @{
            'Name'                 = $Computer.Name
            'Operating System'     = $Computer.'OperatingSystem'
            'Laps Password'        = $Computer.'ms-Mcs-AdmPwd'
            'Laps Expire (days)'   = Convert-TimeToDays -StartTime ($CurrentDate) -EndTime (Convert-ToDateTime -Timestring ($Computer.'ms-Mcs-AdmPwdExpirationTime'))
            'Laps Expiration Time' = Convert-ToDateTime -Timestring ($Computer.'ms-Mcs-AdmPwdExpirationTime')
            'DistinguishedName'    = $Computer.'DistinguishedName'
        }
    }
}

Again, usage is very similar to what you get in Bitlocker above

$Laps = Get-WinADDomainLAPS
$Laps | Format-Table -AutoSize

# Again using this required PSWriteExcel
ConvertTo-Excel -FilePath 'C:\myFile.xlsx' -DataTable $Laps -AutoFilter -AutoFit -ExcelWorkSheetName 'LAPS'
Required modules

There are two PowerShell modules I'm using that I've created and are utilized above. One is PSSharedGoods, and one is PSWriteExcel. PSSharedGoods is required for two functions Convert-TimeToDays and Convert-ToDateTime. If you don't feel like installing those feel free to use the code below. It's not strongly optimized, but it works. PSWriteExcel is responsible for creating an Excel file if you prefer to export using other, more common modules you don't need that.

function Convert-TimeToDays {
    [CmdletBinding()]
    param (
        $StartTime,
        $EndTime,
        #[nullable[DateTime]] $StartTime,
        #[nullable[DateTime]] $EndTime,
        [string] $Ignore = '*1601*'
    )
    if ($StartTime -and $EndTime) {
        try {
            if ($StartTime -notlike $Ignore -and $EndTime -notlike $Ignore) {
                $Days = (NEW-TIMESPAN -Start (GET-DATE) -End ($EndTime)).Days
            } else {
                $Days = $null
            }
        } catch {
            $Days = $null
        }
    }
    return $Days
}

function Convert-ToDateTime {
    [CmdletBinding()]
    param (
        [string] $Timestring,
        [string] $Ignore = '*1601*'
    )
    Try {
        $DateTime = ([datetime]::FromFileTime($Timestring))
    } catch {
        $DateTime = $null
    }
    if ($null -eq $DateTime -or $DateTime -like $Ignore) {
        return $null
    } else {
        return $DateTime
    }
}
Tags: , , ,

This is a unique website which will require a more modern browser to work! Please upgrade today!