我使用注册表项将一些文件夹映射为 Win11 计算机上的驱动器
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices
使用字符串值,例如
X:=\??\C:\some\folder
在大多数情况下,它都能完美地运行,并允许我拥有多个在单个磁盘分区中共享空间的“驱动器”。
尽管如此,一些程序(例如 git)能够“看到”实际的驱动器位置(例如,X:\Foo
变成C:\some\folder\Foo
)。
C:\some\folder\Foo
我正在尝试编写一个 PowerShell 脚本,例如,当传递时可以用来生成X:\Foo
。
我尝试过使用 Get-Item、Split-Path,转换为 UNC(使用概述的方法这里),但似乎没有什么可以揭开将驱动器号映射到文件夹的这种方法的面纱。
我是否遗漏了一些显而易见的东西?
==========================
更多详细信息,添加于 2024-01-16:
卷映射文件夹位于使用 VeraCrypt 安装的驱动器内。 在我的情况下,驱动器是 D - 奇怪的是,它没有出现在 的输出中Get-Volume
。 也许这是因为Get-Volume
文档中的这条注释:“动态卷仅受以下 cmdlet 支持:基本磁盘和存储空间上的 Repair-Volume (chkdsk)、Optimize-Volume (defrag) 和 Format-Volume (format)。 ”
> Get-Volume
DriveLetter FriendlyName FileSystemType DriveType HealthStatus OperationalStatus SizeRemaining Size
----------- ------------ -------------- --------- ------------ ----------------- ------------- ----
C Windows NTFS Fixed Healthy OK 807.6 GB 952.8 GB
Windows RE Tools NTFS Fixed Healthy OK 64.65 MB 814 MB
G New Volume NTFS Fixed Healthy OK 148.57 GB 909.15 GB
============================
注册表项详细信息,添加于 2024-03-05
以下是注册表项。除了此注册表项中的默认项外,还有三个映射驱动器(f:、p: 和 q:)。
答案1
2024-03-05
在注册表路径上使用Get-ItemProperty
,将结果存储在PSObject
数据类型的变量中。使用条件逻辑和匹配运算符对其进行迭代。然后,访问每个所需的属性PSObject
,并进行相应的解析和重新格式化。
利用类似于此的逻辑方法应该可以提供洞察力,了解如何合并或改进流程以更好地满足您获取本地文件路径的要求。
注册表解析和字符串构建
$registryPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices";
$v = Get-ItemProperty -Path $registryPath;
foreach ($property in $v.PSObject.Properties) {
If ($property.Name -match ":"){$property.Value.Replace('\??\','')}
};
输出
笔记:根据提供的示例注册表设置。
D:\!Drives\F
D:\!Drives\P
D:\!Drives\Q
原文不足建议的解决方案细节
这个潜在的解决方案本质上……
用途
Get-Volume
检索卷对象。用途
ForEach-Object
迭代对象,并合并If
语句仅包括那些具有空值的“驱动器号“ 并省略 ”系统保留“ 标签。创建一个变量来存储迭代的“文件系统标签“ 随后用于
calculated property
。让物体穿过
Get-Partition
通过管道和杠杆Select-Object
列出calculated properties
“文件系统标签“ 和 ”访问路径“。最后,它分裂“访问路径" 内
calculated property
以逗号作为分隔符,仅引用第一个[0]
索引来实现所需的输出。
电源外壳
Get-Volume | ForEach-Object {
If (!($_.DriveLetter) -and
$_.FileSystemLabel -ne "System Reserved"){
$fsl = $_.FileSystemLabel;
$_ | Get-Partition |
Select-Object @{n="FileSystemLabel";e={$fsl}},
@{n="AccessPaths";e={$_.AccessPaths.Split(',')[0]}}
}
} | Sort-Object FileSystemLabel;
输出示例
FileSystemLabel AccessPaths
--------------- -----------
TempDB1 T:\TempDB1\
TempDB2 T:\TempDB2\
TempDB3 T:\TempDB3\
TempDB4 T:\TempDB4\
TempDB5 T:\TempDB5\
TempDB6 T:\TempDB6\
TempDB7 T:\TempDB7\
TempDB8 T:\TempDB8\
TempDBLog T:\templog\
答案2
正如我在其中一条评论中提到的,我是 PowerShell 新手,但我确实设法找到了一种适合自己的解决方案。它特定于我的文件夹命名,但其他人应该能够根据自己的需求进行调整。可能还有更优雅的解决方案。
# Get the contents of the HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices
# key into a text string
$t = (Get-Item 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices') | Out-String
# Get the current working directory's drive letter and build the expected DOS Devices entry
$d = $pwd.drive.name
$s = '\??\D:\!Drives\' + $d
# Find the position of that DOS Devices entry in the registry key
$p = $t.IndexOf($s)
# Check if the string exists
if ($p -eq -1)
{
# Get out
Write-Output 'The current drive is not mapped in DOS Devices - nothing to do!'
exit
}
# Build git safe directory entry
$sd = 'D:\!Drives\' + $d + $pwd.path.SubString(2)
# Remove the entry, if it already exists - try with both forms of slashes
Write-Output 'Remove any previous entry (try with both forms of slashes)'
$e = 'git config --global --fixed-value --unset safe.directory ' + $sd
$e
iex $e
$e = $e -Replace '\\','/'
$e
iex $e
# Replace with new entry (replace back-slashes with forward slashes)
Write-Output 'Add new entry'
$e = 'git config --global --add safe.directory ' + $sd
$e = $e -Replace '\\','/'
$e
iex $e