2011-01-27 45 views
4
Get-WmiObject -ComputerName $ip -Credential $credential -Class Win32_logicaldisk 

這讓我在我的磁盤中看到他們在「我的電腦」中,例如。 C :, D:,E: 現在我如何獲得相應的底層物理磁盤?Powershell和wmi,如何將邏輯磁盤/卷映射到硬盤,反之亦然?

如果我運行下面的命令

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卷?普里莫茲最好的問候。

回答

7

試試這個

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實例。

0

檢查Win32_LogicalDisktoPartition爲您提供邏輯磁盤映射到Antecedent中該磁盤上的物理磁盤和分區。只得到每個磁盤的標籤驅動

gwmi win32_volume | select name,label 
1

這裏是我創建列出邏輯磁盤,分區和分區偏移檢查磁盤對齊問題的完整劇本。 (來源:我的博客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 
1

如果您不在乎掛載點卷,WMI關係的其他答案是很好的,因爲WMI沒有直接將掛載點卷與分區或磁盤相關聯的可能方式。

但有一個註冊表項,可以幫助你找出一些信息,這將有助於你建立連接,窗口做的:

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]][email protected]{"serial"=$Matches[1]; 
        "mountedDeviceRegistryName"=$mountedDeviceRegistryName; 
        "diskDriveSignature"=$diskDriveSignature; 
        "diskPartitionStartingOffset"=$diskPartitionStartingOffset; 
        "wmiValue"=$wmiValue.uValue} 

      } 
     }  
    } 

    return $MountPointRegistryInformation 
} 

此代碼應給予回報,你每一個簽名與一個哈希表與掛載設備關聯的磁盤的磁盤驅動器簽名。它還返回DiskPartitionStartingOffset,它與掛載設備關聯的partition.StartingOffset相同。

如果您要自己編寫代碼,則此註冊表SYSTEM \ MountedDevices值的前4個字節是磁盤驅動器簽名,但要小心小端。接下來的8個字節是PartitionStartingOffset。

通過這些信息,您可以使用WMI獲取磁盤驅動器信息並將所有信息插入到一起,以便獲取與您擁有的所有物理驅動器相關的所有卷,而不管它們是如何安裝的。

這不適用於跨越卷。

非常小心當在這些類型的註冊表中玩。

+0

我試圖使用這個,但格式似乎有點關閉。上面的部分(在'function'之上)意味着是另一個腳本/函數的一部分,因爲有'return'語句。 – GregL

+1

你說得對。我編輯了一個我現在使用的代碼的摘要。我不能把它全部放在這裏,因爲它是900行代碼,意味着要在運行各種Windows操作系統的遠程計算機上運行。位轉換器部分非常重要,因爲以前的版本可能無法正確轉換它。 – Alex

0

這裏是另一種使用內核的替代方案。 微軟建議它,但它已顯示非常有效的跨越卷,掛載點和其他卷類型信息以幫助關聯磁盤和卷。

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

它需要你想用管理員帳戶信息的遠程計算機上運行:

$scriptBlockInvokeCommandKernel32 = { 
    param([array]$arrayOfVolumeSerial) 

    $cSharpCodeKernel32GetDisk = @" 
     using System; 
     using Microsoft.Win32.SafeHandles; 
     using System.IO; 
     using System.Runtime.InteropServices; 


     public class GetDisk 
     { 
      private const uint IoctlVolumeGetVolumeDiskExtents = 0x560000; 
      private const uint HASMOREDATA = 234; 
      // 4 rounded to 8 + 8 + 8= 24 
      [StructLayout(LayoutKind.Sequential)] 
      public struct DiskExtent 
      { 
       public int DiskNumber; 
       public Int64 StartingOffset; 
       public Int64 ExtentLength; 
      } 

      //size 4 rounded to 8 + number of extends * 24 
      [StructLayout(LayoutKind.Sequential)] 
      public struct DiskExtents 
      { 
       public int numberOfExtents; 
       public DiskExtent extents; 
      } 
      //4 
      [StructLayout(LayoutKind.Sequential)] 
      public struct DiskExtentsBeforeArray 
      { 
       public int numberOfExtents; 
      } 

      [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
      private static extern SafeFileHandle CreateFile(
       string lpFileName, 
       [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess, 
       [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode, 
       IntPtr lpSecurityAttributes, 
       [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition, 
       [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes, 
       IntPtr hTemplateFile 
      ); 

      [DllImport("Kernel32.dll", SetLastError = false, CharSet = CharSet.Auto)] 
      private static extern bool DeviceIoControl(
       SafeFileHandle hDevice, 
       uint IoControlCode, 
       [MarshalAs(UnmanagedType.AsAny)] [In] object InBuffer, 
       uint nInBufferSize, 
       ref DiskExtents OutBuffer, 
       int nOutBufferSize, 
       ref uint pBytesReturned, 
       IntPtr Overlapped 
      ); 

      [DllImport("Kernel32.dll", SetLastError = false, CharSet = CharSet.Auto)] 
      private static extern bool DeviceIoControl(
       SafeFileHandle hDevice, 
       uint IoControlCode, 
       [MarshalAs(UnmanagedType.AsAny)] [In] object InBuffer, 
       uint nInBufferSize, 
       IntPtr outBuffer, 
       int nOutBufferSize, 
       ref uint pBytesReturned, 
       IntPtr Overlapped 
      ); 


      [DllImport("Kernel32.dll", SetLastError = false, CharSet = CharSet.Auto)] 
      private static extern int GetLastError(); 

      public static DiskExtent[] GetPhysicalDriveString(string path) 
      { 
       DiskExtent[] diskExtent = null; 
       path = path.TrimEnd('\\'); 
       if (!path.StartsWith(@"\\.\")) 
        path = @"\\.\" + path; 

       SafeFileHandle safeFileHandle = CreateFile(path, FileAccess.Read, FileShare.Read | FileShare.Write, IntPtr.Zero, FileMode.Open, 0, 
       IntPtr.Zero); 
       if (safeFileHandle.IsInvalid) 
       { 
        Exception e = Marshal.GetExceptionForHR(Marshal.GetLastWin32Error()); 
       } 

       uint bytesReturned = new uint(); 
       DiskExtents VOLUME_DISK_EXTENTS = new DiskExtents(); 
       bool result = DeviceIoControl(
        safeFileHandle, 
        IoctlVolumeGetVolumeDiskExtents, 
        IntPtr.Zero, 
        0, 
        ref VOLUME_DISK_EXTENTS, 
        Marshal.SizeOf(VOLUME_DISK_EXTENTS), 
        ref bytesReturned, 
        IntPtr.Zero); 

       if (result) 
       { 
        diskExtent = new DiskExtent[1]; 
        diskExtent[0] = VOLUME_DISK_EXTENTS.extents; 
       } 
       else 
       { 
        int numberOfExtents = VOLUME_DISK_EXTENTS.numberOfExtents; 
        int lastError = GetLastError(); 

        if (lastError == HASMOREDATA) 
        { 
         int size = 8 + 24 * numberOfExtents; 
         uint bytesReturned2 = new uint(); 

         IntPtr blob = default(IntPtr); 
         blob = Marshal.AllocHGlobal(size); 
         bool resultMutipleDiskExtent = DeviceIoControl(
          safeFileHandle, 
          IoctlVolumeGetVolumeDiskExtents, 
          IntPtr.Zero, 
          0, 
          blob, 
          (int)size, 
          ref bytesReturned2, 
          IntPtr.Zero 
         ); 

         if (resultMutipleDiskExtent) 
         { 
          DiskExtentsBeforeArray lie = default(DiskExtentsBeforeArray); 
          lie = (DiskExtentsBeforeArray)Marshal.PtrToStructure(blob, typeof(DiskExtentsBeforeArray)); 
          diskExtent = new DiskExtent[lie.numberOfExtents]; 
          for (int i = 0; i <= lie.numberOfExtents - 1; i++) 
          { 
           IntPtr offset = new IntPtr(blob.ToInt64() + 8 + 24 * i); 
           diskExtent[i] = (DiskExtent)Marshal.PtrToStructure(offset, typeof(DiskExtent)); 
          } 

         } 
        } 
        else{ 
         throw new System.ComponentModel.Win32Exception(); 
        } 
       } 
       safeFileHandle.Close(); 
       return diskExtent; 
      } 
     } 
"@ 
    $resultOfOperation [email protected]{} 
    $volumeKernelInfo [email protected]{} 
    $type = Add-Type -TypeDefinition $cSharpCodeKernel32GetDisk -ErrorAction Continue -ErrorVariable errorAddType -PassThru 
    if($errorAddType){ 
     $resultOfOperation["error"]= ("error at CsharpBuild" + $errorAddType) 
    } 
    foreach($volumeSerial in $arrayOfVolumeSerial){ 
     $volumeString = "Volume{" + $volumeSerial + "}" 
     $volumeKernelInfo[$volumeSerial] = [GetDisk]::GetPhysicalDriveString($volumeString) 
    } 
    $resultOfOperation["volumeKernelInfo"]=$volumeKernelInfo 

    return $resultOfOperation 
} 

你可以調用它。