1

I'm trying to get the encryption status of all drives on a Windows system and sort that list in a custom formatted output. I need this because the output is going to a Nagios server; it messes up the formatting of the standard output for Get-BitLockerVolume and is too long.

Here's what I have so far. I'm trying to sort the output in such a manner that the system drive is listed first and gives the mount point (drive letter) along with the percentage.

[array]$DriveTypes = Get-BitLockerVolume | Sort-Object VolumeType | Select-Object VolumeType
[array]$DriveMounts = Get-BitLockerVolume | Sort-Object VolumeType | Select-Object MountPoint
[array]$WDEPercent = Get-BitLockerVolume | Sort-Object VolumeType | Select-Object EncryptionPercentage

for ($i = 0; $i -lt $DriveTypes.Count; $i++) {
    if ($DriveIndex -eq $DriveTypes.Count) {
        $TextDriveListing = $TextDriveListing + $DriveMounts.MountPoint+" ("+$DriveTypes.VolumeType+") at "+$WDEPercent.EncryptionPercentage+"%."
    }
    else {
        $TextDriveListing = $TextDriveListing + $DriveMounts.MountPoint+" ("+$DriveTypes.VolumeType+") at "+$WDEPercent.EncryptionPercentage+"%, "
    }
    if ($WDEPercent.EncryptionPercentage -lt $ReqValue) {
        $NoEncryptFlag = 1
    }
}

My desired output, for example, is this:

C: (OperatingSystem) at 100%, D: (Data) at 0%.

What I actually end up with is this:

C: D: (OperatingSystem Data) at 100 0%, C: D: (OperatingSystem Data) at 100 0%,

I did try something deriving from an answer to "How to sort a Multi Dimensional Array in Powershell" to test it out, commenting out my aforementioned for block and putting in:

$ListDrives | ForEach-Object {
  Get-BitLockerVolume @{
    MountPoint = $_[0]
    EncryptionPercentage = $_[1]
  }
} | Sort-Object VolumeType
Write-Host $ListDrives

That spit out this error:

Cannot index into a null array. At C:****************.ps1:142 char:3

  • Get-BitLockerVolume @{
  • ~~~~~~~~~~~~~~~~~~~~~~
    • CategoryInfo : InvalidOperation: (:) [], RuntimeException
    • FullyQualifiedErrorId : NullArray

What am I doing wrong? Any suggestions?

Thanks so much in advance!

1
  • Don't you want to use $i inside your for loop? Commented May 3, 2017 at 15:00

1 Answer 1

1

Try this:

for ($i = 0; $i -lt $DriveTypes.Count; $i++) {
    if ($i -eq ($DriveTypes.Count - 1)) {
        $TextDriveListing = $TextDriveListing + $DriveMounts[$i].MountPoint+" ("+$DriveTypes[$i].VolumeType+") at "+$WDEPercent[$i].EncryptionPercentage+"%."
    }
    else {
        $TextDriveListing = $TextDriveListing + $DriveMounts[$i].MountPoint+" ("+$DriveTypes[$i].VolumeType+") at "+$WDEPercent[$i].EncryptionPercentage+"%, "
    }
    if ($WDEPercent[$i].EncryptionPercentage -lt $ReqValue) {
        $NoEncryptFlag = 1
    }
}

You weren't using the $i from your For Loop to access specific indexes in your collections (i've added [$i] to each of your collection variables to do so). You were also using a variable called $DriveIndex that was never populated and I think this needed to be comparing to $i also, however the logic was also one that would never be true because the For loop would end before it was so (so i've changed the logic to ($i -eq ($DriveTypes.Count - 1)).

Here's a tidier version that I think also gets you the same result:

$TextDriveListing = ''
$Drives = Get-BitLockerVolume | Sort-Object VolumeType | Select VolumeType,MountPoint,EncryptionPercentage
$Drives | ForEach-Object { 

    $TextDriveListing += "$($_.MountPoint) ($($_.VolumeType)) at $($_.EncryptionPercentage)%,"
    If ($_.EncryptionPercentage -lt $ReqValue) { $NoEncryptFlag = 1 }

} -End { $TextDriveListing -Replace ',$','.' }
  • Uses a single variable for the three properties you wanted to access, rather than putting them in to separate variables which was unnecessary.
  • Uses a ForEach-Object loop to access each item (and their properties) in that collection via the special token $_.
  • Uses a single double quoted string for output, with the object/properties accessed via the subexpression operator $().
  • Puts a comma on the end of each line, but then at the End of the ForEach, uses regex to replace the comma at the end of the line (regex: $ token) with a full stop.

Both sets of code are untested, so may need tweaking.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.