【问题标题】:Drive Letters + Drive Physical Types (Powershell)驱动器号 + 驱动器物理类型 (Powershell)
【发布时间】:2020-01-03 17:51:35
【问题描述】:

有没有一种方法可以让我们获取每个驱动程序的字母和物理类型?也就是说,获取一个数组,其中类似这样的内容:

$Drivers = *Get-Something*   # Where $Drivers is @{} array 
$Drivers
---
C: SSD
D: HDD
E: SSD
F: SSD

我需要将这两者的数据绑定到一个数组中。第一个包含字母。第二个包含物理类型:

$DriversName = (Get-WmiObject -Class Win32_Volume).DriveLetter | Where-Object { $_ }
$DriversType = Get-PhysicalDisk | Select-Object -ExpandProperty MediaType

但是我不知道第一个数组的哪个元素引用了第二个数组的元素。因为系统没有优先考虑它们。

非常感谢您的回答。

【问题讨论】:

标签: powershell


【解决方案1】:

这对我有用:

$partitions = Get-CimInstance Win32_DiskPartition
$physDisc = get-physicaldisk
$arr = @()
foreach ($partition in $partitions){
    $cims = Get-CimInstance -Query "ASSOCIATORS OF `
                          {Win32_DiskPartition.DeviceID='$($partition.DeviceID)'} `
                          WHERE AssocClass=Win32_LogicalDiskToPartition"
    $regex = $partition.name -match "(\d+)"
    $physDiscNr = $matches[0]
    foreach ($cim in $cims){
        $arr += [PSCustomObject]@{
            Drive = $cim.deviceID
            Partition = $partition.name
            MediaType = $($physDisc | ? {$_.DeviceID -eq $physDiscNr} | select -expand MediaType)
        }
    }
}

$arr

虽然使用正则表达式似乎有点笨拙,所以也许有更好的方法我没有看到。

【讨论】:

  • 非常感谢您的工作。但是,并非所有 MediaType 都会显示。我有两个磁盘。我只能看到一个驱动器的 MediaTypes。即C:SSD,D:_
  • @КириллЗацепин 您的电脑中有哪些媒体类型。您希望看到什么输出?
  • 非常感谢。我有 C:SSD,D:SSD,E:HHD。我想在控制台上获得相同的输出。我很惊讶 Powershell 没有这样一种方法可以同时给出一个字母和一个媒体类型。因此,我对您的尊重是您从不同的匹配方法中找到联系。我还不是很好的Powershell,但我正在向你学习)。尚未找到解决方案,但附近有一个。
【解决方案2】:

首先你要查看Win32_LogicalDiskToPartition

PS C:\> Get-WMIObject Win32_LogicalDiskToPartition | Select-Object Antecedent, Dependent | Write

这在我的系统上提供了

Antecedent                                                                        Dependent
----------                                                                        ---------
\\DESKTOP-JJASNFC\root\cimv2:Win32_DiskPartition.DeviceID="Disk #1, Partition #0" \\DESKTOP-JJASNFC\root\cimv2:Win32_LogicalDisk.DeviceID="C:"
\\DESKTOP-JJASNFC\root\cimv2:Win32_DiskPartition.DeviceID="Disk #0, Partition #1" \\DESKTOP-JJASNFC\root\cimv2:Win32_LogicalDisk.DeviceID="D:"

查询Win32_LogicalDisk 以获取有关驱动器号的信息。

Get-WMIObject Win32_LogicalDisk | Select DeviceID, Path | Write

对我有好处

DeviceID Path
-------- ----
C:       \\DESKTOP-JJASNFC\root\cimv2:Win32_LogicalDisk.DeviceID="C:"
D:       \\DESKTOP-JJASNFC\root\cimv2:Win32_LogicalDisk.DeviceID="D:"
F:       \\DESKTOP-JJASNFC\root\cimv2:Win32_LogicalDisk.DeviceID="F:"

这里Path 属性连接到我们之前看到的Dependent 属性。

Win32_DiskPartition我们可以找到设备ID

Get-WMIObject Win32_DiskPartition | Select DiskIndex, MedPath | Write

再次,对我来说

DiskIndex Path
--------- ----
        1 \\DESKTOP-JJASNFC\root\cimv2:Win32_DiskPartition.DeviceID="Disk #1, Partition #0"
        0 \\DESKTOP-JJASNFC\root\cimv2:Win32_DiskPartition.DeviceID="Disk #0, Partition #0"
        0 \\DESKTOP-JJASNFC\root\cimv2:Win32_DiskPartition.DeviceID="Disk #0, Partition #1"

现在,对您来说最有趣的部分是我们查询MSFT_Physicaldisk

Get-WmiObject MSFT_Physicaldisk -Namespace root\Microsoft\Windows\Storage | Select DeviceId, MediaType | Write

...

DeviceId MediaType
-------- ---------
1                4
0                4

这里,MediaType 是关键。值 4 表示 SSD,3 表示 HDD。 DeviceId 对应于DiskIndex

因此,如果您将这 4 个“表”连接在一起,您就可以实现您想要的。我的 Powershell-Fu 不够好。

回顾一下:连接就像

MSFT_Physicaldisk.MediaTypeMSFT_Physicaldisk.DeviceID

Win32_DiskPartition.DiskIndex, *Win32_DiskPartition.Path

Win32_LogicalDiskToPartition.DependentWin32_LogicalDiskToPartition.Antecedent

Win32_LogicalDisk.PathWin32_LogicalDisk.DeviceID

【讨论】:

    【解决方案3】:

    您可以使用磁盘的SerialNumber 属性来映射输出并将逻辑驱动器号与物理磁盘的MediaType 结合起来。

    # create a Hashtable to store the DriveLetter and SerialNumber obtained from WMI (I use Get-CimInstance here)
    $ht = @{}
    $wmiQuery1 = 'ASSOCIATORS OF {{Win32_DiskDrive.DeviceID="{0}"}} WHERE AssocClass = Win32_DiskDriveToDiskPartition'
    $wmiQuery2 = 'ASSOCIATORS OF {{Win32_DiskPartition.DeviceID="{0}"}} WHERE AssocClass = Win32_LogicalDiskToPartition'
    
    # for PowerShell < 3.0 use Get-WmiObject instead of Get-CimInstance
    Get-CimInstance -ClassName Win32_DiskDrive | Where-Object { $_.MediaType -match '^(Fixed|External)' } |
        ForEach-Object {
            # store the disk serialnumber of the physical disk and get the get the partition info for each disk
            $serial = $_.SerialNumber                  
            Get-CimInstance -Query ($wmiQuery1 -f $_.DeviceID.Replace('\','\\'))   #'# double-up the backslashes
        } |
        ForEach-Object {
            # now get the logical disks on each partition to find the drive letters in property DeviceID
            Get-CimInstance -Query ($wmiQuery2 -f $_.DeviceID)
        } | 
        ForEach-Object { $ht[$_.DeviceID] = $serial }  # store the drive letters as key, the disk serial as value
    
    # get the serialnumber and mediatype for each physical disk with Get-PhysicalDisk
    $disks = Get-PhysicalDisk | Select-Object SerialNumber, MediaType
    
    # loop through the Hashtable with partition/volume info gathered before and map on the SerialNumber property
    $ht.Keys | ForEach-Object {
        $drive = $_
        $type = ($disks | Where-Object { $_.SerialNumber -eq $ht[$drive] }).MediaType
        [PsCustomObject]@{
            DriveLetter = $drive
            MediaType   = if ($type) { $type } else { 'Unspecified' }
        }        
    } | Sort-Object DriveLetter
    

    结果应该是这样的

    DriveLetter  MediaType
    -----------  ---------
    C:           SSD
    D:           HHD
    E:           SSD
    F:           SSD
    

    【讨论】:

    • 根据我的观察,这些连续剧不匹配。
    • @hcm 我已更改代码以获取硬盘驱动器的制造商序列号。我的第一次尝试得到了错误的序列号(windows 给它的卷序列号)
    • 这行得通。唯一的缺点:你得到的是物理磁盘而不是分区的MediaType。因此,并非所有分区都显示出来。你必须把它转过来索引分区而不是物理驱动器。
    • @hcm 感谢您的意见。无法尝试,但明天将在 Win10 机器上尝试您的建议。
    • 非常感谢您的工作。但是,并非所有 MediaType 都会显示。我有两个磁盘。我只能看到一个驱动器的 MediaTypes。即C:SSD,D:_。也许是因为不同的方法显示的序列号不同。也许磁盘名称的组合将有助于解决问题。
    【解决方案4】:

    这是解决方案(感谢 js2010 的想法)。几乎。因为您需要显示逻辑驱动器。 Chris Dent 的决定:

    powershell
    Get-PhysicalDisk | ForEach-Object {
        $physicalDisk = $_
        $physicalDisk |
            Get-Disk |
            Get-Partition |
            Where-Object DriveLetter |
            Select-Object DriveLetter, @{n='MediaType';e={ $physicalDisk.MediaType }}
    }
    

    【讨论】:

      【解决方案5】:

      Get-Volume 返回 DriveLetter 和 DriveType 属性。

      编辑:

      Get-PhysicalDisk 具有 MediaType 属性。但它的 ObjectId 与驱动器号不匹配。

      $disk = get-physicaldisk
      $disk | get-disk | get-partition | select DriveLetter, 
        @{n='MediaType';e={$disk.MediaType}}
      
      DriveLetter MediaType
      ----------- ---------
                C SSD
      

      嗯,为什么管道变量不起作用?可以有多个驱动器号。

      get-physicaldisk -pv disk | get-disk | get-partition | select DriveLetter,
        @{n='MediaType';e={$disk.MediaType}}
      
      DriveLetter MediaType
      ----------- ---------
                C
      

      【讨论】:

      • DriveType 不是 MediaType
      • 添加 ForEach-Object 以解决对 PipelineVariable 缺乏支持的问题,这个在 imo 上是正确的。
      猜你喜欢
      • 1970-01-01
      • 2012-05-24
      • 2015-04-27
      • 2011-04-18
      • 1970-01-01
      • 2016-08-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多