我尝试过 Diskpart 命令,例如“list”、“volume”(根本不是那样)、“disk”和“partition”;但它仍然不起作用。
\Device\Harddiskvolume0 似乎未被使用,因为 \Device\Harddiskvolume1 表示第一个 Windows 分区(又名“系统保留”),而 \Device\Harddiskvolume2 表示 C:。
所以问题是:如何列出 Windows 7 安装盘中的每个 \Device\Harddiskvolume(用于 BCD 编辑)?
答案1
我使用记录在微软。
它显示驱动器:
- 没有驱动器号
- 安装到文件夹
- 带有驱动器号
示例输出:
DriveLetter DevicePath VolumeName
----------- ---------- ----------
\Device\HarddiskVolume5 \\?\Volume{a2b4c6d8-0000-0000-00000100000000000}\
E:\ \Device\HarddiskVolume9 \\?\Volume{a2b4c6d8-1234-1234-1234-123456789abc}\
C:\Mounted\My-Folder-Mount\ \Device\HarddiskVolume13 \\?\Volume{a2b4c6d8-1234-1234-1234-123456789abc}\
PowerShell 脚本:
$signature = @'
[DllImport("kernel32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetVolumePathNamesForVolumeNameW([MarshalAs(UnmanagedType.LPWStr)] string lpszVolumeName,
[MarshalAs(UnmanagedType.LPWStr)] [Out] StringBuilder lpszVolumeNamePaths, uint cchBuferLength,
ref UInt32 lpcchReturnLength);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr FindFirstVolume([Out] StringBuilder lpszVolumeName,
uint cchBufferLength);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool FindNextVolume(IntPtr hFindVolume, [Out] StringBuilder lpszVolumeName, uint cchBufferLength);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax);
'@;
Add-Type -MemberDefinition $signature -Name Win32Utils -Namespace PInvoke -Using PInvoke,System.Text;
[UInt32] $lpcchReturnLength = 0;
[UInt32] $Max = 65535
$sbVolumeName = New-Object System.Text.StringBuilder($Max, $Max)
$sbPathName = New-Object System.Text.StringBuilder($Max, $Max)
$sbMountPoint = New-Object System.Text.StringBuilder($Max, $Max)
[IntPtr] $volumeHandle = [PInvoke.Win32Utils]::FindFirstVolume($sbVolumeName, $Max)
do {
$volume = $sbVolumeName.toString()
$unused = [PInvoke.Win32Utils]::GetVolumePathNamesForVolumeNameW($volume, $sbMountPoint, $Max, [Ref] $lpcchReturnLength);
$ReturnLength = [PInvoke.Win32Utils]::QueryDosDevice($volume.Substring(4, $volume.Length - 1 - 4), $sbPathName, [UInt32] $Max);
if ($ReturnLength) {
$DriveMapping = @{
DriveLetter = $sbMountPoint.toString()
VolumeName = $volume
DevicePath = $sbPathName.ToString()
}
Write-Output (New-Object PSObject -Property $DriveMapping)
}
else {
Write-Output "No mountpoint found for: " + $volume
}
} while ([PInvoke.Win32Utils]::FindNextVolume([IntPtr] $volumeHandle, $sbVolumeName, $Max));
答案2
找到一个列出已安装卷的 powershell 脚本:
# Biuild System Assembly in order to call Kernel32:QueryDosDevice.
$DynAssembly = New-Object System.Reflection.AssemblyName('SysUtils')
$AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run)
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('SysUtils', $False)
# Define [Kernel32]::QueryDosDevice method
$TypeBuilder = $ModuleBuilder.DefineType('Kernel32', 'Public, Class')
$PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('QueryDosDevice', 'kernel32.dll', ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static), [Reflection.CallingConventions]::Standard, [UInt32], [Type[]]@([String], [Text.StringBuilder], [UInt32]), [Runtime.InteropServices.CallingConvention]::Winapi, [Runtime.InteropServices.CharSet]::Auto)
$DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String]))
$SetLastError = [Runtime.InteropServices.DllImportAttribute].GetField('SetLastError')
$SetLastErrorCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor, @('kernel32.dll'), [Reflection.FieldInfo[]]@($SetLastError), @($true))
$PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute)
$Kernel32 = $TypeBuilder.CreateType()
$Max = 65536
$StringBuilder = New-Object System.Text.StringBuilder($Max)
Get-WmiObject Win32_Volume | ? { $_.DriveLetter } | % {
$ReturnLength = $Kernel32::QueryDosDevice($_.DriveLetter, $StringBuilder, $Max)
if ($ReturnLength)
{
$DriveMapping = @{
DriveLetter = $_.DriveLetter
DevicePath = $StringBuilder.ToString()
}
New-Object PSObject -Property $DriveMapping
}
}
来源: http://www.morgantechspace.com/2014/11/Get-Volume-Path-from-Drive-Name-using-Powershell.html
输出如下所示:
DevicePath DriveLetter
---------- -----------
\Device\HarddiskVolume2 F:
\Device\HarddiskVolume7 J:
\Device\HarddiskVolume10 D:
\Device\HarddiskVolume12 E:
\Device\HarddiskVolume5 C:
答案3
我无法完成任务的原因是 HarddiskVolume 没有反映 Diskpart 卷 - 它仅列出每个 Windows 可读卷。
事实上,它可以处理磁盘上每个可用的分区 - 甚至是非 Windows 分区 - 按照它们在 Linux 的 Gparted 中出现的顺序进行操作。
例如,如果在 sda3 之前有 sda4,则后者将显示为 -sda4 然后是 sda3-(HarddiskVolume4 然后是 HarddiskVolume3)。
所以,这意味着 HarddiskVolume0 在 BCD 中主要不存在。
帮助我理解这一点的命令是:
mountvol /L
bootsect /nt60 all /force -> Be careful with that one !!!
这些链接也帮助了我:
- https://neosmart.net/forums/threads/confusion-over-harddiskvolume.9841/
- https://digital-forensics.sans.org/blog/2015/08/19/device-profiling-with-windows-prefetch
- http://diddy.boot-land.net/bcdedit/files/device.htm
- https://discuss.howtogeek.com/t/windows-7-device-harddisk-to-physical-drive/10066/8
- https://translate.google.com/translate?sl=auto&tl=en&js=y&prev=_t&hl=en&ie=UTF-8&u=http%3A%2F%2Fwww.delphipraxis.net%2F186489-win7-%255Cdevice%255Charddiskvolume-n-wo-finde-ich-das.html&edit-text=&act=url
最后,如果你有多余的 Windows,只需运行驱动器号查看器了解 Windows 如何使用 HarddiskVolume。
注意:HarddiskVolume 是 WMI/COM 符号
答案4
更简单的方法如下。我还自定义了几个列。
请在 PowerShell 中运行以下命令:
Get-CimInstance win32_volume -ComputerName "Enter Your Computer Name, or Multiple Computer Names" | select @{n="ComputerName";e={$_.PSComputerName}},DriveLetter,@{n="Capacity(GB)";e={$_.Capacity / 1gb -as [int]}},@{n="Free(GB)";e={$_.FreeSpace / 1gb -as [int]}} | ft -AutoSize