Hello!
I am in the process of learning PowerShell. I am not a professional programmer, and I've had no real training in PowerShell. I will finally be receiving training after the new year, but in the meantime I am trying to get a script working, and have hit a snag.
In our environment, we use BitLocker to encrypt the local drives on all our computers. The drive encryption is one of the last steps of our imaging process, and the recovery key normally gets backed up into AD. I have recently discovered that some computers have been deployed without the BitLocker recovery key getting backed up into AD. I am trying to write a script that will build a list of all computer objects in AD, use that list to build another list of machines missing recovery the key, and output list.
First, I needed to figure out how to identify machines missing the recovery key. Some Googling turned up that the recovery key is stored as a child object of the computer object, and is called msFVE-RecoveryInformation. I put together a small list of machines as my test group. PC2, PC3, PC5, and PC6 are missing the recovery key, and the remaining machines in the test group are not. Remember, I am not a professional programmer, so this probably does not follow all the best practices that a pro would employ. Here is what I came up with, and it works:
$Computers = @("PC1","PC2","PC3","PC4","PC5","PC6","PC7") # Create the list. $NullBitLocker = New-Object System.Collections.Generic.List[System.Object] foreach ($Computer in $Computers) { $BitLockerKey = Get-AdObject -Filter "objectclass -eq 'msFVE-RecoveryInformation'" -SearchBase (Get-ADComputer $Computer).DistinguishedName -Properties msFVE-RecoveryPassword | Select-Object msFVE-RecoveryPassword If ($null -eq $BitLockerKey) { $NullBitLocker.Add($Computer) } } $NullBitLocker
The second task was to figure out how to get a list of machines from AD, which was fairly straight-forward. Our printers are setup as computer objects, and the "-like '*$'" part filters out the printers. This also works, but it would be nice to filter out some OUs, like for handheld scanners that run Windows but are not encrypted with BitLocker.
try{ $ou = "OU=MyOffice,DC=MyCompany,DC=com" $Computers = Get-ADComputer -Filter 'SamAccountName -like "*$"' -SearchBase $ou | Select Name } catch { $error[0].exception.message } $Computers
At this point, I figured that since both pieces of code work in isolation, all I had to do was combine the two. So I produced this script. Note that in the ForEach loop I changed "(Get-ADComputer $Computer)" to "(Get-ADComputer $Computers[$Computer])".
try{ $ou = "OU=MyOffice,DC=MyCompany,DC=com" $Computers = Get-ADComputer -Filter 'SamAccountName -like "*$"' -SearchBase $ou | Select Name } catch { $error[0].exception.message } # Create the list. $NullBitLocker = New-Object System.Collections.Generic.List[System.Object] ForEach ($Computer in $Computers) { $BitLockerKey = Get-AdObject -Filter "objectclass -eq 'msFVE-RecoveryInformation'" -SearchBase (Get- ADComputer $Computers[$Computer]).DistinguishedName -Properties msFVE-RecoveryPassword | Select-Object msFVE-RecoveryPassword If ($null -eq $BitLockerKey) { $NullBitLocker.Add($Computer) } } $NullBitLocker
I figured that would work. Instead, what I get is this:
Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.Int32". At G:\Scripts\PowerShell\BitLocker\BitLocker.ps1:22 char:9+ $BitLockerKey = Get-AdObject -Filter "objectclass -eq 'msFVE- ...+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ CategoryInfo : InvalidArgument: (:) [], RuntimeException+ FullyQualifiedErrorId : ConvertToFinalInvalidCastException
I am stumped as to what I did wrong. Any guidance you can offer in getting these two pieces of code combined and working will be greatly appreciated!
Also, while it is a secondary concern at this point, any tips on how to filter out certain OUs would be appreciated as well.
Thanks in advance for any help that you can offer!
--Tom