I am sure you more less all know by now that I work in Switzerland. What an amazing country i have to say! The mountains, the chocolate, the watches, the nature, and… their awesome army knifes.
These knifes are really super cool! They combine so many different funtionalities in one, and it is so small that you can carry it everywhere with you! While camping, hiking etc…
It is super handy! Need to open a can?
–> Use the swiss army knife.
Went out for a lunch in the park with your girl friend/boy friend and need to open the bottle of Bordeaux Saint-emilion you specially bought for the occasion?
–> Use the Swiss army knife.
Need to fix your shirt fastly before attending this job interview?
–> again, Swiss army knife!
You got it, you can do everything with it But what does all of that have to do with PowerShell ?
Well, I have recently been developing a powershell script for bitlocker remediation purposes. The knowledge I build from it, made me realize that nothing really existed in powershell to manage the bitlocker parts.
I decided to create a powershell bitlocker encryption tool that gives any admin / system engineer to manage the bitlocker encryption and TPM settings from a machine. The powershell bitlocker encryption tool function aka “BitlockerSAK“.
The BitlockerSAK function is a big Swiss army knife that is extremely helpful to manage Powershell Bitlocker encryption / remediation automation for Windows systems (especially prior to Windows 8.1). It contains all the functionality that you would expect to be there to help you manage your bitlocker environment.
Download powershell BitlockerSAK:
BitlockerSAK is free, and is available for download on Technet. Once downloaded, please think to rate the script by clicking the stars, and do not hesitate to give me feedback concerning the tool.
What can the powershell bitlocker Swiss army knife concretely do?
This powershell bitlocker encryption tool “BitlockerSAK” will enable the automation of the bitlocker encryption and TPM operations that need to be done on Microsoft Windows (R) machines through PowerShell.
The following actions can be done with with BitlockerSAK:
- Identify if the TPM is activated.
- Identify if the TPM is enabled.
- Identify it the TPM is owned.
- Identify if the TPM ownership is allowed.
- Get the current bitlocker protection status.
- Start the bitlocker drive encryption. (with Pin).
- Resume a bitlocker encryption that is in paused state.
- Return the current bitlocker encryption percentage of the drive.
- Return the bitlocker key protector id’s of the machine.
- Return the encryption method of the encrypted drive.
- Return the Key protector methods.
Help and examples can be easily found by using the integrated help system.
How does the PowerShell Bitlocker SAK work?
The windows powershell Bitlocker SAK tool is based on 3 different technologies: Powershell bitlocker wmi.
The combination of Powershell bitlocker and WMI brings us the possibility to manage the complete bitlocker and TPM activities using a simple windows powershell tool; BitlockerSAK.
As mentioned above, the BitlockerSAK does not work only for Powershell and bitlocker, but you can also use BitlockerSAK to work on the different TPM actions. Indeed, using the same combination as for bitlocker (powershell tpm wmi), bitlockerSAK will allow you to manage your TPM with powershell just like you would have done with manageBDE.exe.
Powershell bitlocker wmi, Powershell tpm wmi are the key features of the BitlockerSAK.
BitlockerSAK usage examples:
How to get the current Bitlocker encryption status with Powershell?
Simply call the BitlockerSAK function without any parameter, and it will return an object that with the current encryption status:
BitlockerSAK returns an object which can be integrated into existing script logic to identify and force the encryption.
How to remediate bitlocker drives that are not encrypted?
It is possible to use the BitlockerSAK in logic in order to remediate non-encrypted bitlocker drives. Here under you can see an example:
1
2
3
4
|
$EncryptionState = (BitlockerSAK -Getencryptionstatus).encryptionstate
if ($EncryptionState -eq “Fullydecrypted”)
{ BitlockerSAK -Encrypt }
else{ write-host “Bitlocker is currently in $
|
1
|
(BitlockerSAK -Getencryptionstatus).encryptionstate
|
1
|
state.” }
|
BitlockerSAK help and integrated examples:
More help can be found using the following command:
1
|
Get-help BitlockerSAK -Full
|
To see examples of the powershell bitlocker encryption function bitlockerSAK, type this:
1
|
Get-help BitlockerSAK -Examples
|
Download the bitlocker Swiss army knife:
The powershell bitlocker tool can be downloaded directly from Technet, or it can be copy pasted from the listing below.
Listing:
The listing of the latest version of the BitlockerSAK is available here below. You can copy past this function directly into one of your scripts or module and start using it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
|
Function BitLockerSAK {
<#
.SYNOPSIS
Get and set Bitlocker related information.
.DESCRIPTION
Based on WMI classes, this function can achiev the following tasks :
--TPM operations---
-TPM activation state.
-If the TPM is enabled or not.
-If a TPM OwnerShip is Allowed.
-If the TPM is currently owned.
-The possibility to take the ownerShip
--Encryption possibilities ---
- Retrieves the current encryption method.
- Get the current protection status.
- The current protection state.
- The possibility to encrypt a Drive.
- The possibility to Resume an encryption that has been paused.
- Possibility to return the current protector ID's.
- Possibility to return the current protector type(s).
.PARAMETER isTPMActivated
Returns activation state of the TPM:
Returns true if activated and false if not.
.PARAMETER isTPMEnabled
Returns the enabled state of the TPM:
Returns true if activated and false if not.
.PARAMETER IsTPMOwnerShipAllowed
Returns if the TPM ownership is allowed.
Returns true if allowed, false if not.
.PARAMETER ResumeEncryption
Will resume an paused encryption.
.PARAMETER GetEncryptionState
Returns the current encurrent state in an object as folled :
.PARAMETER GetProtectionStatus
Returns the current protection status. It will return "Protected" if the drive is 100% encrypted, and "Unprotected" if anything else then "100% encrypted".
.PARAMETER Encrypt
Will encrypt a drive.
.PARAMETER TakeOwnerShip
Returns true if allowed, false if not
.PARAMETER pin
Is needed in order to take the ownership and to encrypt the drive.
.PARAMETER IsTPMOwned
Returns true if owned, false if not
.PARAMETER GetProtectorIds
Returns all the protector id's available on the machine.
.PARAMETER GetKeyProtectorType
Returns the type of protector that is currently in use.
.PARAMETER GetEncryptionMethod
REturns the current encryption method that is in use.
.PARAMETER Whatif
Permits to launch this script in "draft" mode. This means it will only show the results without really making generating the files.
.PARAMETER Verbose
Allow to run the script in verbose mode for debbuging purposes.
.EXAMPLE
BitLockerSAK
Returns the current status of the drives.
IsTPMOwned : True
EncryptionMethod : AES_128
IsTPMOwnerShipAllowed : True
IsTPMActivated : True
IsTPMEnabled : True
CurrentEncryptionPercentage : 100
EncryptionState : FullyEncrypted
ProtectorIds : {{FFC19381-6E75-4D1E-94E9-D6E0D3E681FA}, {65AF5A93-9846-47AC-B3B1-D8DE6F06B780}}
KeyProtectorType : {Numerical password, Trusted Platform Module (TPM)}
.EXAMPLE
BitLockerSAK -GetProtectionStatus
Returns the current protection status : Protected or unprotected
.EXAMPLE
BitLockerSAK -GetEncryptionState
CurrentEncryptionProgress is express in percentage.
CurrentEncryptionProgress EncryptionState
------------------------- ---------------
100 FullyEncrypted
.NOTES
-Author: Stephane van Gulick
-Email :
-CreationDate: 13-01-2014
-LastModifiedDate: 16-01-2014
-Version: 1.2
-History:
#0.1 : Created function
#1.1 : 20140901 Added GetProtectorIds
#1.2 : 20140909 Rewrote function
Added GetKeyprotectorType
Added EncryptionMethod
.LINK
Blog:
www.PowerShellDistrict.com
.LINK
Technet page:
http://gallery.technet.microsoft.com/Bitlocker-Powershell-swiss-a4777303
#>
[/fusion_builder_column][fusion_builder_column type="1_1" background_position="left top" background_color="" border_size="" border_color="" border_style="solid" spacing="yes" background_image="" background_repeat="no-repeat" padding="" margin_top="0px" margin_bottom="0px" class="" id="" animation_type="" animation_speed="0.3" animation_direction="left" hide_on_mobile="no" center_content="no" min_height="none"][cmdletBinding()]
Param(
[Switch]$IsTPMActivated,
[Switch]$IsTPMEnabled,
[Switch]$IsTPMOwnerShipAllowed,
[Switch]$ResumeEncryption,
[Switch]$GetEncryptionState,
[Switch]$GetProtectionStatus,
[switch]$Encrypt,
[Parameter(ParameterSetName="OwnerShip")][switch]$TakeOwnerShip,
[Parameter(ParameterSetName="OwnerShip")][int]$pin,
[switch]$IsOwned,
[Switch]$GetProtectorIds,
[switch]$GetEncryptionMethod,
[string]$DriveLetter="C:",
[switch]$GetKeyProtectorType
)
Begin {
$Tpm = Get-WmiObject -Namespace ROOTCIMV2SecurityMicrosoftTpm -Class Win32_Tpm
}
Process{
switch ($PSBoundParameters.keys){
"IsTPMActivated"{$return = $tpm.IsActivated().isactivated;break}
"IsTPMEnabled"{$return = $tpm.IsEnabled().isenabled;break}
"IsTPMOwnerShipAllowed"{$return = $tpm.IsOwnerShipAllowed().IsOwnerShipAllowed;break}
"IsTPMOwned"{$return = $Tpm.isowned().isowned;break}
"GetEncryptionState"{
write-verbose "Getting the encryptionstate of drive $($driveletter)"
#http://msdn.microsoft.com/en-us/library/aa376433(VS.85).aspx
#We only want to work on the C: drive.
$EncryptionData= Get-WmiObject -Namespace ROOTCIMV2SecurityMicrosoftvolumeencryption -Class Win32_encryptablevolume -Filter "DriveLetter = '$DriveLetter'"
$protectionState = $EncryptionData.GetConversionStatus()
$CurrentEncryptionProgress = $protectionState.EncryptionPercentage
switch ($ProtectionState.Conversionstatus){
"0" {
$Properties = @{'EncryptionState'='FullyDecrypted';'CurrentEncryptionProgress'=$CurrentEncryptionProgress}
$Return = New-Object psobject -Property $Properties
}
"1" {
$Properties = @{'EncryptionState'='FullyEncrypted';'CurrentEncryptionProgress'=$CurrentEncryptionProgress}
$Return = New-Object psobject -Property $Properties
}
"2" {
$Properties = @{'EncryptionState'='EncryptionInProgress';'CurrentEncryptionProgress'=$CurrentEncryptionProgress}
$Return = New-Object psobject -Property $Properties
}
"3" {
$Properties = @{'EncryptionState'='DecryptionInProgress';'CurrentEncryptionProgress'=$CurrentEncryptionProgress}
$Return = New-Object psobject -Property $Properties
}
"4" {
$Properties = @{'EncryptionState'='EncryptionPaused';'CurrentEncryptionProgress'=$CurrentEncryptionProgress}
$Return = New-Object psobject -Property $Properties
}
"5" {
$Properties = @{'EncryptionState'='DecryptionPaused';'CurrentEncryptionProgress'=$CurrentEncryptionProgress}
$Return = New-Object psobject -Property $Properties
}
default {
write-verbose "Couldn't retrieve an encryption state."
$Properties = @{'EncryptionState'=$false;'CurrentEncryptionProgress'=$false}
$Return = New-Object psobject -Property $Properties
}
}
}
#Change C: drive (add more)
"ResumeEncryption"{
write-verbose "Resuming encryption"
$ProtectionState = Get-WmiObject -Namespace ROOTCIMV2SecurityMicrosoftvolumeencryption -Class Win32_encryptablevolume -Filter "DriveLetter = 'C:'"
$Ret = $protectionState.ResumeConversion()
$ReturnCode = $ret.ReturnValue
switch ($ReturnCode){
("0"){$Message = "The Method Resume Conversion was called succesfully."}
("2150694912"){$message = "The volume is locked"}
default {$message = "The resume operation failed with an uknowned return code."}
}
$Properties = @{'ReturnCode'=$ReturnCode;'ErrorMessage'=$message}
$Return = New-Object psobject -Property $Properties
}
"GetProtectionStatus"{
#http://msdn.microsoft.com/en-us/library/windows/desktop/aa376448(v=vs.85).aspx
$ProtectionState = Get-WmiObject -Namespace ROOTCIMV2SecurityMicrosoftvolumeencryption -Class Win32_encryptablevolume -Filter "DriveLetter = 'C:'"
write-verbose "Gathering BitLocker protection status infos."
switch ($ProtectionState.GetProtectionStatus().protectionStatus){
("0"){$return = "Unprotected"}
("1"){$return = "Protected"}
("2"){$return = "Uknowned"}
default {$return = "NoReturn"}
}
}
"Encrypt"{
#http://msdn.microsoft.com/en-us/library/windows/desktop/aa376432(v=vs.85).aspx
$ProtectionState = Get-WmiObject -Namespace ROOTCIMV2SecurityMicrosoftvolumeencryption -Class Win32_encryptablevolume -Filter "DriveLetter = 'C:'"
write-verbose "Launching drive encryption."
$ProtectorKey = $protectionState.ProtectKeyWithTPMAndPIN("ProtectWithTPMAndPIN",$null,$pin)
Start-Sleep -Seconds 3
$NumericalPasswordReturn = $protectionState.ProtectKeyWithNumericalPassword($pin)
$Return = $protectionState.Encrypt()
$returnCode = $return.returnvalue
switch ($ReturnCode) {
("0"){$message = "Operation succesfully started."}
("2147942487") {$message = "The EncryptionMethod parameter is provided but is not within the known range or does not match the current Group Policy setting."}
("2150694958") {$message = "No encryption key exists for the volume"}
("2150694957") {$message = "The provided encryption method does not match that of the partially or fully encrypted volume."}
("2150694942") {$message = "The volume cannot be encrypted because this computer is configured to be part of a server cluster."}
("2150694956") {$message = "No key protectors of the type Numerical Password are specified. The Group Policy requires a backup of recovery information to Active Directory Domain Services"}
default{
$message = "An unknown status was returned by the Encryption action."
}
}
$Properties = @{'ReturnCode'=$ReturnCode;'ErrorMessage'=$message}
$Return = New-Object psobject -Property $Properties
}
"GetProtectorIds"{
$BitLocker = Get-WmiObject -Namespace "Rootcimv2SecurityMicrosoftVolumeEncryption" -Class "Win32_EncryptableVolume"
$return =$BitLocker.GetKeyProtectors("0").volumekeyprotectorID
}
"GetEncryptionMethod"{
$BitLocker = Get-WmiObject -Namespace "Rootcimv2SecurityMicrosoftVolumeEncryption" -Class "Win32_EncryptableVolume"
$EncryptMethod=$BitLocker.GetEncryptionMethod().encryptionmethod
switch ($EncryptMethod){
"0"{$Return = "None";break}
"1"{$Return = "AES_128_WITH_DIFFUSER";break}
"2"{$Return = "AES_256_WITH_DIFFUSER";break}
"3"{$Return = "AES_128";break}
"4"{$Return = "AES_256";break}
"5"{$Return = "HARDWARE_ENCRYPTION";break}
default{$Return = "UNKNOWN";break}
}
}
"GetKeyProtectorType"{
$ProtectorIds = $BitLocker.GetKeyProtectors("0").volumekeyprotectorID
$BitLocker = Get-WmiObject -Namespace "Rootcimv2SecurityMicrosoftVolumeEncryption" -Class "Win32_EncryptableVolume"
#$LastProtectorID = $BitLocker.GetKeyProtectors("0").volumekeyprotectorID[-1]
$return = @()
foreach ($ProtectorID in $ProtectorIds){
$KeyProtectorType = $BitLocker.GetKeyProtectorType($ProtectorID).KeyProtectorType
switch($KeyProtectorType){
"0"{$return += "Unknown or other protector type";break}
"1"{$return += "Trusted Platform Module (TPM)";break}
"2"{$return += "External key";break}
"3"{$return += "Numerical password";break}
"4"{$return += "TPM And PIN";break}
"5"{$return += "TPM And Startup Key";break}
"6"{$return += "TPM And PIN And Startup Key";break}
"7"{$return += "Public Key";break}
"8"{$return += "Passphrase";break}
"9"{$return += "TPM Certificate";break}
"10"{$return += "CryptoAPI Next Generation (CNG) Protector";break}
}
}
}
}#endSwitch
if ($PSBoundParameters.Keys.Count -eq 0){
#Returning info on all drives.
write-verbose "Returning bitlocker main status"
$Tpm = Get-WmiObject -Namespace ROOTCIMV2SecurityMicrosoftTpm -Class Win32_Tpm
$BitLocker = Get-WmiObject -Namespace "Rootcimv2SecurityMicrosoftVolumeEncryption" -Class "Win32_EncryptableVolume"
$TpmActivated = $tpm.IsActivated().isactivated
$TPMEnabled=$tpm.IsEnabled().isenabled
$TPMOwnerShipAllowed=$Tpm.IsOwnershipAllowed().IsOwnerShipAllowed
$TPMOwned=$Tpm.isowned().isowned
$ProtectorIds = $BitLocker.GetKeyProtectors("0").volumekeyprotectorID
$CurrentEncryptionState = BitLockerSAK -GetEncryptionState
$EncryptionMethod= BitLockerSAK -GetEncryptionMethod
$KeyProtectorType = BitLockerSAK -GetKeyProtectorType
$properties= @{ "ComputerName"= $Env:computername;
“IsTPMActivated”= $TpmActivated;
"IsTPMEnabled" = $TPMEnabled;
“IsTPMOwnerShipAllowed”=$TPMOwnerShipAllowed;
"IsTPMOwned"= $TPMOwned;
“ProtectorIds”=$ProtectorIds;
"CurrentEncryptionPercentage"=$CurrentEncryptionState.CurrentEncryptionProgress;
“EncryptionState”=$CurrentEncryptionState.encryptionState;
"EncryptionMethod"=$EncryptionMethod;
“KeyProtectorType”=$KeyProtectorType
}
$Return = New-Object psobject -Property $Properties
}
}
End{
return $return
}
}
|
Leave A Comment