虚拟移动硬盘
背景
目前的工作需要在虚拟机中进行,因为笔记本电脑配置不高,为了让虚拟机中的 win10 系统运行流畅,因此除了公司登陆内网的安全软件外,其余软件一概不装。但是这就带来一个问题,工作中需要使用的 office 办公软件虚拟机中没有安装,这时候就要将虚拟机中的文件拿到物理机中用 office 打开。当然,解决的方法多种多样,VMWare 虚拟机可以直接将文件复制出来,我现在用的 Hyper-V 的话可以通过共享文件的方式访问。我这里用的虚拟机是 win10 自带的 Hyper-V,直接复制文件出来的办法行不通,共享文件倒是可以实现,但是因为虚拟机里的工作环境装有公司的安全软件,如果开启共享,就无法连接到公司内网,所以这个方法也 pass 掉。怎么办?还有一个方法。创建一个 vhd 虚拟硬盘挂载到虚拟机中,用来存放工作中用到的文件,当需要在物理机中打开这些文件时,先卸载虚拟机中的 vhd,然后在挂载到物理机中,这就像是两台电脑之间通过移动硬盘传输文件一样,只不过这个移动硬盘是个“假的”。但是每次需要打开一个文件的时候,都要先在 Hyper-V 里操作卸载 vhd,然后又要在物理机中挂载这个 vhd,有些时候只是需要打开文件看一眼,也就几秒钟,但是这一系列操作下来花了 1 分钟,很繁琐。刚好这几天在学 PowerShell,就想到用它实现这些操作的自动化。
用到的 PowerShell 命令
获取 VHD:Get-VHD
获取虚拟机:Get-VM
获取虚拟机磁盘驱动器:Get-VMHardDiskDrive
增加一个磁盘驱动到虚拟机:Add-VMHardDiskDrive
删除磁盘驱动:Remove-VMHardDiskDrive
卸载 VHD:Dismount-VHD
装载一个或多个虚拟磁盘:Mount-VHD
打印信息到控制台:Write-Output
代码实现
if( $args.Length -ne 2 ){
Write-Output "请传入参数:虚拟机名称 VHD路径"
exit
}
$vmName = $args[0]
$vhdPath = $args[1]
$vhdObj = Get-VHD -Path $vhdPath
if (!$?) {
Write-Output "VHD不存在! ---> $vhdPath"
exit
}
$vmm = Get-VM -Name $vmName
# 判断虚拟机是否存在
if ($?) {
# 获取虚拟机中的虚拟磁盘驱动器
$vmHardDiskDriveList = Get-VMHardDiskDrive -VMName $vmName
# 判断是否已经挂着了“移动VHD”
foreach ( $vmHardDiskDrive in $vmHardDiskDriveList ) {
if ( $vmHardDiskDrive.Path -like $vhdObj.Path ) {
Write-Output "准备卸载虚拟机中的VHD,挂载到物理机..."
Remove-VMHardDiskDrive -VMName $vmName -ControllerType $vmHardDiskDrive.ControllerType -ControllerNumber $vmHardDiskDrive.ControllerNumber -ControllerLocation $vmHardDiskDrive.ControllerLocation
if ($?) {
Write-Output "虚拟机卸载VHD成功!准备挂载到物理机..."
} else {
Write-Output "虚拟机卸载VHD失败,退出脚本!"
exit
}
if (!$vhdObj.Attached -or ($null -eq $vhdObj.Number)) {
# 物理机挂载VHD
Mount-VHD -Path $vhdPath
if ($?) {
Write-Output "物理机挂载VHD成功!"
} else {
Write-Output "物理机挂载VHD失败,退出脚本!"
exit
}
} else {
Write-Output "物理机VHD已挂载,无需重复操作。"
}
exit
}
}
Write-Output "准备卸载物理机中的VHD,挂载到虚拟机..."
if ( $vhdObj.Attached ) {
Dismount-VHD -Path $vhdObj.Path
if ($?) {
Write-Output "物理机卸载VHD成功!准备挂载到虚拟机..."
} else {
Write-Output "物理机卸载VHD失败,退出脚本!"
exit
}
} else {
Write-Output "物理机VHD没有挂载!准备挂载到虚拟机..."
}
Add-VMHardDiskDrive -VMName $vmName -ControllerType SCSI -ControllerLocation $vmHardDiskDriveList.Length -Path $vhdObj.Path
if ($?) {
Write-Output "虚拟机挂载VHD成功!"
} else {
Write-Output "虚拟机挂载VHD失败,退出脚本!"
}
exit
} else {
Write-Output "虚拟机不存在! ---> $vmName"
exit
}
OK 了吗
代码写完了,但是执行却遇到麻烦。首先,默认情况下,脚本的运行策略是 Restricted,也就是不执行脚本,需要调整。第二,脚本必须以管理员身份运行,但是在脚本的右键菜单里并没有这个选项,属性中也没有这项设置。解决方法也简单:
1.需要调整计算机的脚本运行默认策略
将脚本执行策略调整为‘REMOTESIGNED’网络上下载的脚本执行需要签名,本地脚本执行不需要签名
Set-ExecutionPolicy -ExecutionPolicy REMOTESIGNED
2.需要以管理员方式运行,执行脚本
通过 bat 调用 ps 脚本,bat 脚本右键菜单中有“以管理员身份运行”
powershell.exe -file D:\MtK\PowerShell\自动化虚拟移动硬盘.ps1 "win10工作" "D:\Hyper-V\Virtual hard disks\移动虚拟硬盘.vhdx"
@pause
exit
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于