Powershell:如何结合 2 个命令的输出将磁盘字母与磁盘 MediaType 相关联?
Posted
技术标签:
【中文标题】Powershell:如何结合 2 个命令的输出将磁盘字母与磁盘 MediaType 相关联?【英文标题】:Powershell: How to combine the output of 2 commands to associate disk letter with disk MediaType? 【发布时间】:2021-10-23 06:22:46 【问题描述】:我正在使用以下命令获取磁盘信息:
get-ciminstance -ClassName Win32_LogicalDisk
问题是,它不包含MediaType
属性(HDD、SSD 或分别为数字形式 4、3)。
我想我需要将它与另一个命令结合(关联),例如:
Get-PhysicalDisk
或
Get-WmiObject -Class MSFT_PhysicalDisk -Namespace root\Microsoft\Windows\Storage
我从 Node.js 调用这些命令,因此我可以运行单独的命令并在之后组合结果。它不必是 1 个命令。我只是不确定如何关联它们,因为 Powershell API 不一致:
这个返回数字
(Get-WmiObject -Class MSFT_PhysicalDisk -Namespace root\Microsoft\Windows\Storage).DeviceID
这个返回驱动器号
(get-ciminstance -ClassName Win32_LogicalDisk).DeviceID
我在另一个thread 中找到了这段代码,但我不确定如何在其中添加MediaType
属性:
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
【问题讨论】:
你确定,这会返回 MediaType 吗?Get-CimInstance -ClassName Win32_LogicalDisk | Select-Object -Property MediaType
@jfrmilner 是的,但这是一个错误的 MediaType,它返回一些神奇的数字 12,而不是 3 (SSD) 或 4 (HDD)。
【参考方案1】:
我不知道是否有更复杂的方法,但我认为它提供了您期望的结果。
$PhysicalDiskList =
Get-PhysicalDisk
$LogicalDiskList =
Get-CimInstance -ClassName CIM_LogicalDisk |
Where-Object -Property 'DriveType' -EQ -Value 3
$Result =
foreach ($LogicalDisk in $LogicalDiskList)
$DiskPartition =
Get-CimAssociatedInstance -InputObject $LogicalDisk -ResultClass CIM_DiskPartition
$PhysicalDisk =
$PhysicalDiskList |
Where-Object -Property 'DeviceID' -EQ -Value $DiskPartition.DiskIndex
[PSCustomObject]@
DriveLetter = $LogicalDisk.DeviceID
VolumeName = $LogicalDisk.VolumeName
Size = $LogicalDisk.Size
FreeSpace = $LogicalDisk.FreeSpace
DriveModel = $PhysicalDisk.FriendlyName
MediaType = $PhysicalDisk.MediaType
$Result |
Format-Table -AutoSize
它在我的系统上返回以下内容:
DriveLetter VolumeName Size FreeSpace DriveModel MediaType
----------- ---------- ---- --------- ---------- ---------
C: System 254493077504 49397727232 SAMSUNG MZNTY256HDHP-000L7 SSD
D: Data 1000067821568 643155914752 WDC WD10SPCX-08S8TT0 HDD
【讨论】:
感谢您的回答。不幸的是,只有 SSD 驱动器具有正确的MediaType: SSD
。 HDD 驱动器有一个空的MediaType: ''
。你知道为什么会这样吗?当我单独运行 Get-PhysicalDisk
时,我得到所有驱动器的正确结果。
我不知道该说什么。它按预期对我有用。
我的硬盘有 2 个分区和一个网络文件夹映射在上面,也许这就是导致硬盘出现问题的原因?如果我删除-Value $DiskPartition.DiskIndex
之后的所有内容并将$PhysicalDisk
放在它下面,它只会返回SSD 驱动器。但是上面几行的$PhysicalDisk
会返回来自所有驱动器的所有分区
我更改了代码以仅获取固定磁盘 - 没有 DVD 驱动器或网络驱动器。但是多个分区应该不是问题。我试过了,它只是为这个磁盘上的两个分区返回相同的硬件信息两次。
谢谢,不幸的是,这个解决方案不适用于我的用例。我确实需要所有驱动器的列表,包括网络驱动器。顺便说一句,由于某种原因,编辑后的 sn-p 仍然没有为 HDD 驱动器返回 MediaType: 'HDD'
【参考方案2】:
在获取 mediatype 和其他属性方面,我的结果好坏参半。一些系统返回实际值,而另一些系统则返回整数。这是我的脚本中的一个 sn-p,可以帮助您解决这个问题。
Get-CimInstance Win32_Diskdrive -Filter "Partitions>0" | ForEach-Object
$disk = Get-CimInstance -ClassName MSFT_PhysicalDisk -Namespace root\Microsoft\Windows\Storage -Filter "SerialNumber='$($_.SerialNumber.trim())'"
foreach($partition in $_ | Get-CimAssociatedInstance -ResultClassName Win32_DiskPartition)
foreach($logicaldisk in $partition | Get-CimAssociatedInstance -ResultClassName Win32_LogicalDisk)
[PSCustomObject]@
Disk = $_.DeviceID
DiskModel = $_.Model
DiskSize = $_.Size
HealthStatus = $disk.HealthStatus
BusType = $disk.BusType
MediaType = "0 (1)" -f $_.MediaType,$disk.MediaType
Partition = $partition.Name
PartitionSize = $partition.Size
VolumeName = $logicaldisk.VolumeName
DriveLetter = $logicaldisk.DeviceID
VolumeSize = $logicaldisk.Size
FreeSpace = $logicaldisk.FreeSpace
在返回代码的时候,可以改为运行。
$mediatypelist = @
'0' = 'Unspecified'
'3' = 'HDD'
'4' = 'SSD'
'5' = 'SCM'
$healthstatuslist = @
'0' = 'Healthy'
'1' = 'Warning'
'2' = 'Unhealthy'
'5' = 'Unknown'
$bustypelist = @
'0' = 'Unknown'
'1' = 'SCSI'
'2' = 'ATAPI'
'3' = 'ATA'
'4' = 'IEEE 1394'
'5' = 'SSA'
'6' = 'Fibre Channel'
'7' = 'USB'
'8' = 'RAID'
'9' = 'iSCSI'
'10' = 'Serial Attached SCSI (SAS)'
'11' = 'Serial ATA (SATA)'
'12' = 'Secure Digital (SD)'
'13' = 'Multimedia Card (MMC)'
'14' = 'This value is reserved for system use.'
'15' = 'File-Backed Virtual'
'16' = 'Storage Spaces'
'17' = 'NVMe'
'18' = 'This value is reserved for system use.'
Get-CimInstance Win32_Diskdrive -Filter "Partitions>0" | ForEach-Object
$disk = Get-CimInstance -ClassName MSFT_PhysicalDisk -Namespace root\Microsoft\Windows\Storage -Filter "SerialNumber='$($_.SerialNumber.trim())'"
foreach($partition in $_ | Get-CimAssociatedInstance -ResultClassName Win32_DiskPartition)
foreach($logicaldisk in $partition | Get-CimAssociatedInstance -ResultClassName Win32_LogicalDisk)
[PSCustomObject]@
Disk = $_.DeviceID
DiskModel = $_.Model
DiskSize = $_.Size
HealthStatus = $healthstatuslist["$($disk.HealthStatus)"]
BusType = $bustypelist["$($disk.BusType)"]
MediaType = "0 (1)" -f $_.MediaType,$mediatypelist["$($disk.MediaType)"]
Partition = $partition.Name
PartitionSize = $partition.Size
VolumeName = $logicaldisk.VolumeName
DriveLetter = $logicaldisk.DeviceID
VolumeSize = $logicaldisk.Size
FreeSpace = $logicaldisk.FreeSpace
【讨论】:
只有一个问题 - 我有一个网络驱动器Z:
映射到我的硬盘驱动器 E:
上的一个文件夹,但是在这个 sn-p 的输出中我得到 DriveLetter : E:
E:
和 Z:
驱动器。如果我单独运行get-ciminstance -ClassName Win32_LogicalDisk
,我会看到网络驱动器分配了Z:
字母。有没有办法在这个 sn-p 中解决这个问题?我认为这个问题是由Get-CimInstance -ClassName MSFT_PhysicalDisk
不返回网络驱动器引起的
我没有从get-ciminstance -ClassName Win32_LogicalDisk
获得任何映射驱动器。 $disk
中唯一使用的是 healthstatus
、bustype
和 mediatype
。驱动器号来自$logicaldisk.deviceid
- 需要弄清楚为什么没有字母。
我认为 MSFT_PhysicalDisk
通常无法获取网络驱动器,也许这个 sn-p 应该从 Win32_LogicalDisk
获取整个驱动器列表,然后将列表从 MSFT_PhysicalDisk
以相反的方式填充到Win32_LogicalDisk
的输出?
就像我说的物理磁盘只用于三个属性,没有一个是驱动器号
看来Get-CimAssociatedInstance
正在获取它映射到的网络源驱动器。也许代码 sn-p 应该改为循环 get-ciminstance -ClassName Win32_LogicalDisk
以获取所有具有正确驱动器号的驱动器并将驱动器映射到 Get-CimInstance Win32_Diskdrive
的输出?这也可以获取网络驱动器的 ProvideName 属性以上是关于Powershell:如何结合 2 个命令的输出将磁盘字母与磁盘 MediaType 相关联?的主要内容,如果未能解决你的问题,请参考以下文章
Powershell:将外部命令输出通过管道传输到另一个外部命令
将 2 个 git 存储库与冲突结合在一起后,我希望 Powershell 中的 git mergetool 始终为每个文件选择(m)修改
适用于 Linux 的 Powershell:将命令与管道符号结合起来不起作用
如何使用 PowerShell 处理 diskpart 命令的输出
我正在使用来自 python 的 powershell 命令获取一些数据,而 Windows 中没有 cmd!如何将此输出分配给字符串变量?