17 July 2017

TPM Readiness Verification

A while back, I posted a PowerShell script that verified if the TPM was ready for BitLocker to be applied in a build. Recently, the script stopped working. I decided to decipher the code I had borrowed to make the script work. In looking at it, I found a way to significantly simplify the code down to one-liners.

The objective is to verify the TPM is ready for BitLocker encryption before an image is laid down. This is so that if the technician forgets to ready the TPM, it won't go through the entire build process and then fail near the end, thereby wasting a lot of time. There are five steps to verifying this. They are:

NOTE: As stated in this Dell article, Windows 10 takes ownership of the TPM once the OS is laid down and booted up. It will retake ownership everytime the OS starts unless otherwise stopped by the Disable-TPMAutoProvisioning cmdlet. This means that if you use the Verify No TPM Ownership script after the OS is laid down, it will fail.
  • Verify TPM Ownership is Allowed
  • Verify TPM is Enabled
  • Verify No TPM Ownership
  • Verify TPM is Activated
  • Set the BIOS Password
Each of these steps can be accomplished as a one-liner using PowerShell. As a one-liner, they can be implemented as individual task sequences as shown below.


Each task is set up as a Run Command Line. When WinPE loads, it gathers data in the WMI of the TPM status. I started out using the Get-WMIObject which returned a boolean value. The problem was that MDT does not recognize boolean values. It had to be converted to an integer. The second problem was that executing this via PowerShell would not return the boolean value. It only returned if the expression was successfully executed. That is what the if then else does with the exit 1 or 0. Here are the command lines used along with the required success code.

  • Verify TPM Ownership is Allowed
    • powershell.exe -executionpolicy bypass -command "&{Write-Host 'TPM OwnerShip: ' -NoNewLine;if (([int]((Get-WmiObject -Namespace ROOT\CIMV2\Security\MicrosoftTpm -Class Win32_Tpm).IsOwnerShipAllowed().IsOwnerShipAllowed)) -eq 1) {Write-Host 'Allowed' -ForegroundColor Yellow;Exit 0 } else {Write-Host 'Not Allowed' -ForegroungColor Red;Exit 1}}"
    • Success Code: 1
    • Success Exit Code: 0
  • Verify TPM is Enabled
    • powershell.exe -executionpolicy bypass -command "&{Write-Host 'TPM Enabled: ' -NoNewLine;if (([int]((Get-WmiObject -Namespace ROOT\CIMV2\Security\MicrosoftTpm -Class Win32_Tpm).IsEnabled().isenabled)) -eq 1) {Write-Host 'Yes' -ForegroundColor Yellow;Exit 0 } else {Write-Host 'No' -ForegroundColor Red;Exit 1}}"
    • Success Code: 1
    • Success Exit Code: 0
  • Verify No TPM Ownership
    • powershell.exe -executionpolicy bypass -command "&{Write-Host 'TPM Owned: ' -NoNewLine;if (([int]((Get-WmiObject -Namespace ROOT\CIMV2\Security\MicrosoftTpm -Class Win32_Tpm).isowned().isowned)) -eq 1) {Write-Host 'No' -ForegroundColor Yellow;Exit 0 } else {Write-Host 'No' -ForegroundColor Red;Exit 1}}"
    • Success Code: 1
    • Success Exit Code: 0
  • Verify TPM is Activated
    • powershell.exe -executionpolicy bypass -command "&{Write-Host 'TPM Activated: ' -NoNewLine;if (([int]((Get-WmiObject -Namespace ROOT\CIMV2\Security\MicrosoftTpm -Class Win32_Tpm).IsActivated().isactivated)) -eq 1) {Write-Host 'Yes' -ForegroundColor Yellow;Exit 0 } else {Write-Host 'No' -ForegroundColor Red;Exit 1}}"
    • Success Code: 1
    • Success Exit Code: 0
The other part to this is setting the BIOS password, which also requires CCTK to be installed. For more information on installing the CCTK within the WinPE environment, please refer to this blog entry.

The task sequence to set the BIOS password is shown below. This occurs after the installation of CCTK is done. The task sequence needs to be setup as a Run Command Line. The command line for it is as follows:


  • Set BIOS Password
    • powershell.exe -command "&{If (((Start-Process -FilePath x:\CCTK\cctk.exe -ArgumentList '--setuppwd=<BIOS Password>' -wait -passthru).ExitCode) -eq 115) {(Start-Process -FilePath x:\CCTK\cctk.exe -ArgumentList '--valsetuppwd=<BIOS Password> --setuppwd=<BIOS Password>' -wait -passthru).ExitCode}}"
This command line first tries to set the BIOS password if it is not set. If it is, an error code of 115 is returned and the command line entering the BIOS password is then executed. 

This is all that is required to execute this. Here is a video of the task sequences executing in the build process. 

Here is a video of the task sequences executing at the beginning of the build. 





There is also an alternative to failing at the beginning of the build process. You could have the one-liner create a task sequence variable that would be a flag for a later task just before the BitLocker process starts that would pause the build by initiating the LTISuspend.wsf and pop-up an alert saying to ready the TPM before unpausing the build. We decided to stop the build initially because that reminds the technician that they needed to ready the TPM first. 

0 comments:

Post a Comment