【问题标题】:Combine `Get-Disk` info and `LogicalDisk` info in PowerShell (but with formatted output)在 PowerShell 中结合 `Get-Disk` 信息和 `LogicalDisk` 信息(但带有格式化输出)
【发布时间】:2020-11-22 22:52:51
【问题描述】:

这是关于Combine `Get-Disk` info and `LogicalDisk` info in PowerShell?的答案的问题

这是我尝试更改的答案,以按照我想要的方式格式化输出: https://stackoverflow.com/a/31092004/8262102

它需要像下面的代码一样仅以所需的格式适用于多个驱动器。

这是包含我尝试这样做的所有详细信息的代码:

$info_diskdrive_basic = Get-WmiObject Win32_DiskDrive | ForEach-Object {
  $disk = $_
  $partitions = "ASSOCIATORS OF " + "{Win32_DiskDrive.DeviceID='$($disk.DeviceID)'} " + "WHERE AssocClass = Win32_DiskDriveToDiskPartition"
  Get-WmiObject -Query $partitions | ForEach-Object {
    $partition = $_
    $drives = "ASSOCIATORS OF " + "{Win32_DiskPartition.DeviceID='$($partition.DeviceID)'} " + "WHERE AssocClass = Win32_LogicalDiskToPartition"
    Get-WmiObject -Query $drives | ForEach-Object {
      [PSCustomObject][Ordered]@{
        Disk          = $disk.DeviceID
        DiskModel     = $disk.Model
        Partition     = $partition.Name
        RawSize       = '{0:d} GB' -f [int]($partition.Size/1GB)
        DriveLetter   = $_.DeviceID
        VolumeName    = $_.VolumeName
        Size          = '{0:d} GB' -f [int]($_.Size/1GB)
        FreeSpace     = '{0:d} GB' -f [int]($_.FreeSpace/1GB)
      }
    }
  }
}

# Here's my attempt at formatting the output of the code above.

# 1. This trims the dead whitespace from the output.
$info_diskdrive_basic = ($info_diskdrive_basic | Out-String) -replace '^\s+|\s+$', ('')

# 2. I then separate the DiskModel, RawSize, DriveLetter, VolumeName, FreeSpace with the regexp below so this becomes:
# Disk Model, Raw Size, Drive Letter, Volume Name, Free Space
$info_diskdrive_basic = ($info_diskdrive_basic) -replace '(?-i)(?=\B[A-Z][a-z])', (' ')

# 3. Here I then format the string to how I want:
$info_diskdrive_basic = ($info_diskdrive_basic) -replace '(.+?)(\s+):\s*(?!\S)', ($id2 + '$1:$2                                       ')

$info_diskdrive_basic

输出应如下所示:

我想像这样格式化属性和值:Properties: >spaces< value,其中值在右侧并沿它们的左侧对齐

# Disk:                                                 \\.\PHYSICALDRIVE0
# Disk Model:                                           Crucial_CT512MX100SSD1
# Partition:                                            Disk #0, Partition #2
# Raw Size:                                             476 GB
# Drive Letter:                                         C:
# Volume Name:
# Size:                                                 476 GB
# Free Space:                                           306 GB

但我的输出最终是这样的:(注意文本未对齐)

# Disk:                                                \\.\PHYSICALDRIVE0
# Disk Model:                                           Crucial_CT512MX100SSD1
# Partition:                                           Disk #0, Partition #2
# Raw Size:                                             476 GB
# Drive Letter:                                         C:
# Volume Name:
# Size:                                                476 GB
# Free Space:                                           306 GB

【问题讨论】:

  • 为什么不直接输出$info_diskdrive_basic | Format-List 而不是执行这些步骤1、2和3?
  • 我还有很多其他代码可以输出系统信息,这些代码使用Description: Value 遵循这种格式,所以我想用同样的方式。
  • 所以基本上,您想要Format-List 产生的输出,但是在属性名称和实际值之间有很多额外的空格?再次:为什么?
  • 我给出了原因,所有其他输出都是这样的,它根据示例将右侧的属性与左对齐对齐。

标签: powershell get-wmiobject


【解决方案1】:

按原样使用您发布的代码,“字符串化”您的属性

例如:

($info_diskdrive_basic = Get-WmiObject Win32_DiskDrive | 
ForEach-Object {
  $disk       = $_
  $partitions = "ASSOCIATORS OF " + 
                  "{Win32_DiskDrive.DeviceID='$($disk.DeviceID)'} " + 
                  "WHERE AssocClass = Win32_DiskDriveToDiskPartition"
  Get-WmiObject -Query $partitions | 
  ForEach-Object {
    $partition = $_
    $drives    = "ASSOCIATORS OF " + 
                "{Win32_DiskPartition.DeviceID='$($partition.DeviceID)'} " + 
                "WHERE AssocClass = Win32_LogicalDiskToPartition"
    Get-WmiObject -Query $drives | 
    ForEach-Object {
      [PSCustomObject][Ordered]@{
        Disk          = "$($disk.DeviceID)"
        DiskModel     = "$($disk.Model)"
        Partition     = "$($partition.Name)"
        RawSize       = "$('{0:d} GB' -f [int]($partition.Size/1GB))"
        DriveLetter   = "$($_.DeviceID)"
        VolumeName    = "$($_.VolumeName)"
        Size          = "$('{0:d} GB' -f [int]($_.Size/1GB))"
        FreeSpace     = "$('{0:d} GB' -f [int]($_.FreeSpace/1GB))"
      }
    }
  }
})
# Results
<#
Disk        : \\.\PHYSICALDRIVE0
DiskModel   : Samsung SSD 950 PRO 512GB
Partition   : Disk #0, Partition #0
RawSize     : 477 GB
DriveLetter : D:
VolumeName  : Data
Size        : 477 GB
FreeSpace   : 364 GB
...
#>

注意事项:

我正在使用PowerShell变量压缩将结果分配给变量并同时输出到屏幕。

更新

至于这个……

“我想像这样格式化属性和值:属性:>空格

$Spacer = ("`t")*8

($info_diskdrive_basic = Get-WmiObject Win32_DiskDrive | 
ForEach-Object {
  $disk       = $_
  $partitions = "ASSOCIATORS OF " + 
                  "{Win32_DiskDrive.DeviceID='$($disk.DeviceID)'} " + 
                  "WHERE AssocClass = Win32_DiskDriveToDiskPartition"
  Get-WmiObject -Query $partitions | 
  ForEach-Object {
    $partition = $_
    $drives    = "ASSOCIATORS OF " + 
                "{Win32_DiskPartition.DeviceID='$($partition.DeviceID)'} " + 
                "WHERE AssocClass = Win32_LogicalDiskToPartition"
    Get-WmiObject -Query $drives | 
    ForEach-Object {
      [PSCustomObject][Ordered]@{
        Disk          = "$Spacer$($disk.DeviceID)"
        DiskModel     = "$Spacer$($disk.Model)"
        Partition     = "$Spacer$($partition.Name)"
        RawSize       = "$Spacer$('{0:d} GB' -f [int]($partition.Size/1GB))"
        DriveLetter   = "$Spacer$($PSItem.DeviceID)"
        VolumeName    = "$Spacer$($PSItem.VolumeName)"
        Size          = "$Spacer$('{0:d} GB' -f [int]($PSItem.Size/1GB))"
        FreeSpace     = "$Spacer$('{0:d} GB' -f [int]($PSItem.FreeSpace/1GB))"
      }
    }
  }
})
# Results
<#
Disk        :                               \\.\PHYSICALDRIVE0
DiskModel   :                               Samsung SSD 950 PRO 512GB
Partition   :                               Disk #0, Partition #0
RawSize     :                               477 GB
DriveLetter :                               D:
VolumeName  :                               Data
Size        :                               477 GB
FreeSpace   :                               364 GB
...
#>

【讨论】:

  • 感谢您发布,但返回的代码与我的问题中的代码相同。我想像这样格式化属性和值:Properties: &gt;spaces&lt; value,其中值在右侧并沿它们的左侧对齐。
  • 然后在格式化中,只需输入附加的字符/字符串格式化代码即可。此时它只是一个字符串。
  • 这是我最初尝试过的。输出的详细信息在原始问题中。那只是一个简短的描述。此外,接受的答案是输出应该是什么。
【解决方案2】:

要输出您显然需要的信息,我们需要知道最大行长度(在您的示例中为 79 个字符)并以此为基础工作。

$maxLineLength  = 79  # counted from the longest line in your example
$maxValueLength = 0   # a counter to keep track of the largest value length in characters

$info_diskdrive_basic = Get-WmiObject Win32_DiskDrive | ForEach-Object {
    $disk = $_
    $partitions = "ASSOCIATORS OF " + "{Win32_DiskDrive.DeviceID='$($disk.DeviceID)'} " + "WHERE AssocClass = Win32_DiskDriveToDiskPartition"
    Get-WmiObject -Query $partitions | ForEach-Object {
        $partition = $_
        $drives = "ASSOCIATORS OF " + "{Win32_DiskPartition.DeviceID='$($partition.DeviceID)'} " + "WHERE AssocClass = Win32_LogicalDiskToPartition"
        Get-WmiObject -Query $drives | ForEach-Object {
            $obj = [PSCustomObject]@{
                'Disk'         = $disk.DeviceID
                'Disk Model'   = $disk.Model
                'Partition'    = $partition.Name
                'Raw Size'     = '{0:d} GB' -f [int]($partition.Size/1GB)
                'Drive Letter' = $_.DeviceID
                'Volume Name'  = $_.VolumeName
                'Size'         = '{0:d} GB' -f [int]($_.Size/1GB)
                'Free Space'   = '{0:d} GB' -f [int]($_.FreeSpace/1GB)
            }
            # get the maximum length for all values
            $len = ($obj.PsObject.Properties.Value.ToString().Trim() | Measure-Object -Property Length -Maximum).Maximum
            $maxValueLength = [Math]::Max($maxValueLength, $len)
                                          
            # output the object to be collected in $info_diskdrive_basic
            $obj
        }
    }
}

# sort the returned array of objects on the DriveLetter property and loop through
$result = $info_diskdrive_basic | Sort-Object DriveLetter | ForEach-Object {
    # loop through all the properties and calculate the padding needed for the output
    $_.PsObject.Properties | ForEach-Object {
        $label   = '# {0}:' -f $_.Name.Trim()
        $padding = $maxLineLength - $maxValueLength - $label.Length
        # output a formatted line
        "{0}{1,-$padding}{2}" -f $label, '', $_.Value.ToString().Trim()
    }
    # add a separator line between the disks
    ''
}

# output the result on screen
$result

# write to disk
$result | Set-Content -Path 'X:\theResult.txt'

# format for HTML mail:
'<pre>{0}</pre>' -f ($result -join '<br>')

示例输出:

# 磁盘:\\.\PHYSICALDRIVE1 # 磁盘型号:三星 SSD 750 EVO 250GB # 分区:磁盘#1,分区#0 # 原始大小:232 GB # 盘符:C: # 卷名:系统 # 大小:232 GB # 可用空间:160 GB # 磁盘:\\.\PHYSICALDRIVE2 # 磁盘型号:WDC WD7501AALS-00J7B0 # 分区:磁盘#2,分区#0 # 原始大小:699 GB # 盘符:D: # 卷名:数据 # 大小:699 GB # 可用空间:385 GB

附注与创建[PsCustomObject],无需添加[Ordered]

【讨论】:

  • 谢谢,这正是我所追求的。我唯一更改的是将$label = '# {0}:' -f $_.Name 更改为$label = '{0}:' -f $_.Name -replace '(?-i)(?=\B[A-Z][a-z])', (' ')DiskModel 更改为Disk Model。编辑:第一个驱动器没有排队。见这里:i.imgur.com/H68hKTR.png
  • @Ste 感谢您告诉我。顺便说一句,您可以立即在 [PsCustomObject] 的定义中更改该标签:DiskModel --> 'Disk Model',这样您之后就不必执行正则表达式了。
  • 当我尝试它返回一个错误。您的代码有一件小事。列表中的第一个驱动器没有对齐。 i.imgur.com/H68hKTR.png
  • @Ste 请查看编辑后的答案。它现在允许在返回的属性标签中使用空格,并在更高级别上计算最大值长度
  • 伟大的西奥。谢谢。这是完美的工作。我有一个已连接的网络驱动器,但这可能是另一个 Q 的东西。Get-PSDrive -PSProvider FileSystem 返回此:i.imgur.com/L7Dfa6B.png,其中驱动器突出显示为黄色。
猜你喜欢
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多