Windows 7 命令脚本通过 DiskPart 挂载具有指定驱动器号的 VHD 磁盘

Windows 7 命令脚本通过 DiskPart 挂载具有指定驱动器号的 VHD 磁盘

我使用VHD diskDropbox 将文件存储在办公室电脑上。

我需要在启动时自动加载 .vhd,即我只需输入,而不必一直decode password使用Disk Manager工具例如引导这里

我的谷歌搜索想出了DiskPart命令;虽然我无法drive letter在没有指定volume id参数的情况下进行设置。更多谷歌搜索出现了此主题,尽管使用 Powershell 对我来说不是原生/受欢迎的方式。我需要一个可以正常工作的原生 Windows 命令。

所以我的问题是,调用 DiskPart 时如何获取volume id已安装的 VHD 磁盘?目前我必须将其设置为 3,这仅适用于我的 PC。

附言

  1. 不寻找 Powershell 脚本
  2. 我的DiskPart脚本可以在这里查看1),2)卸载

答案1

我使用很久以前在互联网上找到的一个脚本。

该脚本(MountVHD.cmd)生成一个 diskpart 脚本,然后使用您指定的路径和驱动器号通过生成的脚本调用 diskpart。

该脚本接受两个参数:

MountVHD.cmd \path\to\vhdfile.vhd X

其中 X: 是要分配的驱动器号。

然后,您可以创建另一个命令脚本,使用上面的命令行调用该脚本,并将该调用脚本放在启动文件夹中。

@echo off
setlocal enabledelayedexpansion

if {%1}=={} (
    echo Usage: %~nx0 [vhd] [letter]
    exit /b 1
)
set vhdPath=%~dpnx1
set driveLetter=%2

if {!driveLetter!}=={} (
    echo Mounting !vhdPath!
) else (
    echo Mounting !vhdPath! to !driveLetter!:
)

REM
REM create diskpart script
REM
set diskPartScript=%~nx0.diskpart
echo sel vdisk file="!vhdPath!">!diskPartScript!
echo attach vdisk>>!diskPartScript!

REM assign the drive letter if requested
if not {!driveLetter!}=={} (
    echo select partition 1 >>!diskPartScript!
    echo assign letter=!driveLetter!>>!diskPartScript!
)

REM Show script
echo.
echo Running diskpart script:
type !diskPartScript!

REM
REM diskpart
REM
diskpart /s !diskPartScript!
del /q !diskPartScript!

echo Done!

endlocal

答案2

我也遇到过类似的情况,希望这能对你有所帮助......

我将旧工作站的 C 盘备份到驱动器标签为“Old_BG7”的 VHD。VHDX 文件目前位于我的数据中心的服务器上(\\bgserver\e$\Backup\NetOpsBG7_C$.vhdx)。我希望每次登录时都将此虚拟磁盘安装为我的 E: 驱动器。但是,我遇到的问题是 Diskpart 并不总是为我的虚拟磁盘分配相同的卷号。

以下是我为解决该问题所采取的措施,到目前为止,它对我很有用。

我创建了一个运行批处理脚本的计划任务(C:\用户\BG\AppData\Roaming\BG_Stuff\NetOpsBG7_E$.cmd) 以提升的权限登录。该批处理脚本如下所示:

@echo off

diskpart /s "%userprofile%\AppData\Roaming\BG_Stuff\NetOpsBG7_C$.cfg"

for /f "tokens=2,3* delims= " %%i in ('echo list volume ^| diskpart ^| find /i "Old_BG7"') do if not %%j==E (echo select volume=%%i>"%userprofile%\AppData\Roaming\BG_Stuff\tmpScript.cfg" && echo assign letter=E>>"%userprofile%\AppData\Roaming\BG_Stuff\tmpScript.cfg" && echo exit>>"%userprofile%\AppData\Roaming\BG_Stuff\tmpScript.cfg" && diskpart /s "%userprofile%\AppData\Roaming\BG_Stuff\tmpScript.cfg" && del /q "%userprofile%\AppData\Roaming\BG_Stuff\tmpScript.cfg")

exit 0

批处理脚本中的第一个命令调用此标准 diskpart 脚本(C:\用户\BG\AppData\Roaming\BG_Stuff\NetOpsBG7_C$.cfg):

select vdisk file="\\bgserver\e$\Backup\NetOpsBG7_C$.vhdx"
attach vdisk
exit

然而,真正的魔力发生在批处理脚本的第二行。我将命令“list volume”回显到 Diskpart,通过“FIND”命令将该输出传输到管道以找到我的 VHD 磁盘标签“Old_BG7”,然后使用“FOR”返回两个变量:卷号和已安装 VHD 的驱动器号。然后“IF”命令接管并检查 VHD 的驱动器号是否与“E”匹配。如果匹配,它就会退出;但如果不匹配,它会写入、执行然后删除临时的 Diskpart 脚本 (C:\用户\BG\AppData\Roaming\BG_Stuff\tmpScript.cfg)。

例如,如果 VHD 分配的驱动器号是不是“E”,其卷号为5,那么tmp脚本看起来像:

select volume=5
assign letter=E
exit

希望这可以帮助...

-=B

答案3

在 Dawn Benton 的回答中,如果您使用带有 GPT 分区表的 vhd,则您的 vhd(x) 中将有 2 个分区:

  1. 第一个分区是保留分区,无法挂载
  2. 第二个分区是真正的数据分区

需要将脚本第26行的形式改为:

保留分区echo select partition 1 >>!diskPartScript!

数据分区echo select partition 2 >>!diskPartScript!

然后脚本就可以运行了!

答案4

事实:不可能编写一个单独的 diskpart 脚本来为已安装的 VHD 选择特定的驱动器号!

但是可以进行两次 diskpart 调用(使用两个脚本),由一个批处理或任何其他程序调用。

问题原因:似乎存在时间问题,至少在 Windows 7 等某些 Windows 版本中是如此。Diskpart 没有等到“连接”成功。

对于某些应用程序来说这似乎没有问题,因为一旦分配的驱动器号将在下次被记住,因此您可以在第一次连接后在一台计算机上编写脚本。

但是,对于一个完整的独立脚本来说这还不够。如果你想避免使用 powershell,将其分成两个 diskpart 命令是实现自动化的唯一方法:

这里有一个脚本作为解决方案(由于某种原因,它避免使用“enabledelayedexpansion”,但这并不重要,如果您愿意,可以添加它并删除 goto 命令:-)

该脚本即使没有参数也能正常工作。它有一些不错的功能,例如

  • 如果没有给出,它只会查找 .vhd 名称本身:-)
  • 它在 %TEMP% 目录中创建 diskpart 脚本,因为不能保证您对脚本所在的位置具有写访问权限(并且它更干净)。

需要提一下的是:由于驱动器号是已更改在第二次 diskpart 调用期间,Windows 资源管理器中可能会显示旧字母的“影子条目”,直到再次打开资源管理器窗口。

@echo off

pushd "%~dp0"
set thisPath=%~dp0
setlocal

REM
REM Determining parameters
REM
REM You can specify the path to a specific vhd file in parameter 1, but you don't have to. Script will take 1st .vhd file found.
REM You can specify the driveletter - without colon - in parameter 2, but you don't have to. Script will take free drive letter found.
set vhdPath=%~dpnx1
set driveletter=%2
echo ThisPath: "%thisPath%"
if {%vhdPath%}=={} echo No specific VHD mentioned- will take first VHD file..

if not {%vhdPath%}=={} goto SpecificVHD
set SearchPath=%thisPath%*.vhd
echo SearchPath: %SearchPath%
for %%I in ("%SearchPath%") do (
   rem echo File: "%%I"
   set vhdpath=%%I
   if exist "%%I" goto outloop
)
:outloop
:SpecificVHD
echo.
if not exist %vhdpath% (
   echo Error! No .vhd file found in '%thisPath%' !
   exit /B 1
)

echo VHD path: %vhdpath%
rem pause

if {%driveLetter%}=={} (
    set Text=Mounting %vhdPath%
) else (
    set Text=Mounting %vhdPath% to %driveLetter%:
)
echo %Text%
echo.

REM
REM Create diskpart script
REM
set diskPartScript=%TEMP%\%~n0.diskpart
echo Creating diskpart script: '%diskPartScript%'
rem exit /B 0
rem pause

echo sel vdisk file="%vhdPath%">"%diskPartScript%"
echo attach vdisk>>"%diskPartScript%"

REM
REM diskpart Part 1
REM
diskpart /s "%diskPartScript%"
del /q "%diskPartScript%"

REM Assign the drive letter if given
REM [it is assumed, that only 1 partition exists in the VHD]
if {%driveLetter%}=={} goto noSpecificDriveLetter
   echo sel vdisk file="%vhdPath%">"%diskPartScript%"
   echo select partition 1 >>"%diskPartScript%"
   echo assign letter=%driveLetter%>>"%diskPartScript%"

REM timeout is not necessary on my system, but could be useful, so specified here
REM timeout /T 1 /nobreak

REM
REM diskpart Part 2
REM
diskpart /s "%diskPartScript%"
del /q "%diskPartScript%"

:noSpecificDriveLetter
echo Done.
popd
endlocal
pause

相关内容