Powershell - определяет, установлена ​​ли буква диска на твердотельном диске SSD

Я пишу сценарий сборки виртуальной машины 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

3 ответа

Вот поворот на тему, если это то, что вам нужно вместо этого. Эта функция возвращает массив букв дисков 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://stackru.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
#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.

Вот мой вариант проверки, находится ли текущий рабочий каталог на 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'
        }
    }
}

Это можно изменить, указав букву диска в качестве аргумента для проверки по букве диска.

Другие вопросы по тегам