使用挂载点时,如何找出给定 NTFS 路径所在的卷?

发布于 2024-08-01 14:30:43 字数 148 浏览 3 评论 0原文

我有一个带有很多安装点的 Exchange 服务器。 给定数据库文件的路径,有没有办法找出它们所在的卷? 问题是它们通常不在卷安装点,而是在树的更下方。 我使用的是 Powershell,因此我需要一个最好使用 WMI 但也可以使用任何 .NET 或 COM 对象的解决方案。

I have an Exchange server with lots of mountpoints. Given the path to the database files is there a way to find out what volume they are on? The problem is that they are typically not at the volume mount point, but further down the tree. I'm using Powershell, so I need a solution preferably using WMI but could also use any .NET or COM objects.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

○闲身 2024-08-08 14:30:43

PSCX 包括 Get-ReparsePoint cmdlet:

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:

有关数组比较函数的说明,请参阅 Keith Hill 的博客

为了完整起见,请注意这似乎与 COM 报告的序列不同...

> $comSerial = (new-object -com scripting.filesystemobject).getdrive("d")
> [bitconverter]::GetBytes($comSerial)
18
208
242
202

PSCX includes a Get-ReparsePoint cmdlet:

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

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

You can map volume GUIDs to familiar drive names using the registry:

Get-ItemProperty HKLM:\SYSTEM\MountedDevices

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

Putting things together, we can get the serial # of the physical drive that's mounted at c:\temp\d:

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

You can compare that serial against the serial numbers of the other logical volumes such as the ones with DOS letters.

> 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:

See Keith Hill's blog for an explanation of the array comparison function.

For completeness, note this does NOT seem to be the same serial reported by COM...

> $comSerial = (new-object -com scripting.filesystemobject).getdrive("d")
> [bitconverter]::GetBytes($comSerial)
18
208
242
202
橘虞初梦 2024-08-08 14:30:43

我刚刚发现了 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_MountPointWin32_Volume

有点复杂 - 但我没有看到一个简单的方法来问“我的音量是多少?” 一旦我将所有内容放在一起,我将发布完整的解释。

编辑 - 更多详细信息请参见:http://slipsec.com/blog/?p=126

I'd just discovered the ReparsePoint attribute.

After grabbing the directory I'm in, I can walk up the tree untill I get to Root and check for ReparsePoints along the way.

$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.
}

From here there's the "mountvol /L" tool, or better the WMI Association class Win32_MountPoint and Win32_Volume.

A bit involved- but I don't see a simple way to just ask "what volume am I on?" Once I get it all put together, I'll post a full explanation.

edit - more details here: http://slipsec.com/blog/?p=126

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文