2

I am trying to automate the bitlocker in our corporate environment. I have written a script which enables the bitlocker and it works fine if I run it manually, but whenever I implement it via GPO (startup script) right after

Enable-BitLocker -MountPoint C:\ -EncryptionMethod XtsAes256 -SkipHardwareTest -UsedSpaceOnly -TpmProtector

I see in the transcription following error

Add-TpmProtectorInternal : A required privilege is not held by the client. (Exception from HRESULT: 0x80070522)

At C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\BitLocker\BitLocker.psm1:2095 char:31

+ ...   $Result = Add-TpmProtectorInternal $BitLockerVolumeInternal.MountPo ...

+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : NotSpecified: (:) [Write-Error], COMException

    + FullyQualifiedErrorId : System.Runtime.InteropServices.COMException,Add-TpmProtectorInternal

Add-TpmProtectorInternal : A required privilege is not held by the client. (Exception from HRESULT: 0x80070522)

At C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\BitLocker\BitLocker.psm1:2095 char:31

+ ...   $Result = Add-TpmProtectorInternal $BitLockerVolumeInternal.MountPo ...

+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : NotSpecified: (:) [Write-Error], COMException

    + FullyQualifiedErrorId : System.Runtime.InteropServices.COMException,Add-TpmProtectorInternal

I have tried to wrap the PS script with bat file:

powershell.exe -ExecutionPolicy bypass -file "Enable-bitlocker_step2.ps1"

Enable-bitlocker_step2.ps1 script body:

Start-Process Powershell.exe -ArgumentList '-ExecutionPolicy bypass -File "\\**********\SYSVOL\***********\scripts\Enable Bitlocker.ps1"' -Verb RunAs -ErrorAction SilentlyContinue -WarningAction SilentlyContinue

The bitlocker script itself:

Start-Transcript -Path \\Melandru\temp\"$env:COMPUTERNAME.txt"

#get computer capability

$OS_edition = Get-WmiObject -Class win32_operatingSystem

$TPM_info = Get-Tpm

$bitlocker_status = Get-BitLockerVolume C: 

$gpo_path = "***********\SYSVOL\***********\Policies\{*******-****-****-****-**********}\"

###Pre-requisites###

#if bitlocker is on and encryption method is XtsAes256 - exit, since nothing to do

if (($bitlocker_status.protectionstatus -eq "On") -and ($bitlocker_status.EncryptionMethod -eq "XtsAes256")){

    if ((Get-Content "$($gpo_path)\bitlocker_list.txt") -like "*$($env:COMPUTERNAME)*") {Write-output "Bitlocker key already backed up";exit}

    else{

        $key_protector=(Get-BitLockerVolume C:).keyprotector | ?{$_.KeyProtectorType -eq "Recoverypassword"} | select -expandproperty KeyProtectorId

        Backup-BitLockerKeyProtector -KeyProtectorId $key_protector -MountPoint C:

        exit}

    }

#check if encryption/decryption in progress. If so - exit the script

elseif (($bitlocker_status.volumestatus -eq "EncryptionInProgress") -or ($bitlocker_status.volumestatus -eq "DecryptionInProgress")) {Write-output "Bitlocker encryption/decryption in progress";exit}


###define bitlocker functions###

function remove_old_key_protectors {

    foreach ($keyprotector in $bitlocker_status.keyprotector){

        Remove-BitLockerKeyProtector C: -KeyProtectorId $keyprotector.keyprotectorid

        Write-Output "Removed $($keyprotector.keyprotectorid)"

        }

    Write-Output "Old keys removed"

    }

function enable_bitlocker {

    #add a new key protector - recovery password

    Add-BitLockerKeyProtector -MountPoint C:\ -RecoveryPasswordProtector

    Write-Output "Added password key protector"

    #enable bitlocker

    Enable-BitLocker -MountPoint C:\ -EncryptionMethod XtsAes256 -SkipHardwareTest -UsedSpaceOnly -TpmProtector

    Write-Output "Bitlocker enabled"

    }

#check tpm chip and OS edition

if (($OS_edition.caption -notlike "*ent*") -or ($TPM_info.TPMPresent -ne $True)){write-output "Not compatible";exit}

#if all checks passed - do the script logic

else {

    #Check if bitlocker is enabled and enryption method is not XtsAes256. If so - disable bitlocker    

    If (($bitlocker_status.protectionstatus -eq "On") -and ($bitlocker_status.EncryptionMethod -ne "XtsAes256"))  {

        Write-Output "Disabling bitlocker"

        Disable-BitLocker C:

        }

    Elseif ($bitlocker_status.protectionstatus -eq "Off"){

        #check if there's an old protection key and remove it

        if ($bitlocker_status.keyprotector -ne $null) {

        Write-Output "Removing old keys"

        remove_old_key_protectors

        }

        Write-Output "Enabling Bitlocker XtsAes256"

        enable_bitlocker

    }

}

Stop-Transcript -ErrorAction SilentlyContinue

The thing is if i simply run bat file manually from a computer - I have bitlocker enabled, but if I add bat script to Computer Configuration->Policies->Windows Settings->Scripts(Startup/Shutdown)->Startup I see the error mentioned above. Also I tried to push the bitlocker script(without any wrappers) via SCCM - it works.

I would like to understand what permissions are required and why?

5
  • Is there a reason for using a script instead of group policies from Computer Configuration\Administrative Templates\Windows Components\BitLocker Drive Encryption? Apr 6, 2019 at 6:56
  • 1
    @EsaJokinen Thanks for the tip. I was pretty sure that GPO sets parameters, but does not enable the bitlocker itself. also we have many laptops with 128bit encryption, which should be changed to 256(the only way to change it - decrypt and re-encrypt)
    – 2 B
    Apr 8, 2019 at 13:51
  • Well that's a good reason. Apr 8, 2019 at 17:53
  • @TeslaGreat Did you ever solve this? I have the same issue. May 8, 2020 at 2:13
  • @PabloCarrascoHernández nope. didn't find solution. Running via SCCM is my workaround.
    – 2 B
    May 12, 2020 at 10:30

1 Answer 1

0

The error clearly states a privilege issue. I guess this might/can be due to you actual code is in the 2nd script.

I would suggest you to :

  1. Have a single script
  2. Configure the Preference Variable options in the main script as:

    $ErrorActionPreference = "SilentlyContinue" $WarningPreference = "SilentlyContinue"

  3. If your Domain Controller supports running powershell scripts via Logon, then call it from there

  4. If your Domain Controller does not support running powershell scripts via logon, then, yep you can create a batch file. Use the same startup parameters with ExecutionPolicy as bypass. Place the powershell script in the same location as the batch file. I would also advice to use -NoProfile so that any other powershell profile does not interfere. The command line in the batch file would now become:

    Powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\EnableBitLocker.ps1

About Preference Variables

Using Group Policy to deploy a Windows Powershell Logon Script

1
  • Thank you for the advice, but the script itself starts fine - otherwise I wouldn't see the transcript. The specific action is the problem Add-TpmprotectorInternal.
    – 2 B
    May 12, 2020 at 10:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.