Как узнать, на каком томе находится данный путь NTFS при использовании точек монтирования? - PullRequest
1 голос
/ 03 августа 2009

У меня есть сервер Exchange с множеством точек монтирования. Учитывая путь к файлам базы данных, есть ли способ узнать, на каком томе они находятся? Проблема заключается в том, что они обычно находятся не в точке монтирования тома, а в глубине дерева. Я использую Powershell, поэтому мне нужно решение, предпочтительно с использованием WMI, но также можно использовать любые объекты .NET или COM.

Ответы [ 2 ]

2 голосов
/ 04 августа 2009

PSCX включает командлет Get-ReparsePoint:

C:\temp> Get-ReparsePoint d | ft -auto

Target                                           Path      ReparsePointTag
------                                           ----      ---------------
\??\Volume{a5908e7a-eca5-11dd-be98-005056c00008} C:\temp\d      MountPoint

Вы можете сопоставить GUID тома с известными именами дисков, используя реестр:

Get-ItemProperty HKLM:\SYSTEM\MountedDevices

[...]
\DosDevices\D:                                   : {22, 35, 171, 65...}
[...]
\??\Volume{a5908e7a-eca5-11dd-be98-005056c00008} : {22, 35, 171, 65...}

Собрав все вместе, мы можем получить серийный номер физического диска, который смонтирован в c: \ temp \ d:

$guid = (Get-ReparsePoint d).target
$serial = (get-itemproperty HKLM:\SYSTEM\MountedDevices).$guid

Вы можете сравнить этот серийный номер с серийными номерами других логических томов, например, с буквами DOS.

> function ArrayEqual([psobject[]]$arr1, [psobject[]]$arr2) 
      { @(Compare-Object $arr1 $arr2 -sync 0).Length -eq 0 }

> (gi HKLM:\SYSTEM\MountedDevices).property | ?{ $_ -like "\dos*" } | 
      ?{ ArrayEqual$serial (gp HKLM:\SYSTEM\MountedDevices).$_ }

\DosDevices\D:

См. Блог Кейта Хилла для объяснения функции сравнения массивов.

Для полноты обратите внимание, что это НЕ тот же самый серийный номер, о котором сообщает COM ...

> $comSerial = (new-object -com scripting.filesystemobject).getdrive("d")
> [bitconverter]::GetBytes($comSerial)
18
208
242
202
1 голос
/ 04 августа 2009

Я только что обнаружил атрибут ReparsePoint.

После захвата каталога, в котором я нахожусь, я могу пройтись по дереву, пока не доберусь до Root и по пути проверю ReparsePoints.

$dbDir = (get-item (Get-MailboxDatabase $db).edbfilepath).directory
$dbDir
if($dbdir.parent){
  #todo make this recursive
}

#test if it's a reparse point.    
if ($dbdir.attributes -band [System.IO.FileAttributes]::ReparsePoint ){
  #it's a mountpoint.
}

Отсюда есть инструмент "mountvol / L" или, что лучше, класс ассоциации WMI Win32_MountPoint и Win32_Volume.

Немного сложновато, но я не вижу простого способа просто спросить: «На каком я уровне?» Как только я соберу все это вместе, я выложу полное объяснение.

edit - подробнее здесь: http://slipsec.com/blog/?p=126

...