Powershell и wmi, как отобразить логический диск / тома на жесткий диск или наоборот? - PullRequest
4 голосов
/ 28 января 2011
Get-WmiObject -ComputerName $ip -Credential $credential -Class Win32_logicaldisk

Это дает мне диски, как я вижу их в "Мой компьютер", например.C :, D :, E: Теперь, как мне получить соответствующие базовые физические диски?

Если я запускаю следующую команду

Get-WmiObject -ComputerName $ip -Credential $credential -Class win32_diskdrive

Я получаю диск 0, диск 1, диск 2

Так как узнать, какой логический диск находится на каком физическом диске?

Другой вопрос, как узнать номер тома?Если я запускаю diskpart и выполняю «список томов», я получаю следующий вывод

  Volume ###  Ltr  Label        Fs     Type        Size     Status     Info
  ----------  ---  -----------  -----  ----------  -------  ---------  --------
  Volume 2     C                NTFS   Partition     59 GB  Healthy    Boot
  ...

Как мне узнать, что логический диск C: том 2?

с наилучшими пожеланиями, Primoz.

Ответы [ 6 ]

8 голосов
/ 28 января 2011

Попробуйте это

Get-WMIObject Win32_LogicalDisk | Foreach-Object {
    Get-WmiObject -Query "Associators of {Win32_LogicalDisk.DeviceID='$($_.DeviceID)'} WHERE ResultRole=Antecedent"
} | Format-Table

Это дает вам связанные экземпляры WIn32_logicalDisk, где Win32_LogicalDisk является зависимой сущностью в отношении. Итак, вы получаете экземпляры Win32_DiskDrive.

1 голос
/ 14 июля 2016

Другие ответы с отношением WMI хороши, если вас не волнует том точки монтирования , поскольку с WMI невозможно напрямую связать том точки монтирования с разделом или диском.

Но есть раздел реестра, который поможет вам выяснить некоторую информацию, которая поможет вам построить соединение, как это делает Windows:

function getVolumeInformation{
    param($hostName, $credential)
    $volumeInformation = getVolumeInformation -computerName $hostName -credential $credential                   


    $WMIRegistryMountedDeviceInfo = WMIRegistryMountedDeviceInfo -computerName $hostName -Credential $credential
    foreach($volumeSerial in $volumeInformation.keys){                        
        if($WMIRegistryMountedDeviceInfo.containsKey($volumeSerial)){                        
            $volumeInformation[$volumeSerial]["diskPartitionStartingOffset"]=$WMIRegistryMountedDeviceInfo[$volumeSerial].diskPartitionStartingOffset
            $volumeInformation[$volumeSerial]["diskDriveSignature"]=$WMIRegistryMountedDeviceInfo[$volumeSerial].diskDriveSignature
            $volumeInformation[$volumeSerial]["wmiValueRegistry"]=$WMIRegistryMountedDeviceInfo[$volumeSerial].wmiValue
        }   
    }
    return $volumeInformation
}



function getWMIVolumeInformation{
    param($computerName, $credential)
    $diskToVolumeAssociation = @{}
    $regexGetVolumeSerial = ".*Volume{(.*)}.*"
    $wmiVolumes = $null
    $wmiVolumes = Get-WmiObject Win32_Volume -Credential $credential -ComputerName $computerName -filter "DriveType != 5" -ErrorVariable errorWMIVolume -ErrorAction SilentlyContinue

    $volumeInfo = @{}

    $wmiVolumes |   Foreach-Object {
        $wmiVolume = $_
        if($wmiVolume.DeviceID -match  $regexGetVolumeSerial){
            $wmiVolumeSerial = $Matches[1]
            $volumeInfo[$wmiVolumeSerial] = @{}
            $volumeInfo[$wmiVolumeSerial]["wmiInfo"] = $wmiVolume
            $volumeInfo[$wmiVolumeSerial]["volumeDirectoryName"] = $wmiVolume.Name
            $volumeInfo[$wmiVolumeSerial]["label"] = $wmiVolume.label
            $volumeInfo[$wmiVolumeSerial]["serial"] = $wmiVolumeSerial
            $volumeInfo[$wmiVolumeSerial]["capacity"] = $wmiVolume.Capacity
            $volumeInfo[$wmiVolumeSerial]["freeSpace"] = $wmiVolume.FreeSpace
        }
    }
    return $volumeInfo  


}
function WMIRegistryMountedDeviceInfo{
    param($computerName, $mycreds)
    $MountPointRegistryInformation = @{}

    $hklm = 2147483650
    $registryKeyMountedDevices = "SYSTEM\MountedDevices"
    $regexMountPoint = ".*{(.*)}.*"

    $wmi = get-wmiobject -list "StdRegProv" -namespace root\default -computername $computerName -credential $mycreds
    $wmiMountedDeviceKey = ($wmi.EnumValues($hklm,$registryKeyMountedDevices))

    foreach($mountedDeviceRegistryName in $wmiMountedDeviceKey.sNames){

        if($mountedDeviceRegistryName -match $regexMountPoint){
            $wmiValue = ($wmi.GetBinaryValue($hklm,$registryKeyMountedDevices,$mountedDeviceRegistryName))
            if($wmiValue.uValue.Count -eq 12){
                $diskDriveSignature = [bitconverter]::ToUInt32($wmiValue.uValue[0..3],0)
                $diskPartitionStartingOffset = [bitconverter]::ToUInt64($wmiValue.uValue[4..11],0)
                $MountPointRegistryInformation[$Matches[1]]=@{"serial"=$Matches[1];
                    "mountedDeviceRegistryName"=$mountedDeviceRegistryName;
                    "diskDriveSignature"=$diskDriveSignature;
                    "diskPartitionStartingOffset"=$diskPartitionStartingOffset;
                    "wmiValue"=$wmiValue.uValue}

            }
        }      
    }

   return $MountPointRegistryInformation
}

Этот код должен возвращать каждую подпись хэш-таблице с подписью диска, связанной с mountDevice. Он также возвращает DiskPartitionStartingOffset, который будет тем же, что и partition.StartingOffset, связанный с mountDevice.

Если вы хотите написать код самостоятельно, первые 4 байта этого значения реестра SYSTEM \ MountingDevices являются сигнатурой диска, но будьте осторожны с прямым порядком байтов. Следующие 8 байтов являются PartitionStartingOffset.

С помощью этой информации вы можете использовать WMI для получения информации о жестких дисках и подключать все вместе, чтобы действительно получить весь том, связанный со всеми имеющимися у вас физическими дисками, независимо от того, как они смонтированы.

Это не работает для объединенного тома.

Будьте очень осторожны при игре в такого рода реестре.

1 голос
/ 28 января 2011

Вот полный сценарий, который я создал для перечисления логического диска, раздела и смещения раздела для проверки проблем с выравниванием диска. (источник: мой блог http://sev17.com/2009/02/disk-alignment-partitioning-the-good-the-bad-the-ok-and-the-not-so-ugly/)

param ($computer)

$partitions = Get-WmiObject -computerName $computer Win32_DiskPartition

$partitions | foreach { Get-WmiObject -computerName $computer -query “ASSOCIATORS OF {Win32_DiskPartition.DeviceID=’$($_.DeviceID)’} WHERE AssocClass = Win32_LogicalDiskToPartition” |
add-member -membertype noteproperty PartitionName $_.Name -passthru |
add-member -membertype noteproperty Block $_.BlockSize -passthru |
add-member -membertype noteproperty StartingOffset $_.StartingOffset -passthru |
add-member -membertype noteproperty StartSector $($_.StartingOffset/$_.BlockSize) -passthru } |
Select SystemName, Name, PartitionName, Block, StartingOffset, StartSector
0 голосов
/ 20 марта 2019

Вот ответ Чеда Миллера, модифицированный для работы с PowerShell Core и с правильными кавычками и апострофами, чтобы он действительно работал в Linux / Windows и независимо от настроек термина (например, UTF-8 или нет):

param ($ComputerName)

$partitions = Get-CimInstance -ComputerName $ComputerName Win32_DiskPartition

$partitions |
foreach `
{
  Get-CimInstance -ComputerName $ComputerName `
                  -Query "ASSOCIATORS OF `
                          {Win32_DiskPartition.DeviceID='$($_.DeviceID)'} `
                          WHERE AssocClass=Win32_LogicalDiskToPartition" |
  Add-Member -MemberType NoteProperty PartitionName $_.Name -PassThru |
  Add-Member -MemberType NoteProperty Block $_.BlockSize -PassThru |
  Add-Member -MemberType NoteProperty StartingOffset $_.StartingOffset -PassThru |
  Add-Member -MemberType NoteProperty StartSector ($_.StartingOffset/$_.BlockSize) `
             -PassThru
} |
Select SystemName, Name, PartitionName, Block, StartingOffset, StartSector |
Sort-Object -Property Name # Sort by Drive letter to improve quality of life
# Select code above starting to the left of the hash in this comment
0 голосов
/ 26 августа 2016

вот еще одна альтернатива, использующая ядро. Microsoft рекомендует повторить его , но оказалось, что он очень эффективен для перехвата объединенного тома, точки монтирования и другой информации о типе тома, чтобы помочь связать диск и том.

$resultVolumeMappingFromKernel = Invoke-Command -ScriptBlock $scriptBlockInvokeCommandKernel32 -ComputerName $hostName -Credential $credential -ArgumentList (,$arrayOfVolumeSerial)

Он должен быть запущен на удаленной машине, для которой вам нужна информация с учетной записью администратора.

0 голосов
/ 28 января 2011

Проверьте Win32_LogicalDisktoPartition, который дает вам карту логического диска к физическому диску и разделу на этом диске в Antecedent. Чтобы просто получить метку для каждого диска

 gwmi win32_volume | select name,label
...