Query for Bitlocker Status

(imported topic written by jclark91)

Does anyone know a way to use the relevance language to determine if MicroSoft Bitlocker is enable on an endpoint? I would like to be able to develop a retrieved property to determine if Bitlocker is enabled and aslo to determine the encryption status of the encrypted drive (i.e. % encrypted, encryption in progress, decryption in progress). Any suggestions are welcome. Bitlocker documentation suggests a wmi interface Win32_EncryptableVolume. I tried the relevance debugger with the query:

Selects “* from Win32_EncryptableVolume” of wmi

and received the error: The expression could not be evaluated: Windows Error: unknown error 0x80041010

(imported comment written by BenKus)

Hey John,

Try this to get started:

q: Selects “* from Win32_EncryptableVolume” of wmi "root\CIMv2\Security\MicrosoftVolumeEncryption"
A: DeviceID=\?\Volume{4c536488-d01d-11db-87f9-806e6f6e6963}
A: DriveLetter=D:
A: PersistentVolumeID=

Here is a reference page:

http://msdn.microsoft.com/en-us/library/aa376483(VS.85).aspx

Note that this query took a while on my system (2 seconds) and I have no idea what sort of resources it uses so be very cautious putting this in a Fixlet or property until you feel like you have tested it well…

Ben

(imported comment written by SystemAdmin)

jClark/Ben,

Can either of you confirm that this was functional? I need to do the same thing that jclark does.

-J

(imported comment written by nberger91)

is there a way to restrict this to the system drive only ?

Error refers to both encrypted c:\ drive and inserted bitlocker encrypted usb thumb drive, or any better way of pulling this ?

q: if (name of operating system = “Win7”) then if (exists wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”) then ((if ((string value of (selects “DriveLetter from Win32_EncryptableVolume” of wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”)) as lowercase contains “C” AND ((string value of (selects “ProtectionStatus from Win32_EncryptableVolume” of wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”)) = “1”) ) then “BitLocker Encrypted” ELSE “BitLocker Problematic”) as string) else “Unknown” else “N/A”

E: Singular expression refers to non-unique object.

(imported comment written by BenKus)

Hey Nick,

The query is failing because it is returning multiple results for the different drives but you are only asking for a single value (“string value of …”)

You can re-craft it with an “exists … whose …” clause to handle the multiple results…

Try this:

q: if (name of operating system = “Win7”) then if (exists wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”) then ((if (exists (select objects “ProtectionStatus, DriveLetter from Win32_EncryptableVolume” of wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”) whose ((integer value of property “ProtectionStatus” of it = 1 AND string value of property “DriveLetter” of it = “C:”) )) then “BitLocker Encrypted” ELSE “BitLocker Problematic”) as string) else “Unknown” else “N/A”

Ben

(imported comment written by nberger91)

I have logic succesfully detecting Bitlocker encryption status of the system drive, and now would like to expand the code to include status for secondary ‘fixed’ drives and/or partitions by joining the following statements, -

Q: if (name of operating system = “Win7”) AND exists service “BDESVC” whose (state of it = “Running”) AND (exists wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”) then ((if (exists (select objects “ProtectionStatus, DriveLetter from Win32_EncryptableVolume” of wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”) whose ((integer value of property “ProtectionStatus” of it = 1 AND string value of property “DriveLetter” of it = “C:”) )) then “BitLocker Encrypted” ELSE “N/A”) as string) else “N/A”

A: BitLocker Encrypted

Q: exists drive whose (name of it != name of drive of system folder AND type of it = “DRIVE_FIXED”)

A: True

Im getting ‘E: A singular expression is required.’ when pluralising drive to drives

Q: if (name of operating system = “Win7”) then if (exists wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”) then ((if ((string value of (selects “ProtectionStatus from Win32_EncryptableVolume” of wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”)) = “1”) of drives whose (type of it = “DRIVE_FIXED”) then “BitLocker Encrypted” ELSE “BitLocker Problematic”) as string) else “Unknown” else “N/A”

(imported comment written by BenKus)

Does this work?

Q: if (name of operating system = “Win7”) AND exists service “BDESVC” whose (state of it = “Running”) AND (exists wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”) then ((if (exists (select objects “ProtectionStatus, DriveLetter from Win32_EncryptableVolume” of wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”) whose ((integer value of property “ProtectionStatus” of it = 1 AND exists (drive (string value of property “DriveLetter” of it)) whose (name of it != name of drive of system folder AND type of it = “DRIVE_FIXED”)) )) then “BitLocker Encrypted” ELSE “N/A”) as string) else “N/A”

Ben

(imported comment written by nberger91)

Getting there, still need some help please :slight_smile:

I need to return “N/A” if any of the fixed drives

excluding

Q: are unenecrypted (failing the wmi check), currently the logic below returns “N/A” when both the system disk and secondary partition are encrypted, which i would have expected see ‘BitLocker Encrypted’

Q: if (name of operating system does not contain “Win”) then “Non Windows” ELSE if (name of operating system = “Win7”) AND exists service “BDESVC” whose (state of it = “Running”) AND (exists wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”) then ((if (exists (select objects “ProtectionStatus, DriveLetter from Win32_EncryptableVolume” of wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”) whose ((integer value of property “ProtectionStatus” of it = 1 AND string value of property “DriveLetter” of it = names of drives whose (type of it = “DRIVE_FIXED” AND name of it != “Q:”)) )) then “BitLocker Encrypted” ELSE “N/A”) as string) else “N/A”

E: A singular expression is required.

Q: names of drives whose (type of it = “DRIVE_FIXED” AND name of it != “Q:”)

A: C:

A: W:

Q: name of drive whose (type of it = “DRIVE_FIXED” AND name of it != “Q:”)

A: C:

E: Singular expression refers to non-unique object.

(imported comment written by NoahSalzman)

This is the part that doesn’t work. “String value” is a singular thing. You cant say “this single thing”

is

the same as two things (the drive letters).

string value of property “DriveLetter” of it = names of drives whose (type of it = “DRIVE_FIXED” AND name of it != “Q:”)

Here is the simplified version of what that statement boils down to:

Q: “A” = (“B”;“C”)

E: A singular expression is required.

One way to solve this is:

Q: set of (“B”;“C”) contains “A”

A: False

Q: set of (“B”;“C”;“A”) contains “A”

A: True

So, without running it through the debugger, I believe your statement becomes:

set of (names of drives whose (type of it = “DRIVE_FIXED” AND name of it != “Q:”)) contains (string value of property “DriveLetter” of it)

(imported comment written by nberger91)

HELP HELP … PLEASE … (this is driving me crazy)

Why wont this iterate through all fixed drives ? Currently if 1 fixed drive (except system drive and Q: is detected and encrypted, the statement returns All Fixed Drives BitLocker Encrypted and does not continue to iterate through the other fixed drives.

Results -

System Drive - returns N/A (works as expected)

Q: Drive - returns N/A (works as expected)

Fixed Drive 1 Encrypted - returns All Fixed Drives BitLocker Encrypted (works as expected)

Fixed Drive 1 Encrypted, Fixed Drive 2 Unencrypted - returns All Fixed Drives BitLocker Encrypted … ??? (expected result N/A)

if (name of operating system does not contain “Win”) then “Non Windows” ELSE if (name of operating system = “Win7”) AND exists service “BDESVC” whose (state of it = “Running”) AND exists (names of drives whose (name of it != “Q:” AND name of it != name of drive of system folder AND type of it = “DRIVE_FIXED”)) AND (exists wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”) then ((if (exists (select objects “ProtectionStatus, DriveLetter from Win32_EncryptableVolume” of wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”) whose ((integer value of property “ProtectionStatus” of it = 1 AND set of (names of drives whose (name of it != name of drive of system folder AND name of it != “Q:” AND type of it = “DRIVE_FIXED”)) contains (string value of property “DriveLetter” of it)))) then “All Fixed Drives BitLocker Encrypted” ELSE “N/A”) as string) else “N/A”

(imported comment written by JackCoates91)

I don’t have multiple bitlocker drives so it’s hard to test… but you might need to provide a list of possible drive letters to test, like in this post: http://forum.bigfix.com/viewtopic.php?pid=27293

(imported comment written by SystemAdmin)

I was going to try taking a look at this, but haven’t had any time. From what I can tell, because you need to compare one ‘set’ of data (from the wmi query) and one set of drive letters/encryption status, I don’t think you can just try matching like for like as you are doing it.

All the single queries work, because they won’t fall foul of trying to use multiple results of drive letters attempting to do a boolean comparison. The minute you think you are doing iteration (or trying to), you’ll probably need to rethink how you are gettting your results.

I would try creating a long list that has all the elements linked together “(drive, enc. status),(drive,enc. status)” and once you have the list, you merely need to check whether there are more than 0 that have a status of n. Or if you do the filtering first, whether there are any in the list. (That is, I don’t think you care about how many there are, just whether there are 1 or more that aren’t encrypted.)

I’ll try and see if I can find a sample of status values to use in place of yours and perhaps I can come up with something.

-Jim

(imported comment written by NoahSalzman)

I may have led you astray a little, sorry.

Your script currently checks that

any

drive, that is not system or Q:, is encrypted. You want

all

, of course.

So, you have entry checks at the start (which I’ll ignore in the example below) to make sure we have drives that are not Q and not system. Given that, here is what the desired structure of your script should look like when we are done:

IF

Entry checks are true

THEN

IF
Is it true that ALL the drives I’m interested in are encrypted?
THEN
"Yes, they are ALL encrypted"
ELSE
"NA – I checked, and at least one of them was not encrypted"

ELSE

“NA – The entry checks showed that there were no drives to check”

The part in bold currently is this:

if ( exists ( select objects 
"ProtectionStatus, DriveLetter from Win32_EncryptableVolume" of wmi 
"root\CIMv2\Security\MicrosoftVolumeEncryption" ) whose ( ( integer value of property 
"ProtectionStatus" of it = 1 AND set of ( names of drives whose ( name of it != name of drive of system folder AND name of it != 
"Q:" AND type of it = 
"DRIVE_FIXED" ) ) contains ( string value of property 
"DriveLetter" of it ) ) ) ) then 
"All Fixed Drives BitLocker Encrypted" ELSE 
"N/A"

Basically: give me a list of drives from WMI, check them one by one (iterate) against the list of all drives that are not Q and not system. The “whose” will return true if any of the items from the WMI query match.

What we really want is:

  1. Create a set of drives from WMI that have (“ProtectionStatus” of it = 1)

  2. Subtract Q and the system drive from that set

  3. If our result is 0 after that subtraction then all of the drives we are interested in are encrypted (or are system or Q)

The basic idea is this, if your list of unencrypted drives were A, C, and Q:

Q: number of elements of (set of (“A:”;“C:”;“Q:”) - set of (“Q:”; name of drive of system folder))

A: 1

I don’t have bitlocker turned on, so I can’t test this properly. The first thing to do is get our list of unencrypted drives, I’m hoping that this is what we need:

string value of property “DriveLetter” of (select objects “ProtectionStatus, DriveLetter from Win32_EncryptableVolume” whose (integer value of property “ProtectionStatus” of it = 1 ) of wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”)

If you get a list of drives from this relevance then you know you have unencrypted drives that are not Q or system:

set of (string value of property “DriveLetter” of (select objects “ProtectionStatus, DriveLetter from Win32_EncryptableVolume” whose (integer value of property “ProtectionStatus” of it = 1 ) of wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”)) - set of (“Q:”; name of drive of system folder)

Putting it all together:

if ( name of operating system does not contain 
"Win" ) then 
"Non Windows" ELSE 

if ( name of operating system = 
"Win7" ) AND exists service 
"BDESVC" whose ( state of it = 
"Running" ) AND exists ( names of drives whose ( name of it != 
"Q:" AND name of it != name of drive of system folder AND type of it = 
"DRIVE_FIXED" ) ) AND ( exists wmi 
"root\CIMv2\Security\MicrosoftVolumeEncryption" ) then ( ( 

if ( exists ( select objects 
"ProtectionStatus, DriveLetter from Win32_EncryptableVolume" of wmi 
"root\CIMv2\Security\MicrosoftVolumeEncryption" ) and not ( number of elements of ( set of ( string value of property 
"DriveLetter" of ( select objects 
"ProtectionStatus, DriveLetter from Win32_EncryptableVolume" whose ( integer value of property 
"ProtectionStatus" of it = 1 ) of wmi 
"root\CIMv2\Security\MicrosoftVolumeEncryption" ) ) - set of ( 
"Q:"; name of drive of system folder ) ) > 0 ) ) then 
"All Fixed Drives BitLocker Encrypted" ELSE 
"N/A" ) as string ) 

else 
"N/A"

Same thing with indentation removed for your convenience:

if (name of operating system does not contain 
"Win") then 
"Non Windows" ELSE 

if (name of operating system = 
"Win7") AND exists service 
"BDESVC" whose (state of it = 
"Running") AND exists (names of drives whose (name of it != 
"Q:" AND name of it != name of drive of system folder AND type of it = 
"DRIVE_FIXED")) AND (exists wmi 
"root\CIMv2\Security\MicrosoftVolumeEncryption") then ((

if (exists (select objects 
"ProtectionStatus, DriveLetter from Win32_EncryptableVolume" of wmi 
"root\CIMv2\Security\MicrosoftVolumeEncryption") and not (number of elements of (set of (string value of property 
"DriveLetter" of (select objects 
"ProtectionStatus, DriveLetter from Win32_EncryptableVolume" whose (integer value of property 
"ProtectionStatus" of it = 1) of wmi 
"root\CIMv2\Security\MicrosoftVolumeEncryption")) - set of (
"Q:"; name of drive of system folder)) > 0)) then 
"All Fixed Drives BitLocker Encrypted" ELSE 
"N/A") as string) 

else 
"N/A"

EDIT: Forgot to add the “not” in front of the element count, just fixed that.

(imported comment written by nberger91)

With thanks to Noah and Ben I got this working. Anyone have an idea how to filter off removable drives that present themselves to the operating system as fixed disks ?

Additionally, (names of drives whose ( type of it = “DRIVE_FIXED” )) is picking up network drives on some Win7 hosts ?

Q: if (name of operating system does not contain “Win”) then “Non Windows” ELSE if (name of operating system = “Win7”) AND exists service “BDESVC” whose (state of it = “Running”) AND (exists wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”) then (if (it contains set of (names of drives whose (name of it != “Q:” AND type of it = “DRIVE_FIXED” AND exists (string values whose (it as lowercase contains “Fixed” as string as lowercase) of selects “MediaType FROM Win32_DiskDrive” of wmi) ))) then “BitLocker Encrypted” else "BitLocker Unencrypted Drive Detected - " & concatenation “,” of elements of (set of (names of drives whose (name of it != “Q:” AND type of it = “DRIVE_FIXED” AND exists (string values whose (it as lowercase contains “Fixed” as string as lowercase) of selects “MediaType FROM Win32_DiskDrive” of wmi) ))- it)) of set of (string values of properties “DriveLetter” of (select objects “ProtectionStatus, DriveLetter from Win32_EncryptableVolume” whose (integer value of property “ProtectionStatus” of it = 1) of wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”)) else “N/A”

A: BitLocker Encrypted

(imported comment written by mmcgrew91)

I’m just simply trying to see if C: is encrypted but i’m having trouble. I noticed that the main statement I want is not working for some reason, any ideas? this is on vista enterprise.

q: select objects “ProtectionStatus, DriveLetter from Win32_EncryptableVolume” of wmi “root\CIMv2\Security\MicrosoftVolumeEncryption”

E: The expression could not be evaluated: Windows Error: Invalid query

(imported comment written by NoahSalzman)

That is WMI complaining at you. Can you try it on another machine or two? Are you certain the machine has Bitlocker running?

(imported comment written by mmcgrew91)

Yes, this machine is protected by bitlocker with a boot pin. I ran it on another vista enterprise system that has bitlocker but not encrypted (it would need to work on this system too because i want to tell when bitlocker is not enabled) with the same results. I’ll try it on a couple more tomorrow but i don’t think i’m going to get different results.

(imported comment written by nberger91)

this wmi doesnt work for vista …

(imported comment written by mmcgrew91)

:’(

Is there any alternative way to detect the bitlocker status in vista through relevance?

I could hack together some action that uses manage-bde.wsf but I don’t want to have to run an action on all of our computers, i would much rather use relevance.

Thanks!

(imported comment written by nberger91)

This wont return BitLocker status, but will return whether BitLocker is installed/initiated.

(name of operating system = “WinVista”) AND exists files whose (name of it contains “BdeHdCfg.exe”) of folders “BitLocker” of folders (“Program Files”;“Program Files (x86”) of folder (name of drive of system folder)