Powershell - 检测驱动器号是不是安装在 SSD 固态磁盘上

Posted

技术标签:

【中文标题】Powershell - 检测驱动器号是不是安装在 SSD 固态磁盘上【英文标题】:Powershell - Detect if Drive Letter is Mounted on a SSD Solid State DiskPowershell - 检测驱动器号是否安装在 SSD 固态磁盘上 【发布时间】:2015-04-28 04:15:53 【问题描述】:

我正在编写一个 Hyper-V 虚拟机构建脚本,并希望添加一项功能,以便在可能的情况下选择 SSD,以优先考虑较小且最常用的虚拟机。我首先从这里的脚本专家那里找到了方法:http://blogs.technet.com/b/heyscriptingguy/archive/2013/03/17/powertip-use-powershell-to-identify-ssd.aspx,但我找不到任何可以带我一路走来的东西,所以我使用 WBEMTEST 来查找我需要查询的类,以便在 SSD 磁盘和有问题的驱动器号。

单击开始 --> 运行 --> 键入 WBEMTEST --> 检查命名空间是否设置为 root\cimv2 并单击连接 --> 枚举类 --> 递归 --> 确定。大约 5 秒后,列表将完全填充,允许您单击列表项。单击列表项,然后按字母 W 跳转到 Win32 并找到要查看的项,然后单击添加。然后显示可用的属性和方法。

下面的函数 IsSSDDrive 返回 $True 或 $False,具体取决于给定的驱动器号(包括冒号 - 例如 C:)是否安装在固态磁盘 (SSD) 上 - 假设制造商将字母 SSD 插入到设备中姓名。这种假设最终使这种方法变得不可靠,因此明智的做法是包含一些代码以使用以下代码进行交叉检查:

$DiskScore = (Get-WmiObject -Class Win32_WinSAT).DiskScore
If ($DiskScore -gt 6.9)  $SystemHasSSDDrive=$True  Else  $SystemHasSSDDrive=$False 
Write-Host "System Has SSD Drive: $SystemHasSSDDrive"

...如果您的环境使用此类驱动器。

Function IsSSDDrive($Drive)
# Returns $True or $False depending on whether the given drive letter (including colon - e.g. C:) is mounted on a Solid State Disk (SSD) - assuming that the manufacturer inserted the letters SSD into the device name - which ultimately makes this method unreliable so beware to cross check using something like $DiskScore = (Get-WmiObject -Class Win32_WinSAT).DiskScore # Thanks to Rens Hollanders for this! http://renshollanders.nl/2013/01/sccm-mdt-identifying-ssds-from-your-task-sequence-by-windows-performance-index/

    [array] $SSDDeviceIDList = $Null
    [array] $SSDDeviceIDListF = $Null
    [array] $DDListF = $Null
    [array] $SSDDriveLetters = $Null

    # Build a list of DeviceIDs of disk drives that contain the string SSD.  Example output: \\.\PHYSICALDRIVE0, \\.\PHYSICALDRIVE1 etc
    $SSDDeviceIDList = Get-WmiObject Win32_DiskDrive | where  $_.model -match 'SSD' | Select 'DeviceID'
    #$SSDDeviceIDList

    # Fix the list by removing the \\.\ from each of the obtained \\.\PHYSICALDRIVEx values
    ForEach ($SSDDeviceID in $SSDDeviceIDList) 
        $SSDDeviceIDListF += $SSDDeviceID.DeviceID.ToString().Replace("\\.\","")
    
    #$SSDDeviceIDListF

    # Obtain disk drive to disk partition mapping information.  Section of sample output for a single partition:
        #Antecedent       : \\MyComputerName\root\cimv2:Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE1"
        #Dependent        : \\MyComputerName\root\cimv2:Win32_DiskPartition.DeviceID="Disk #1, Partition #2"
    $DDList1 = $null ; $DDList1 = Get-WmiObject Win32_DiskDriveToDiskPartition
    # Look at each partition
    ForEach ($Disk in $DDList1) 
        # Iterate through the previously collected list of filtered (SSD in the name) hard drives
        ForEach ($SSDDeviceID in $SSDDeviceIDListF) 
            # If the partition is found with a property that matches the deviceID of the known-SSD list, then add the partition dependent information to the filtered (SSD) list of disk drives (DDListF)
            If ($Disk.Antecedent.Contains($SSDDeviceID))  $DDListF += $Disk.Dependent.Split([Char]34)[1] 
        
    
    #$DDListF

    # Obtain disk drive to disk partition mapping information.  We need to do this because the drive letter attribute is not present in Win32_DiskDriveToDiskPartition and the physical disk is not present in Win32_LogicalDiskToPartition. 
    # Section of sample output for a single partition:
    #    Antecedent       : \\MyComputerName\root\cimv2:Win32_DiskPartition.DeviceID="Disk #1, Partition #2"
    #    Dependent        : \\MyComputerName\root\cimv2:Win32_LogicalDisk.DeviceID="I:"
    $LDPList = Get-WmiObject Win32_LogicalDiskToPartition
    # Look at each existing partition (on all drives)
    ForEach ($Partition in $LDPList) 
        # Iterate through the list of filtered SSD partitions
        ForEach ($DDL in $DDListF) 
            # If the disk-partition information from the SSD filtered list is found in the current partition then add the current partition's drive letter to the list of SSD drive letters
            If ($Partition.Antecedent.Contains($DDL))  $SSDDriveLetters += $Partition.Dependent.Split([Char]34)[1] 
        
    
    $IsSSD = $False
    If (!($SSDDriveLetters -eq $Null)) 
        ForEach ($Item in $SSDDriveLetters) 
            If ($Drive.ToUpper() -eq $Item.ToUpper()) 
                $IsSSD = $True
                break
            
        
    
    Return $IsSSD


$d = IsSSDDrive "D:" # Returns True if the given drive letter resides on a disk with a name containing the letters SSD.
$d

$c = IsSSDDrive "C:"
$c

【问题讨论】:

【参考方案1】:

这里是主题的一个转折点,以防这是您需要的。 此函数返回一个 SSD 驱动器号数组 - 如果找到的话

Function GetSSDDriveLetters()
# Returns an array of SSD drive letters - if any are found - assuming that the manufacturer inserted the letters SSD into the device name - which ultimately makes this method unreliable so beware to cross check using something like $DiskScore = (Get-WmiObject -Class Win32_WinSAT).DiskScore # Thanks to Rens Hollanders for this! http://renshollanders.nl/2013/01/sccm-mdt-identifying-ssds-from-your-task-sequence-by-windows-performance-index/
# http://***.com/questions/28731401/powershell-detect-if-drive-letter-is-mounted-on-a-ssd-solid-state-disk/28731402#28731402

    [array] $SSDDeviceIDList = $Null
    [array] $SSDDeviceIDListF = $Null
    [array] $DDListF = $Null
    [array] $SSDDriveLetters = $Null

    # Build a list of DeviceIDs of disk drives that contain the string SSD.  Example output: \\.\PHYSICALDRIVE0, \\.\PHYSICALDRIVE1 etc
    $SSDDeviceIDList = Get-WmiObject Win32_DiskDrive | where  $_.model -match 'SSD' | Select 'DeviceID'
    #$SSDDeviceIDList

    # Fix the list by removing the \\.\ from each of the obtained \\.\PHYSICALDRIVEx values
    ForEach ($SSDDeviceID in $SSDDeviceIDList) 
        $SSDDeviceIDListF += $SSDDeviceID.DeviceID.ToString().Replace("\\.\","")
    
    #$SSDDeviceIDListF

    # Obtain disk drive to disk partition mapping information.  Section of sample output for a single partition:
        #Antecedent       : \\MyComputerName\root\cimv2:Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE1"
        #Dependent        : \\MyComputerName\root\cimv2:Win32_DiskPartition.DeviceID="Disk #1, Partition #2"
    $DDList1 = $null ; $DDList1 = Get-WmiObject Win32_DiskDriveToDiskPartition
    # Look at each partition
    ForEach ($Disk in $DDList1) 
        # Iterate through the previously collected list of filtered (SSD in the name) hard drives
        ForEach ($SSDDeviceID in $SSDDeviceIDListF) 
            # If the partition is found with a property that matches the deviceID of the known-SSD list, then add the partition dependent information to the filtered (SSD) list of disk drives (DDListF)
            If ($Disk.Antecedent.Contains($SSDDeviceID))  $DDListF += $Disk.Dependent.Split([Char]34)[1] 
        
    
    #$DDListF

    # Obtain disk drive to disk partition mapping information.  We need to do this because the drive letter attribute is not present in Win32_DiskDriveToDiskPartition and the physical disk is not present in Win32_LogicalDiskToPartition. 
    # Section of sample output for a single partition:
    #    Antecedent       : \\MyComputerName\root\cimv2:Win32_DiskPartition.DeviceID="Disk #1, Partition #2"
    #    Dependent        : \\MyComputerName\root\cimv2:Win32_LogicalDisk.DeviceID="I:"
    $LDPList = Get-WmiObject Win32_LogicalDiskToPartition
    # Look at each existing partition (on all drives)
    ForEach ($Partition in $LDPList) 
        # Iterate through the list of filtered SSD partitions
        ForEach ($DDL in $DDListF) 
            # If the disk-partition information from the SSD filtered list is found in the current partition then add the current partition's drive letter to the list of SSD drive letters
            If ($Partition.Antecedent.Contains($DDL))  $SSDDriveLetters += $Partition.Dependent.Split([Char]34)[1] 
        
    
    Return $SSDDriveLetters


GetSSDDriveLetters

【讨论】:

【参考方案2】:
#return letters of disks and if SSD or HDD or Unspec..:
Get-PhysicalDisk | ForEach-Object  
    $physicalDisk = $_ 
    $physicalDisk | Get-Disk | Get-Partition |
    Where-Object DriveLetter |Select-Object DriveLetter, @n='MediaType';e= 
    $physicalDisk.MediaType 
    
# | ft -HideTableHeaders if you don't want the table's headers.

【讨论】:

【参考方案3】:

这是我检查当前工作目录是否在 SSD 上的版本:

function IsWorkingDirectorOnAnSSD 
    $DriveLetter = $pwd.Path[0]
    foreach ($Drive in Get-PhysicalDisk)  
        if (($Drive | Get-Disk | Get-Partition).DriveLetter -Contains $DriveLetter) 
            Return $Drive.MediaType -eq 'SSD'
        
    

这可以用驱动器号作为参数进行修改,以通过驱动器号检查。

【讨论】:

以上是关于Powershell - 检测驱动器号是不是安装在 SSD 固态磁盘上的主要内容,如果未能解决你的问题,请参考以下文章

powershell 这使用PowerShell来更改计算机上的驱动器号。

linux 自动检测 IRQ 号

检测是不是安装了 Microsoft Access 驱动程序

地图网络驱动器没有显示Powershell,但与VBS一起使用?

Python自动检测Chrome浏览器版本号并下载对应驱动文件[chromedriver.exe]

1050ti399.24驱动无法安装