Check to see if the TPM is enabled
Hey Everyone!
I recently worked on a project where we were enabling the TPM chip prior to enabling Bitlocker through the task sequence. One thing that we wanted to do was to check to see if the TPM was already enabled and activated prior to running the BIOS configuration tool to enable the TPM. The built in MDT script (ztibde.wsf) does this check however it will fail the script and generate an error and exit the task sequence if the TPM is not already enabled so I decided to modify that script slightly and use the new script to set two variables TPMEnabled and TPMActivated so I could use those as conditions on other steps in the task sequence.
The script below should be named ztiCheckforTPM.wsf and placed in the scripts directory on the deployment share. Just place this script in the task sequence prior to your steps to enable the TPM chip and set a condition that checks for the Task Sequence variables TPMEnabled = FALS and TPMActivated = FALSE on your steps that enable the TPM in the BIOS. I plan on posting the steps to enable the TPM for different manufacturer types later but there are some great articles already out there today. Check out this article for Dell machines.
Enjoy and I hope everyone has a great holiday break!
<job id="ZTIBde">
<script language="VBScript" src="ZTIUtility.vbs"/>
<script language="VBScript">
' // ***************************************************************************
' //
' // Copyright (c) Microsoft Corporation. All rights reserved.
' //
' // Microsoft Deployment Toolkit Solution Accelerator
' //
' // File: ZTICheckforTPM.wsf
' //
' // Version: 5.1.1642.01
' //
' // Purpose: Check to see if TPM is enabled and activated
' //
' // Usage: cscript ZTICheckforTPM.wsf [/debug:true]
' //
' // ***************************************************************************
Option Explicit
RunNewInstance
'//----------------------------------------------------------------------------
'//
'// Global constants
'//
'//----------------------------------------------------------------------------
'//----------------------------------------------------------------------------
'// Main Class
'//----------------------------------------------------------------------------
Class ZTICheckforTPM
'//----------------------------------------------------------------------------
'// Class instance variable declarations
'//----------------------------------------------------------------------------
Public oTpm, oBde, oBdeVol
Public bTpmActivated, bTpmOwned, bTpmEnabled
'//----------------------------------------------------------------------------
'// Constructor to initialize needed global objects
'//----------------------------------------------------------------------------
Private Sub Class_Initialize
End Sub
'//----------------------------------------------------------------------------
'// Main routine
'//----------------------------------------------------------------------------
Function Main
Dim iRetVal, iFreeSpace
Dim sBdeHdTool
Dim bDriveChange
Dim sExistingBdeDrive
Dim sOSDBitLockerWaitForEncryption
Dim sBdeInstallSuppress
Dim iPartitionCount
Dim sOsType
Dim sSecondPass
Dim iValidateConnection
Dim objWMIBDE, colEnVol, objEncVol, ColPS
DIm strStatusData, sEncryptionProgress, sCDriveEncryptionStatus, strConnectionStr1
Dim sSystemDrive
iRetVal = Success
sSystemDrive = ucase(mid(oEnv("WINDIR"),1, 2))
iRetVal = TPMValidate()
wscript.echo oEnvironment.Item("TPMEnabled")
wscript.echo oEnvironment.Item("TPMActivated")
Main = Success
End Function
'//
'// END MAIN
'//
'// TPM Management Functions
Function GetTpmInstance()
Dim iRetVal, sConnection
Dim oTpmWmi, iTpmWmi
On Error Resume Next
sConnection = "winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!root\cimv2\Security\MicrosoftTpm"
Set oTpmWmi = GetObject(sConnection)
TestAndFail SUCCESS, 6732, "Failed to Connect to MicrosoftTPM provider"
'// There should either be 0 or 1 instance of the TPM provider class
Set iTpmWmi = oTpmWmi.InstancesOf("Win32_Tpm")
If iTpmWmi.Count = 0 Then
oLogging.CreateEntry "Failed find a TPM instance in the provider class.", LogTypeInfo
GetTpmInstance = Failure
EXIT FUNCTION
End If
Err.Clear
'Get a single instance of the TPM provider class
Set oTpm = oTpmWmi.Get("Win32_Tpm=@")
TestAndFail SUCCESS, 6733, "Get a TPM instance in the provider class"
End Function
Function TpmValidate ()
Dim iRetVal, sCmd, sTpmOwnerPassword
iRetVal = Success
'// Set oTpm to valid instance
iRetVal = GetTpmInstance()
If iRetVal = Failure Then
TPMValidate = Failure
oEnvironment.Item("TPMEnabled") = "FALSE"
oEnvironment.Item("TPMActivated") = "FALSE"
Exit Function
End If
'// Set global booleans for TPM state. Error bubble handled by subs
iRetVal = GetTpmEnabled()
If iRetVal = Failure Then
TPMValidate = Failure
oEnvironment.Item("TPMActivated") = "FALSE"
Exit Function
End IF
iRetVal = GetTpmActivated()
If iRetVal = Failure Then
TPMValidate = Failure
oEnvironment.Item("TPMActivated") = "FALSE"
Exit Function
End IF
TpmValidate = Success
End Function
Function GetTpmEnabled()
Dim iRetVal
iRetVal = Success
iRetVal = oTpm.IsEnabled(bTpmEnabled)
If iRetVal = Failure Then
oLogging.CreateEntry "TPM is not currently enabled", LogTypeInfo
oEnvironment.Item("TPMEnabled") = "FALSE"
GetTPMEnabled = Failure
Exit Function
End If
oEnvironment.Item("TPMEnabled") = "TRUE"
oLogging.CreateEntry "Success TPM Enabled", LogTypeInfo
GetTpmEnabled = Success
End Function
Function GetTpmActivated()
Dim iRetVal
iRetVal = Success
iRetVal = oTpm.IsActivated(bTpmActivated)
If iRetVal = Failure Then
oLogging.CreateEntry "TPM is not currently Activated", LogTypeInfo
oEnvironment.Item("TPMActivated") = "FALSE"
GetTPMActivated = Failure
Exit Function
End If
oEnvironment.Item("TPMActivated") = "TRUE"
oLogging.CreateEntry "Success TPM Is Activated", LogTypeInfo
GetTpmActivated = Success
End Function
End Class
</script>
</job>
This post was contributed by Tim Mintner, a Senior Consultant with Microsoft Services - U.S.
Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the Terms of Use .
Comments
Anonymous
January 01, 2003
I am having a problem with a new hardware "LENOVO x220" from the log i can see that ztiCheckforTPM Property TPMEnabled is now = TRUE ztiCheckforTPM, Property TPMActivated is now = TRUE ztiCheckforTPM I have a Task that checks for the condition TPMEnabled = FALS and TPMActivated = FALSE and should active TPM chip. But then ZTIBDE reports: FAILURE ( 6740 ): False: Check to see if TPM is activated ZTIBde. Is there is something wrong with the script? Or I am doing something wrong? Thank you.Anonymous
January 01, 2003
Looking for BitLocker info ? the following should help, the list below is Bit Locker info compiled fromAnonymous
January 01, 2003
I got the script from Lenovo to check the status of TPM chip. When Lenovo script is reporting TPMTPMActivated = FALSE, ztiCheckforTPM sets TPMTPMActivated = TRUE and since i have a condition TPMActivated = FALSE it never steps in that task. Factory setting for TPMEnabled is TRUE for lenovo. Lenovo script: tpm_status.vbs Set objItems = objWMIService.InstancesOf("Win32_Tpm") For Each objItem in objItems rvaluea = objItem.IsEnabled(A) rvalueb = objItem.IsActivated(B) rvaluec = objItem.IsOwned(C) WScript.Echo "TPM Is Enabled: " & A WScript.Echo "TPM Is Activated: " & B WScript.Echo "TPM Is Owned: " & C Next OSD Log After ztiCheckforTPM: Property TPMActivated is now = TRUE ztiCheckforTPM I am doing something wrong? Thank you.Anonymous
January 01, 2003
I agree with Cogu, either we are both misunderstanding or there's a flaw in the above. I've uploaded a script that uses the logic Cogu describes here: gallery.technet.microsoft.com/Get-TpmInfo-215a8695. Assuming that is (more) correct, you may need to merge the 2 scripts to get the desired outcome.Anonymous
January 01, 2003
We have sooo many different Manufactures in our environment that automating the enabling of the TPM would be a real pain .. instead ... we just check to see if the TPM is enabled before running our Bitlocker enable script and if everything isn't kosher, the script calls the LTIsuspend script... this way a deployment tech can reboot the machine, enter the bios, bla bla bla and then continue the Task Sequence when ready.Anonymous
January 01, 2003
This needs to run in the full OS and not in PE. Unfortunately the drivers for the TPM won't load in PEAnonymous
January 01, 2003
I am having a problem with a new hardware "LENOVO x220" from the log i can see that ztiCheckforTPM Property TPMEnabled is now = TRUE ztiCheckforTPM, Property TPMActivated is now = TRUE ztiCheckforTPM I have a Task that checks for the condition TPMEnabled = FALS and TPMActivated = FALSE and should active TPM chip. But then ZTIBDE reports: FAILURE ( 6740 ): False: Check to see if TPM is activated ZTIBde. Is there is something wrong with the script? Or I am doing something wrong? Thank you.Anonymous
January 01, 2003
I am having a problem with a new hardware "LENOVO x220" from the log i can see that ztiCheckforTPM Property TPMEnabled is now = TRUE ztiCheckforTPM, Property TPMActivated is now = TRUE ztiCheckforTPM I have a Task that checks for the condition TPMEnabled = FALS and TPMActivated = FALSE and should active TPM chip. But then ZTIBDE reports: FAILURE ( 6740 ): False: Check to see if TPM is activated ZTIBde. Is there is something wrong with the script? Or I am doing something wrong? Thank you.Anonymous
January 01, 2003
Great post over on The Deployment Guys by Tim Mintner. Hey Everyone! I recently worked on a projectAnonymous
January 24, 2011
Hi thanks for this script looks great. Can this be run in PE and full OS ? I am struggling to get TPM working in the full OS and know you can add the Dell CCTK to the boot image.Anonymous
June 21, 2011
I am having a problem with a new hardware "LENOVO x220" from the log i can see that ztiCheckforTPM Property TPMEnabled is now = TRUE ztiCheckforTPM, Property TPMActivated is now = TRUE ztiCheckforTPM I have a Task that checks for the condition TPMEnabled = FALS and TPMActivated = FALSE and should active TPM chip. But then ZTIBDE reports: FAILURE ( 6740 ): False: Check to see if TPM is activated ZTIBde. Is there is something wrong with the script? Or I am doing something wrong? Thank you.Anonymous
April 02, 2013
Unless I'm misunderstanding something, this script has a rather big flaw. IsActivated and IsEnabled methods both return a boolean to indicate whether the TPM is activated or enabled. In the script, that value is being saved to bTpmActivated and bTpmEnabled, respectively. However, the value held in those variables is never checked to see if the TPM is truly activated and/or enabled. Instead, it relies simply on the error code returned by the IsActivated and IsEnabled methods to try to figure out whether it is activated or not. i.e.: Attempt to check if TPM is activated. If the error code of the instruction to check whether it's activated is "Failure" (= 1 in MDT) then TPM must not be activated, else it must be activated. This doesn't seem to take into account that these methods can return non-1 results and still fail or that it can return a 0 (success) but TPM still be IsActivated = False and IsEnabled = False. So if a computer contains a Win32_Tpm=@ instance, even if TPM is not activated, so long as an error code of exactly 1 is not returned, this script will still say that TPMActivated = True and the same for TPMEnabled. msdn.microsoft.com/.../aa376449(v=vs.85).aspxAnonymous
January 15, 2014
Could you provide more info about how to create the task sequence and use it with this script? I'm not sure how to set it up.Anonymous
June 05, 2014
I agree with Mark and cogu... based on my reading of the WMI documentation for the Win32_Tpm class, the return value of .IsEnabled and .IsActivated are irrelevant to determine the status.