none
Zerotouch Bitlocker Deployment - Problems with TPM KeyProtector / GPO login script / Powershell

    Question

  • Hi.

    I'm trying to get Bitlocker to work when users are logging on to our domain.

    https://adameyob.com has provided a lot of information but somehow I can't seem to get it to work.

    After running a slightly modified version of his script and reboot I can see Bitlocker isn't starting and when I look at the ProtectorKeys I can see that the TPM key protector hasn't been added which is why I presume it's not starting.

    The script contains these two protectors:
    Start-Process 'manage-bde.exe' -ArgumentList " -protectors -add $env:SystemDrive -recoverypassword" -Verb runas -Wait
    Start-Process 'manage-bde.exe' -ArgumentList " -protectors -add $env:SystemDrive  -tpm" -Verb runas -Wait

    The script only adds the recovery password key not the tpm one.

    I can't find any errors in the event log and I can't seem to output any errors that might occur when the script is running.

    If I run the script manually or line by line it works fine.

    According to the system tpm is present, ready and activated. Clearing the TPM made no difference. The system also states the drive can be encrypted and adding "Start-Transcript" and "Stop-Transcript" in the scripts top and bottom didn't provide anything useful.

    Any tips on how to debug and find the reason or does anyone have any information that can set me on the right passage?

    Thank you.


    Wednesday, May 15, 2019 12:58 PM

All replies

  • Since there can be only one TPM protector, please verify if the c: drive already contains one:

    manage-bde -protectors -get c:

    Wednesday, May 15, 2019 1:52 PM
  • There's no tpm protector.
    Thursday, May 16, 2019 7:20 AM
  • The script will not work as logon script, since it needs elevation. Configure it to run as startup script.
    Thursday, May 16, 2019 7:33 AM
  • Adding the Recovery Password Key would also require elevated rights but that gets added.

    I'm running the script via "Computer Configuration".

    I'm beginning to think maybe adding a TPM key protector isn't possible with the SYSTEM account.

    Thursday, May 16, 2019 8:03 AM
  • "I'm beginning to think maybe adding a TPM key protector isn't possible with the SYSTEM account." - Good idea. You may confirm or falsify this idea by using the system account via psexec:

    1 download psexec from MS

    2 open an elevated command prompt and launch

    psexec -s -i cmd

    3 on the new cmd which opens, you act as system account. Now start your script lines from there for a test.

    Thursday, May 16, 2019 8:50 AM
  • I'm a bit confused as to why you're wrapping manage-bde.exe in a Powershell script.

    Windows 10 has new native Bitlocker commandlets: https://docs.microsoft.com/en-us/powershell/module/bitlocker/?view=win10-ps and manage-bde is already not supported anymore for all functions in the newer releases. The commandlets also give slightly better error messages back even though they're still not great.

    Thursday, May 16, 2019 9:30 AM
  • @athmanb Would you mind to share where you read this, that manage.bde is already out of support for...?
    Thursday, May 16, 2019 9:33 AM
  • That seemed to work fine.
    Thursday, May 16, 2019 10:02 AM
  • Could you try with a scheduled task that runs as system account and gets triggered on system startup instead of with a startup script, please? I once had a case where this (for whatever reason) made a difference.
    Thursday, May 16, 2019 10:39 AM
  • There are a lot of information on Bitlocker on the web. I've tried to combine whatever I found to fit our wants and needs and not worry about if the function was a Powershell cmdlet or an exe file. Getting things to work was my primary concern.

    I've re-written the script to only use Powershell commands based on your link even the backup to AD which I'm testing out now.

    Thursday, May 16, 2019 11:16 AM
  • Ok, some news.

    I tried changing the script to run Powershell cmdlets instead of manage-bde.exe and I got a different result:

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

    If the other script is running it would run this: 

    Start-Process 'manage-bde.exe' -ArgumentList " -protectors -add $env:SystemDrive  -tpm" -Verb runas -Wait

    This doesn't generate any errors but none of them are adding the TPM protector key.

    I tried running the script via the scheduler but nothing seems to happen. The script says it's running but I don't get any errors, nothing happens and there doesn't seem to be anything in the Event Viewer.

    I tried different settings; different user, location of the script etc. etc.

    I tried to run the Powershell script via PSExec and see if those commands had any issues running as SYSTEM but that worked out fine.

    Monday, May 20, 2019 9:52 AM
  • Could you tell me what action you specified in scheduler?

    Should be powershell yourscript.ps1

    If that is what you have and it does not work, see if other .ps1 scripts work, for example a one liner that creates a folder on c:

    md c:\test

    Monday, May 20, 2019 12:17 PM
  • Ok, I got the scheduled task running.

    I get the same error as before. The task is running with SYSTEM and I get the TPM error.

    I'll try and run manage-bde.exe tomorrow and see if that makes a difference - also I'll try and run it with a user instead of SYSTEM as well.

    Monday, May 20, 2019 1:43 PM
  • I've got it working.

    If the script is located locally and the scheduled task runs powershell.exe with the path to the script as parameter it works.

    If the script is run where I select the script via the browse button and with no arguments it doesn't work.

    If the script is located in SYSVOL - or a remote share - it doesn't work.

    If the script is run via GPO it does work but I get the TPM error.

    Any ideas?


    Tuesday, May 21, 2019 12:47 PM
  • Why would you run this as a logon script.  It is a one time thing.  Logon scripts do not run elevated.  Scripts on a share are not trusted unless they are signed.

    You need to step back and decide what you are trying to do then research this to find the correct way to do it.


    \_(ツ)_/

    Tuesday, May 21, 2019 12:51 PM
  • He is not using a logon script anymore...way past that, jrv. Scheduled task as system.
    Tuesday, May 21, 2019 12:52 PM
  • He is not using a logon script anymore...way past that, jrv. Scheduled task as system.

    Why does a one time task need to be run as a task?


    \_(ツ)_/

    Tuesday, May 21, 2019 12:57 PM
  • Scheduled tasks can be configured to run once, only. Those are called "immediate tasks".
    Tuesday, May 21, 2019 1:32 PM
  • But why.  Why not just deploy this once remotely.

    Look up how to set up TPM in a corporate environment. 


    \_(ツ)_/

    Tuesday, May 21, 2019 1:37 PM
  • I want to make sure all computers that's already encrypted will store the recovery key in our local AD or Azure AD and all computers that's not encrypted will begin preparing the computer for encryption and start it.

    A startup (not login script) script does run elevated (Computer Config.)

    We moved on to a scheduled task because we wanted to test if that made a difference. It could help finding the source of the problem.

    So far we've discovered that if the script is running from the local harddrive via a scheduled task it works but if it's run via GPO it can't add the TPM protector key - everything else works fine (the recovery password, backing up the key to AD etc.).

    Update: The actual 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

    • Edited by tbresson Wednesday, May 22, 2019 12:37 PM Added error msg
    Wednesday, May 22, 2019 12:35 PM
  • Could you please check (as system account) what is your execution policy set to?

    get-executionpolicy

    Wednesday, May 22, 2019 12:38 PM
  • Unrestricted.
    Wednesday, May 22, 2019 12:59 PM
  • Can the system account access the script file? Test with psexec.

    If it can access the script file, are you able to run other scheduled tasks that start powershell scripts as system account IF you place the script o a network share? 

    Wednesday, May 22, 2019 4:42 PM
  • The script is executed since I get the errors and the recovery password key is generated and saved to AD.

    As mentioned previous I tried to test that but had some issues. As also mentioned it's probably related to permissions and remote script execution and what not.

    Perhaps it's a timing issue that the TPM hasn't been registered as ready right when the system is started. I could try and just place a sleep command in the beginning and see if that makes a difference. Also I'm trying to get Powershell to write a more readable error message to see if there are other information that can be used.

    Thursday, May 23, 2019 7:06 AM
  • I have no idea why a local script should work differently - bug/timing issue/race condition - I agree.
    Thursday, May 23, 2019 7:18 AM
  • A bit more info:

    I tried to do a "try" & "catch" in the script around where I run the enable-bitlocker cmdlet and it actually doesn't catch the error but in the TransactionLog the error is written as though there was an error.

    Also I checked the EventLog which states that the TPM was succesfully provisioned and is ready for use (event 1025) 27 miliseconds before the Recovery information is succesfully backed up to AD (event 513). 

    (The Enable-Bitlocker cmdlnet is run just before the key is backed up to AD.)


    • Edited by tbresson Thursday, May 23, 2019 11:01 AM Added more info
    Thursday, May 23, 2019 10:59 AM
  • enable-bitlocker  … -ErrorAction Stop

    \_(ツ)_/

    Thursday, May 23, 2019 11:09 AM
  • Adding the ErrorAction Stop seems to replace the error in the transaction log with a more simplistic error message but now the catch, try-event is triggered. But that event simply generates the same error massage as was seen in the transactions log before.
    Thursday, May 23, 2019 11:44 AM
  • That is how Try/Catch works.  What you write to the error log is your issue.  The error is the error.  Changing the code so that Try/Catch works doesn't fix any errors.  It just allows you to detect the error and react to it in code.

    The error you report ": A required privilege is not held by the client" is what you have to address.

    The only way to make this work is to run the script under an elevated admin account.    The admin account must have "batch" and "run as a service" privileges. The Admin account must also have all correct privileges on AD.  The script should be signed.  This will not work in a login script and a startup script may not have access to the network when it runs.

    Posting in the Security forum will get you more information that can help you discover what you are missing in your setups.

    Start here for most background: https://docs.microsoft.com/en-us/microsoft-desktop-optimization-pack/mbam-v25/prerequisites-for-mbam-25-clients

    Here is the forum for TPM deployment: https://social.technet.microsoft.com/Forums/en-US/home?forum=mdopmbam


    \_(ツ)_/

    Thursday, May 23, 2019 11:55 AM
  • Agreed.

    Still: the system account has access to the network resources in domains (=is part of "authenticated users").

    He says it successuflly dumps the recovery key to AD, so it may be that the TPM recovery password CANNOT be dumped to AD anymore - if I remember correctly, that was changed with some windows version,

    Thursday, May 23, 2019 12:24 PM
  • Agreed.

    Still: the system account has access to the network resources in domains (=is part of "authenticated users").

    He says it successuflly dumps the recovery key to AD, so it may be that the TPM recovery password CANNOT be dumped to AD anymore - if I remember correctly, that was changed with some windows version,

    It has to be  "dumped" to AD.  The OP says that it all works except for the error.  There are other bits that get updated. There is not enough information to diagnose or reproduce the issue. It is up to the user to do the debugging/troubleshooting when the information cannot reproduce the error.

    The MBAM docs will show the correct methods to set this up for all versions of Windows in the enterprise.  Windows7 and later are discussed as well as differences.  WS2008r2 and later AD is discussed.  Somewhere in there is a clue as to what is misconfigured in the OP's systems.


    \_(ツ)_/

    Thursday, May 23, 2019 12:35 PM
  • The try, catch was to try and use the error object's message property to give me a better error description via $_.ErrorDetails.Message; Powershell as a tendency to just abruptly stop the output and add trailing periods ("...")

    What I didn't realize was that I needed the -ErrorAction Stop parameter to trigger the try, catch - I simply thought it would trigger if there was an error. So thanks for pointing that out.

    And thank you for the links. 


    Thursday, May 23, 2019 12:40 PM

  • A startup (not login script) script does run elevated (Computer Config.)

    Actually a startup script does run elevated. What is missing is that the network may not be available and it will have restricted access to shares as the "System" account does not have access to all shares just like the admin accounts don't have access to all shares.

    Also note that the startup script may run before the network is fully available.

    The error also tells us that the account that Is being used is lacking a privileges.  Look at the account privileges:

    whoami /priv

    This will list all privileges for the account.  Compare to a an account that can run the script at a prompt.

    You have to stop thrashing around with bad ideas.  Pick one troubleshooting techniques and direction and work it through to the end.  With many issues this can take hours assuming we need to refer to documentation to clearly understand what is happening at each step.

    I highly recommend carefully reviewing the MBAM documentation as it tells you all of the details affecting a deployment.  There are too many to list or to guess from.


    \_(ツ)_/

    Thursday, May 23, 2019 12:46 PM
  • There are two key protectors being added. See the first post 

    One recovery key and one TPM key. 

    The recovery key is generated fine and is the key that is added to the ad which also works fine. 

    The TPM key is where all the fuss is. 

    Thursday, May 23, 2019 12:47 PM
  • The exception "0x80070522" is also reported with many subsystems as a result of having anti-spyware programs installed.  THe exception may nit be coming from Bitlocker but may be a result of some background operation that the AV or AS software is trying to do. 

    Disable or remove all AV and other third party components to see if the issue goes away. 


    \_(ツ)_/

    Thursday, May 23, 2019 12:54 PM
  • There are two key protectors being added. See the first post 

    One recovery key and one TPM key. 

    The recovery key is generated fine and is the key that is added to the ad which also works fine. 

    The TPM key is where all the fuss is. 

    Is that the line that gives the exceptions you posted.  If o then look at MBAM and BitLocker documentation and track down the resources needed for that line and be sure that are all available to the session using running the code.

    Check which privileges are available and enabled.  Some privileges require explicit activation although yu claim this works when run at a prompt.  THis hints that the issue is that the account failing does not have a privilege enabled when it runs the script.  Run "whoami" to a log and review what it tells you.  Compare it to a successful run.


    \_(ツ)_/

    Thursday, May 23, 2019 1:00 PM
  • Yes, trying to add the TPM keyprotector is what's causing the error.

    I did consider there might be a network issue so I wired up the computer with a cable and I also added a sleep command in the top of the script. Today I added a Test-Connection function in a do-while look at the top. No difference.

    I've done the whoami /priv but I can't find out what priv is needed to add the tpm key protector.

    I'll just have to look further and look into more of MBAM.

    Script:

    Privilege Name                Description                               State
    ============================= ========================================= ========
    SeAssignPrimaryTokenPrivilege Replace a process level token             Disabled
    SeIncreaseQuotaPrivilege      Adjust memory quotas for a process        Disabled
    SeTcbPrivilege                Act as part of the operating system       Enabled
    SeSecurityPrivilege           Manage auditing and security log          Disabled
    SeTakeOwnershipPrivilege      Take ownership of files or other objects  Disabled
    SeLoadDriverPrivilege         Load and unload device drivers            Disabled
    SeCreatePagefilePrivilege     Create a pagefile                         Enabled
    SeCreatePermanentPrivilege    Create permanent shared objects           Enabled
    SeBackupPrivilege             Back up files and directories             Disabled
    SeRestorePrivilege            Restore files and directories             Disabled
    SeShutdownPrivilege           Shut down the system                      Disabled
    SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled
    SeImpersonatePrivilege        Impersonate a client after authentication Enabled

    User:
    Privilege Name                            Description                                                        State
    ========================================= ================================================================== ========
    SeIncreaseQuotaPrivilege                  Adjust memory quotas for a process                                 Disabled
    SeSecurityPrivilege                       Manage auditing and security log                                   Disabled
    SeTakeOwnershipPrivilege                  Take ownership of files or other objects                           Disabled
    SeLoadDriverPrivilege                     Load and unload device drivers                                     Disabled
    SeSystemProfilePrivilege                  Profile system performance                                         Disabled
    SeSystemtimePrivilege                     Change the system time                                             Disabled
    SeProfileSingleProcessPrivilege           Profile single process                                             Disabled
    SeIncreaseBasePriorityPrivilege           Increase scheduling priority                                       Disabled
    SeCreatePagefilePrivilege                 Create a pagefile                                                  Disabled
    SeBackupPrivilege                         Back up files and directories                                      Disabled
    SeRestorePrivilege                        Restore files and directories                                      Disabled
    SeShutdownPrivilege                       Shut down the system                                               Disabled
    SeDebugPrivilege                          Debug programs                                                     Enabled
    SeSystemEnvironmentPrivilege              Modify firmware environment values                                 Disabled
    SeChangeNotifyPrivilege                   Bypass traverse checking                                           Enabled
    SeRemoteShutdownPrivilege                 Force shutdown from a remote system                                Disabled
    SeUndockPrivilege                         Remove computer from docking station                               Disabled
    SeManageVolumePrivilege                   Perform volume maintenance tasks                                   Disabled
    SeImpersonatePrivilege                    Impersonate a client after authentication                          Enabled
    SeCreateGlobalPrivilege                   Create global objects                                              Enabled
    SeIncreaseWorkingSetPrivilege             Increase a process working set                                     Disabled
    SeTimeZonePrivilege                       Change the time zone                                               Disabled
    SeCreateSymbolicLinkPrivilege             Create symbolic links                                              Disabled
    SeDelegateSessionUserImpersonatePrivilege Obtain an impersonation token for another user in the same session Disabled

    Friday, May 24, 2019 12:10 PM
  • Compare only the "enabled" privileges.

    whoami /priv | Where{ $_ -match 'enabled'}


    \_(ツ)_/

    Friday, May 24, 2019 5:21 PM
  • As far as I can tell the user has two privileges that the script doesn't have which is:

    SeDebugPrivilege
    SeCreateGlobalPrivilege

    Monday, May 27, 2019 8:53 AM