Following this guide will let you track Bitlocker information on Windows 7 computers using the resource explorer feature of SCCM. It uses compliance settings to do so, however not in the normal way you might use compliance settings.
Contents
Overview
We are going to use Desired Configuration Management to run a script on target machines. The script will run on a regular schedule and place Bitlocker data into a new WMI class named SCCM_Bitlocker. Then, we will SCCM extend hardware inventory so that it collects data from this new class.
Compliance Rules Setting
First, we will need to create a configuration baseline, a configuration item and two compliance rules.
Configuration Item
- Open the SCCM console on your site server.
- Go to Assets and Compliance -> Compliance Settings -> Configuration Items.
- Click the “Create Configuration Item” button on the ribbon.
- On the ‘General’ screen, enter the name “Bitlocker Information” then click ‘Next’.
- On the “Supported Platforms” screen, select the following items then click ‘Next’:
Windows Vista Windows 7 Windows 8 Windows Server 2008 Windows Server 2012
- On the “Settings” screen, click the button labeled “New”.
- On the ‘Create Setting’ screen, enter the following information:
Name: Bitlocker WMI Provider Setting type: Script Data type: String
- Still on the ‘Create Setting’ screen, click the ‘Add Script…’ Button.
- On the ‘Edit Discovery Script’ screen, change the Script language to ‘VBScript’ then paste the following script into the ‘Script’ field.
'Record-BitlockerToWMI.vbs 'Sherry Kissinger, 2010 'http://social.technet.microsoft.com/Forums/en-US/configmgrgeneral/thread/5c9f9681-e665-4b3f-a83a-b554be65a921 'Extended by Connor Humphries. 2013. tyedyehumps@gmail.com. winventures.wordpress.com. 'Extended by John Puskar. 2013. johnpuskar@gmail.com. windowsmasher.wordpress.com. 'v22 Set WhShell = CreateObject("Wscript.Shell") 'on error resume next dim gstrObjects(26,12) dim gtempnum function getData(WshShell, numVolumes, strings) '-------------------------- 'Run the Manage-bde.wsf, and put all the information into oExec to pull out later '-------------------------- Set objFSO = CreateObject("Scripting.FileSystemObject") If objFSO.FileExists("c:\windows\system32\manage-bde.wsf") Then Set oExec = WshShell.Exec("cscript //Nologo c:\windows\system32\manage-bde.wsf -status") drive = "" drivename = "" i = 0 While Not oExec.StdOut.AtEndOfStream '------------------- 'For each line returned from oExec, check what's in it, and add to an array '------------------- line = oExec.StdOut.Readline() if ucase(left(line,6)) = "VOLUME" then 'if drive <> "" then ' targetmif.writeline(" End Group") 'end if i = i + 1 numVolumes = i drive = mid(line,8,2) line = oExec.StdOut.Readline() drivename = line line = "" strings(i,0) = drive strings(i,1) = drivename strings(i,12) = Now end if if drive <> "" and trim(line) <> "" then parts = split(line,":") Select Case replace(trim(parts(0))," ","_") Case "Size" strings(i,2) = trim(parts(1)) Case "BitLocker_Version" strings(i,3) = trim(parts(1)) Case "Conversion_Status" strings(i,4) = trim(parts(1)) Case "Percentage_Encrypted" strings(i,5) = trim(parts(1)) Case "Encryption_Method" strings(i,6) = trim(parts(1)) Case "Protection_Status" strings(i,7) = trim(parts(1)) Case "Lock_Status" strings(i,8) = trim(parts(1)) Case "Identification_Field" strings(i,9) = trim(parts(1)) Case "Key_Protectors" Set WshShellTwo = CreateObject("Wscript.Shell") Dim TPM, strLine Dim Flag Dim oExecTwo Dim strCommand keys = "" strCommand = "cscript //Nologo c:\windows\system32\manage-bde.wsf -protectors -get " & drive Set oExecTwo = WshShellTwo.Exec(strCommand) Flag = false Set TPM = oExecTwo.StdOut While Not TPM.AtEndOfStream strLine = TPM.ReadLine If InStr(strLine, "Protectors") Then Flag = True End if If Flag Then If strLine = "" or strLine = vbNull Then keys = keys Else If keys = "" or keys = vbNull Then keys = Replace(strLine,"ERROR: ","",1,-1,1) Else keys = keys & VBCrLf & Replace(strLine,"ERROR: ","",1,-1,1) End If End If End if Wend strings(i,10) = keys Case "Automatic_Unlock" strings(i,11) = trim(parts(1)) End Select End If Wend Else Dim drive, drivename,size, bitLockerVersion, conversionStatus, percentageEncrypted Dim encryptionMethod, protectionStatus, lockStatus, identificationField Dim keyProtectors, automaticUnlock drive = 0 drivename = 1 size = 2 bitLockerVersion = 3 conversionStatus = 4 percentageEncrypted = 5 encryptionMethod = 6 protectionStatus = 7 lockStatus = 8 identificationField = 9 keyProtectors = 10 automaticUnlock = 11 numVolumes = 1 strings(1,drive) = "All Drives" strings(1,drivename) = "" strings(1,size) = "" strings(1,bitLockerVersion) = "BDE Feature not installed" strings(1,conversionStatus) = "Fully Decrypted" strings(1,percentageEncrypted) = "0%" strings(1,encryptionMethod) = "None" strings(1,protectionStatus) = "Protection Off" strings(1,lockStatus) = "Unlocked" strings(1,identificationField) = "None" strings(1,keyProtectors) = "No key protectors found." strings(1,automaticUnlock) = "" End If End Function Function CreateBitlockerWmiNamespace Dim wbemCimtypeSint16 Dim wbemCimtypeSint32 Dim wbemCimtypeReal32 Dim wbemCimtypeReal64 Dim wbemCimtypeString Dim wbemCimtypeBoolean Dim wbemCimtypeObject Dim wbemCimtypeSint8 Dim wbemCimtypeUint8 Dim wbemCimtypeUint16 Dim wbemCimtypeUint32 Dim wbemCimtypeSint64 Dim wbemCimtypeUint64 Dim wbemCimtypeDateTime Dim wbemCimtypeReference Dim wbemCimtypeChar16 wbemCimtypeSint16 = 2 wbemCimtypeSint32 = 3 wbemCimtypeReal32 = 4 wbemCimtypeReal64 = 5 wbemCimtypeString = 8 wbemCimtypeBoolean = 11 wbemCimtypeObject = 13 wbemCimtypeSint8 = 16 wbemCimtypeUint8 = 17 wbemCimtypeUint16 = 18 wbemCimtypeUint32 = 19 wbemCimtypeSint64 = 20 wbemCimtypeUint64 = 21 wbemCimtypeDateTime = 101 wbemCimtypeReference = 102 wbemCimtypeChar16 = 103 'Create data class structure Set oServices = oLocation.ConnectServer(, "root\cimv2") Set oDataObject = oServices.Get oDataObject.Path_.Class = "SCCM_BitLocker" oDataObject.Properties_.add "Drive", wbemCimtypeString oDataObject.Properties_.add "DriveLabel", wbemCimtypeString oDataObject.Properties_.add "Size", wbemCimtypeString oDataObject.Properties_.add "BitLocker_Version", wbemCimtypeString oDataObject.Properties_.add "Conversion_Status", wbemCimtypeString oDataObject.Properties_.add "Percentage_Encrypted", wbemCimtypeString oDataObject.Properties_.add "Encryption_Method", wbemCimtypeString oDataObject.Properties_.add "Protection_Status", wbemCimtypeString oDataObject.Properties_.add "Lock_Status", wbemCimtypeString oDataObject.Properties_.add "Identification_Field", wbemCimtypeString oDataObject.Properties_.add "Automatic_Unlock", wbemCimtypeString oDataObject.Properties_.add "Key_Protectors", wbemCimtypeString oDataObject.Properties_.add "ScriptLastRan", wbemCimtypeString oDataObject.Properties_("Drive").Qualifiers_.add "key", True oDataObject.Put_ End Function Function createWMI(stringarr, numVolumes, run) '------------------ 'Create the WMI Namespace '------------------ CreateBitlockerWmiNamespace '------------------------------ 'Add Instances to data class Set oServices = oLocation.ConnectServer(, "root\cimv2") For j = 1 To numVolumes Set oNewObject = oServices.Get("SCCM_BitLocker").SpawnInstance_ oNewObject.Drive = "C:" oNewObject.Drive = stringarr(j,0) oNewObject.DriveLabel = stringarr(j,1) oNewObject.Size = stringarr(j,2) oNewObject.BitLocker_Version = stringarr(j,3) oNewObject.Conversion_Status = stringarr(j,4) oNewObject.Percentage_Encrypted = stringarr(j,5) oNewObject.Encryption_Method = stringarr(j,6) oNewObject.Protection_Status = stringarr(j,7) oNewObject.Lock_Status = stringarr(j,8) oNewObject.Identification_Field = stringarr(j,9) oNewObject.Key_Protectors = stringarr(j, 10) oNewObject.Automatic_Unlock = stringarr(j,11) oNewObject.ScriptLastRan = stringarr(j,12) oNewObject.Put_ run = stringarr(j,12) 'Uncomment the following lines to for troubleshooting interactively ' WScript.Echo stringarr(j,0) & ", " &_ ' stringarr(j,1) & ", " &_ ' stringarr(j,2) & ", " &_ ' stringarr(j,3) & ", " &_ ' stringarr(j,4) & ", " &_ ' stringarr(j,5) & ", " &_ ' stringarr(j,6) & ", " &_ ' stringarr(j,7) & ", " &_ ' stringarr(j,8) & ", " &_ ' stringarr(j,9) & ", " &_ ' stringarr(j,10) & ", " &_ ' stringarr(j,11) & ", " &_ ' stringarr(j,12) Next End Function '---------------- ' Main Function '---------------- 'Removes Existing SCCM_Bitlocker if exists On Error Resume Next Set oLocation = CreateObject("WbemScripting.SWbemLocator") Set oServices = oLocation.ConnectServer(, "root\cimv2") set oNewObject = oServices.Get("SCCM_BitLocker") oNewObject.Delete_ 'Again just in case Set oServices = oLocation.ConnectServer(, "root\cimv2\SMS") Set oNewObject = oServices.Get("SCCM_BitLocker") oNewObject.Delete_ On Error Goto 0 dim runtime getData WhShell, numVolumes, gstrObjects createWMI gstrObjects, numVolumes, runtime
- Still on the ‘Create Setting’ window, click the “Compliance Rules” tab.
- On the ‘Compliance Rules’ tab, click ‘New’.
- On the ‘Create Rule’ screen, enter the following information then click ‘OK’ to save the setting:
Name: Script Return State Rule Type: Existential The setting must comply with the following rule: The specified script does not return any values Noncompliance severity for reports: Warning
- Still on the ‘Create Setting’ window, again click “New” to create another settings.
- On the ‘Create Rule’ screen, enter the following information then click ‘OK’ to save the setting:
>Name: WMI Updated
Rule Type: Value
The value returned by the specified script: ‘Begins with’
The following values: WMI
Noncompliance severity for reports: Warning - On the ‘Create Setting’ screen, click ‘OK’ to save the new setting.
- On the ‘Create Configuration Item Wizard’ window, on the ‘Settings’ screen, click ‘Next’.
- On the ‘Compliance Rules’ screen, click ‘Next’.
- On the ‘Summary’ screen, click ‘Next’.
- On the ‘Completion’ screen, click ‘Close’.
Configuration Baseline
- Open SCCM console on a site server.
- Navigate to Assets and Compliance -> Compliance Settings -> Configuration Baselines.
- Click the ‘Create Configuration Baseline’ button on the ribbon.
- On the ‘Create Configuration Baseline’ screen, enter the following information then click ‘OK’:
Name: Bitlocker Information Escrow Configuration Data: Add -> Bitlocker Informtion
- Right click the new Baseline and choose ‘Deploy’.
- On the ‘Deploy Configuration Baselines’ screen perform the following operations then click ‘OK’ to deploy.
- Choose a collection
- Change the schedule to ‘Simple Schedule’
- Change the field ‘Run Every’ to 1 Days.
Adding the Hardware Inventory Classes
First, we need to add the WMI class SCCM_Bitlocker to the CAS by running the compliance script manually. Then, we can add the class to hardware inventory via the SCCM GUI.
- RDP to the CAS server.
- Open notepad and save the script detailed in a previous step as C:\Install_Files\bitlocker-wmi-provider.vbs.
- Open a command prompt as Administrator and run the following command:
cscript C:\Install_Files\bitlocker-wmi-provider.vbs
- Open a powershell script and run the following command. It should output bitlocker information for the CAS server (probably indicating that bitlocker is diabled). If you get no response back, then there is a problem with the bitlocker-wmi-provider script.:
gwmi sccm_bitlocker
- Open SCCM console on the CAS.
- Navigate to Administration -> Client Settings.
- Right click on the ‘Default Client Settings’ and select ‘Properties’.
- Select ‘Hardware Inventory’ from the left pane.
- Click the button labeled ‘Set Classess …’.
- On the ‘Hardware Inventory Classes’ window click the button labeled ‘Add’.
- On the ‘Add Hardware Inventory Class’ window click the button labeled ‘Connect’.
- On the ‘Connect to Windows Management Instrumentation (WMI)’ window, enter the name of your cas server and click ‘connect’.
- On the ‘Add Hardware Inventory Class’ window, search for the class named SCCM_Bitlocker and check the box next to the class, then click ‘OK’.
- On the ‘Hardware Inventory Classes’ window, make sure that the SCCM_Bitlocker class is selected, then click ‘OK’. The newly added class should be at the top of the list.
- A new class should appear named ‘SCCM_Bitlocker’. Check the next to this new class then click ‘OK’.
You can confirm that the data is inventoried by right-clicking a device and choosing ‘Start’ -> ‘Resource Explorer’.
Further Reading
The following links were pages that gave me a lot of help in getting this process rolling.
- “BitLocker Information via Hardware Inventory“ was referenced at the top but it is the basis for most of this project as it gave the modification of the .mof file and the basis for the script that is doing the WMI namespace modification.
- “SCCM 2012 – Customize / Extend Hardware Inventory” provided a lot of the basic understanding about how all of this works and how to do modifications of the configuration.mof.
- “Compliance Settings in System Center Configuration Manager 2012” didn’t really have anything related to BitLocker, but it provide some sweet understanding into the use of the compliance settings.
- “How to backup recovery information in AD after BitLocker is turned ON in Windows 7” gave me the last piece I needed to finish my script. That was the understanding of how to get all the key protector information into SCCM, because the original script wasn’t getting it.