PowerShell:为自定义输出排序驱动器加密状态

时间:2017-05-03 14:46:33

标签: arrays powershell sorting

我试图获取Windows系统上所有驱动器的加密状态,并在自定义格式化输出中对该列表进行排序。我需要这个,因为输出是去Nagios服务器的;它弄乱了Get-BitLockerVolume标准输出的格式,并且太长了。

这是我到目前为止所拥有的。我试图以这样的方式对输出进行排序,即首先列出系统驱动器并给出安装点(驱动器号)以及百分比。

[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
    }
}

例如,我想要的输出是:

  

C :( OperatingSystem)为100%,D :(数据)为0%。

我实际上最终得到的是:

  

C:D :(操作系统数据)100 0%,C:D :(操作系统数据)100 0%,

我确实尝试过对#34; How to sort a Multi Dimensional Array in Powershell"的回答。测试一下,评论我上面提到的for块并输入:

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

吐出这个错误:

  

无法索引到空数组。   在C:****************。ps1:142 char:3

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

我做错了什么?有什么建议吗?

提前非常感谢!

1 个答案:

答案 0 :(得分:1)

试试这个:

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
    }
}

您没有使用For循环中的$i来访问集合中的特定索引(我已将[$ i]添加到您的每个集合变量中)。您还使用了一个名为$DriveIndex的变量,它从未填充过,我认为这也需要与$i进行比较,但逻辑也是永远不会成为真的,因为For循环将在之前结束它是如此(所以我将逻辑改为($i -eq ($DriveTypes.Count - 1))

这是一个更整洁的版本,我认为也会得到相同的结果:

$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 ',$','.' }
  • 对您想要访问的三个属性使用单个变量,而不是将它们放入不必要的单独变量中。
  • 使用ForEach-Object循环通过特殊标记$_访问该集合中的每个项目(及其属性)。
  • 使用单个双引号字符串进行输出,通过子表达式运算符$()访问对象/属性。
  • 在每行的末尾加上一个逗号,但是在ForEach的结尾处,使用正则表达式替换该行末尾的逗号(正则表达式:$令牌)。 / LI>

这两组代码都未经过测试,因此可能需要进行调整。