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 from

  • Anonymous
    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 PE

  • 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
    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 project

  • Anonymous
    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).aspx

  • Anonymous
    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.