【问题标题】:Combine `Get-Disk` info and `LogicalDisk` info in PowerShell?在 PowerShell 中结合“Get-Disk”信息和“LogicalDisk”信息?
【发布时间】:2015-09-14 08:05:51
【问题描述】:

我有这个扫描所有逻辑磁盘信息的查询:

Write-Host "Drive information for $env:ComputerName"

Get-WmiObject -Class Win32_LogicalDisk |
    Where-Object {$_.DriveType -ne 5} |
    Sort-Object -Property Name | 
    Select-Object Name, VolumeName, VolumeSerialNumber,SerialNumber, FileSystem, Description, VolumeDirty, `
        @{"Label"="DiskSize(GB)";"Expression"={"{0:N}" -f ($_.Size/1GB) -as [float]}}, `
        @{"Label"="FreeSpace(GB)";"Expression"={"{0:N}" -f ($_.FreeSpace/1GB) -as [float]}}, `
        @{"Label"="%Free";"Expression"={"{0:N}" -f ($_.FreeSpace/$_.Size*100) -as [float]}} |
    Format-Table -AutoSize

The output is

但是 - 我在物理磁盘信息及其分区/卷信息之后:

所以 - 对于物理磁盘,我有这个命令:

Get-Disk

Result

问题:

我想结合这两个命令。我想查看每个磁盘下方的磁盘、 - 它的逻辑磁盘信息:

  • 磁盘编号 1 : ....(info)
    >其逻辑磁盘信息.....
  • 磁盘编号 2 : ....(info)
    >这是逻辑磁盘信息.....
  • 磁盘编号 3 : ....(info)
    >这是逻辑磁盘信息.....
  • 等等...

如何在这两个查询之间进行组合?

【问题讨论】:

  • 不久前我也有类似的问题,不知道这个答案是否有帮助:serverfault.com/a/571669/822
  • @Kev 谢谢,但这对我帮助不大。驱动器号是分区的产物。我不想从驱动器号转到它的属性。我想从物理磁盘的 -----> 他们的卷

标签: powershell filesystems drive


【解决方案1】:

您需要查询多个 WMI 类才能获得所需的所有信息。

可以使用Win32_DiskDriveToDiskPartition 类将分区映射到它们的磁盘,并且可以通过Win32_LogicalDiskToPartition 类将驱动器映射到它们的分区。

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 {
      New-Object -Type PSCustomObject -Property @{
        Disk        = $disk.DeviceID
        DiskSize    = $disk.Size
        DiskModel   = $disk.Model
        Partition   = $partition.Name
        RawSize     = $partition.Size
        DriveLetter = $_.DeviceID
        VolumeName  = $_.VolumeName
        Size        = $_.Size
        FreeSpace   = $_.FreeSpace
      }
    }
  }
}

【讨论】:

  • 优秀。正是我需要的。谢谢。
  • 最后一个问题:我已经设法以 GB 显示信息。所以这个数字很好。但我想添加文本后缀(“(GB)”),如123.45(GB)。但我可能错过了一些东西。我应该改变什么?看这里:i.imgur.com/95QyaI4.png
  • 如果您希望将数字显示为x GB,您必须将其转换为字符串,例如'{0:d} GB' -f [int]($_.Size / 1GB)
  • 是否可以使用系统提示符下的 wmic 命令执行此操作?
  • 想通了!如果您想要您的项目列表 ORDERED,请使用“[PSCustomObject][Ordered]@{”而不是“New-Object -Type PSCustomObject -Property @{”
【解决方案2】:

这样怎么样……

Get-CimInstance Win32_Diskdrive -PipelineVariable disk |
Get-CimAssociatedInstance -ResultClassName Win32_DiskPartition -pv partition |
Get-CimAssociatedInstance -ResultClassName Win32_LogicalDisk |
Select-Object @{n='Disk';e={$disk.deviceid}},
@{n='DiskSize';e={$disk.size}},
@{n='DiskModel';e={$disk.model}},
@{n='Partition';e={$partition.name}},
@{n='RawSize';e={$partition.size}},
@{n='DriveLetter';e={$_.DeviceID}},
VolumeName,Size,FreeSpace

输出:

Disk        : \\.\PHYSICALDRIVE0
DiskSize    : 128034708480
DiskModel   : SAMSUNG MZ7PC128HAFU-000L5
Partition   : Disk #0, Partition #0
RawSize     : 128034595328
DriveLetter : C:
VolumeName  : DISK
Size        : 128034594816
FreeSpace   : 7023042560

不幸的是,这不适用于多个驱动器。像 sort-object 一样获取 cimassociatedinstance 块,并且只设置最新的管道变量。这是一个解决方法:

Get-CimInstance Win32_Diskdrive -PipelineVariable disk |
% { Get-CimAssociatedInstance $_ -ResultClass Win32_DiskPartition -pv partition}|
% { Get-CimAssociatedInstance $_ -ResultClassName Win32_LogicalDisk } |
Select-Object @{n='Disk';e={$disk.deviceid}},
@{n='DiskSize';e={$disk.size}},
@{n='DiskModel';e={$disk.model}},
@{n='Partition';e={$partition.name}},
@{n='RawSize';e={$partition.size}},
@{n='DriveLetter';e={$_.DeviceID}},
VolumeName,Size,FreeSpace

Disk        : \\.\PHYSICALDRIVE0
DiskSize    : 128034708480
DiskModel   : SAMSUNG MZ7PC128HAFU-000L5
Partition   : Disk #0, Partition #0
RawSize     : 128034595328
DriveLetter : C:
VolumeName  : DISK
Size        : 128034594816
FreeSpace   : 4226514944

Disk        : \\.\PHYSICALDRIVE1
DiskSize    : 7797565440
DiskModel   : USB Flash Memory USB Device
Partition   : Disk #1, Partition #0
RawSize     : 7801405440
DriveLetter : E:
VolumeName  : WINPE
Size        : 7784628224
FreeSpace   : 7222669312

【讨论】:

  • 嗯,这在 PS 7 上实际上对我不起作用;对于多个结果,它似乎保留了所有字段的初始值,直到DriveLetter,所以基本上,前两个命令专门针对一个结果进行操作。为了解决这个问题,我让它为第一个结果的每个结果调用管道命令 2 和 3,并修复了它。 % { $_ | Get-CimAssociatedInstance -ResultClassName Win32_DiskPartition -PipelineVariable partition } | % { $_ | Get-CimAssociatedInstance -ResultClassName Win32_LogicalDisk } |
  • @AlexFanat 在 PS 7.2 中为我工作。
  • 对于 1 个结果,它可以工作,对于多个具有不同物理驱动器的结果,它不起作用,并且在 DriveLetter 上方显示所有结果的相同信息。尝试使用至少 2 个物理驱动器的配置,其中一个具有 2 个分区。使用与您相同的 PS,7.2.0。
  • @AlexFanat 你是对的。 Get-cimassociatedinstance 似乎会阻塞,直到管道像 sort-object 一样完成,所以只设置了最新的管道变量。
【解决方案3】:

灵感来自 js2010 的答案,并进行了一些改进:

例如,Manufacturer 字段在从 Win32_DiskDrive 实例检索时似乎具有一些占位符值,但在使用 Get-Disk 命令行开关时具有正确的值。

function Get-Drive {

  foreach($disk in Get-CimInstance Win32_Diskdrive) {

    $diskMetadata = Get-Disk | Where-Object { $_.Number -eq $disk.Index } | Select-Object -First 1

    $partitions = Get-CimAssociatedInstance -ResultClassName Win32_DiskPartition -InputObject $disk

    foreach($partition in $partitions) {

      $drives = Get-CimAssociatedInstance -ResultClassName Win32_LogicalDisk -InputObject $partition

      foreach($drive in $drives) {

        $totalSpace = [math]::Round($drive.Size / 1GB, 3)
        $freeSpace  = [math]::Round($drive.FreeSpace / 1GB, 3)
        $usedSpace  = [math]::Round($totalSpace - $freeSpace, 3)

        $volume     = Get-Volume |
                      Where-Object { $_.DriveLetter -eq $drive.DeviceID.Trim(":") } |
                      Select-Object -First 1

        [PSCustomObject] @{
                            DriveLetter   = $drive.DeviceID
                            Number        = $disk.Index

                            Label         = $volume.FileSystemLabel
                            Manufacturer  = $diskMetadata.Manufacturer
                            Model         = $diskMetadata.Model
                            SerialNumber  = $diskMetadata.SerialNumber.Trim() 
                            Name          = $disk.Caption

                            FileSystem    = $volume.FileSystem
                            PartitionKind = $diskMetadata.PartitionStyle

                            TotalSpace    = $totalSpace
                            FreeSpace     = $freeSpace
                            UsedSpace     = $usedSpace

                            Drive         = $drive
                            Partition     = $partition
                            Disk          = $disk
        }

      }
    }
  }
}           

示例用法:

Get-Drive | Format-List
Get-Drive | Where-Object { $_.DriveLetter -eq 'G:' }

输出:

DriveLetter   : G:
Number        : 5
Label         : SE-LXY2-298GB
Manufacturer  : Seagate
Model         : FreeAgent Go
SerialNumber  : 2GE45CK1
Name          : Seagate FreeAgent Go USB Device
FileSystem    : NTFS
PartitionKind : MBR
TotalSpace    : 298.089
FreeSpace     : 297.865
UsedSpace     : 0.224
Drive         : Win32_LogicalDisk: G: (DeviceID = "G:")
Partition     : Win32_DiskPartition: Disk #5, Partition #0 (DeviceID = "Disk #5, Partition #0")
Disk          : Win32_DiskDrive: Seagate FreeAgent Go USB Device (DeviceID = "\\.\PHYSICALDRIVE5")

【讨论】:

    猜你喜欢
    • 2020-11-22
    • 2022-01-26
    • 2013-02-22
    • 1970-01-01
    • 1970-01-01
    • 2016-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多