在 Hyper-V Windows 虚拟机中共享物理机的显卡算力,是提升虚拟机能力的重要手段。尽管互联网上能查到相关教程,但是实际体验下来,并不容易。本文介绍一个一键脚本,帮助你轻松完成共享显卡的操作。
最近在研究 Hyper-V 中安装 Ubuntu 并开启 VGPU 的方法。尽管还没有掌握这个技术,但是意外发现了一个神级脚本,可以轻松安装 Hyper-V Windows 系统 VGPU。
这个脚本的项目名称是
一、系统环境要求
-
操作系统:
- 宿主机:Windows 10/11 专业版(21H2或更新)或 Windows Server 2022
- 虚拟机:Windows 10/11 企业版(需启用Hyper-V集成服务)
-
硬件要求:
- 支持DirectX 12的独立显卡(NVIDIA 10系+/AMD RX 5000+)
- 预留至少2GB显存空间
- 虚拟机内存≥8GB
二、操作流程详解
步骤1:物理机操作
- 在物理机上安装好显卡驱动,确保能正常使用
- 在物理机上安装好虚拟机,确保能正常运行
- 将本文提供的代码保存为 PowerShell 脚本,名称为
,保存到物理机任意目录 - 在物理机上运行
- 按提示选择虚拟机、显卡,等待脚本运行
步骤2:虚拟机操作
- 在虚拟机 C 盘根目录找到
- 在
文件名上点击右键,选择“以管理员身份运行”
PowerShell 脚本
#region 初始化配置
# 修改执行策略允许运行签名脚本(需管理员权限)
Set-ExecutionPolicy RemoteSigned -Force
# 设置错误处理模式:遇到错误立即停止执行
$ErrorActionPreference = "Stop"
#region 本地化配置
# 定义心跳服务和状态标签的默认值(英语)
$signalLabel = "HeartBeat"
$okLabel = "OK"
# 检测系统区域设置,如果是简体中文环境则替换为中文标签
if ((Get-WinSystemLocale).Name -eq "zh-CN") {
$signalLabel = "检测信号"
$okLabel = "确定"
}
#endregion
#region 虚拟机选择与预处理
# 通过图形界面选择目标虚拟机(单选框)
$vmobject = Get-VM | Out-GridView -Title "Select VM to setup GPU-P" -OutputMode Single
$vmid = $vmobject.VMId
# 停止虚拟机并进行预处理
Write-Host "Stopping VM"
$vmobject | Stop-VM -Force # 强制停止确保状态变更
Write-Host "Disabling checkpoints for VM"
$vmobject | Set-VM -CheckpointType Disabled # 禁用检查点
Write-Host "Enabling heartbeat service for VM"
$vmobject | Enable-VMIntegrationService -Name $signalLabel # 启用心跳服务
# 清理现有GPU分区适配器(如果存在)
if ($vmobject | Get-VMGpuPartitionAdapter) {
$vmobject | Remove-VMGpuPartitionAdapter
}
# 启动虚拟机并等待心跳服务就绪
Write-Host "Starting VM"
$vmobject | Start-VM
do {
Start-Sleep 2
$status = ($vmobject | Get-VMIntegrationService -Name $signalLabel).PrimaryStatusDescription
} while ($status -ne $okLabel) # 轮询等待服务状态变为"OK"
#endregion
#region 建立远程会话
Write-Host "Connecting to VM"
$vmsess = New-PSSession -VMId $vmid # 创建与虚拟机的PowerShell会话
#endregion
#region 物理GPU选择与驱动处理
# 通过图形界面选择物理GPU设备(单选框)
$dev = Get-PnpDevice -Class Display -Status OK | Out-GridView -Title "Select Card to setup GPU-P" -OutputMode Single
# 提取设备驱动信息
$props = $dev | Get-PnpDeviceProperty
$pnpinf = ($props | Where-Object {$_.KeyName -eq "DEVPKEY_Device_DriverInfPath"}).Data # 获取INF文件路径
$infsection = ($props | Where-Object {$_.KeyName -eq "DEVPKEY_Device_DriverInfSection"}).Data # 获取INF文件段落
$cbsinf = (Get-WindowsDriver -Online | Where-Object {$_.Driver -eq "$pnpinf"}).OriginalFileName # 获取系统驱动路径
# 验证驱动可用性
if (-not $cbsinf) {
Write-Host "Device not supported: $dev, inf: $pnpinf, cbs: $cbsinf"
exit 1
}
#region GPU路径处理
# 转换设备实例ID为Hyper-V可识别的路径格式
$gpuName = $dev.FriendlyName
$path = $dev.InstanceId.Replace('\', '#').ToLower() # 替换反斜杠并转小写
# 遍历可分区GPU列表进行路径匹配
$pvs = Get-VMHostPartitionableGpu
foreach ($pv in $pvs) {
$name = $pv.Name.ToLower()
if ($name.Contains($path)) {
$path = $pv.Name # 获取完整的设备路径
break
}
}
# 打印调试信息
Write-Host "============================"
Write-Host "Selected GPU: $gpuName"
Write-Host "INF File: $pnpinf"
Write-Host "Adapter Path: $path"
Write-Host "============================"
#endregion
#region 驱动文件复制
# 获取驱动文件信息
$inffile = (Get-Item -LiteralPath $cbsinf)
$drvpkg = $inffile.Directory # 驱动包目录
# 在虚拟机中创建驱动存储目录
$hostdrvstorepath = Invoke-Command -Session $vmsess {
New-Item -Path "$env:SystemRoot\System32\HostDriverStore\FileRepository" -ItemType Directory -Force
}
# 复制驱动文件到虚拟机
Write-Host "Copying driver package [$($drvpkg.FullName)] to VM..."
Copy-Item -LiteralPath $drvpkg.FullName -ToSession $vmsess -Destination $hostdrvstorepath -Recurse -Force
# 构建虚拟机内的完整INF文件路径
$vminfpath = Join-Path (Join-Path $hostdrvstorepath $drvpkg.Name) $inffile.Name
#endregion
#region 生成自动化脚本
# 在虚拟机系统盘创建初始化批处理文件
Invoke-Command -Session $vmsess -ScriptBlock {
if (-not $prologWritten) {
# 批处理文件头:创建临时目录
Set-Content -LiteralPath "$env:SystemDrive\GPUPAdditionalSetup.bat" -Encoding UTF8 -Value @"
cd /d %TEMP%
set dirname=gpupaddlsetup%RANDOM%
mkdir %dirname%
cd %dirname%
"@
$prologWritten = $true
}
# 添加驱动安装命令
Add-Content -LiteralPath "$env:SystemDrive\GPUPAdditionalSetup.bat" -Encoding UTF8 -Value "start `"`" /wait rundll32 advpack.dll,LaunchINFSectionEx $using:vminfpath,$using:infsection,,4"
}
# 添加批处理文件尾部清理命令
$scriptWritten = Invoke-Command -Session $vmsess -ScriptBlock {
if ($prologWritten) {
Add-Content -LiteralPath "$env:SystemDrive\GPUPAdditionalSetup.bat" -Encoding UTF8 -Value @"
cd ..
rmdir /s /q %dirname%
"@
}
return $prologWritten
}
#endregion
#region 最终配置
# 再次停止虚拟机进行GPU分区配置
Write-Host "Stopping VM"
$vmobject | Stop-VM -Force
# 配置GPU-P分区适配器
Write-Host "Configuring GPU-P for VM"
$vmobject | Add-VMGpuPartitionAdapter -InstancePath "$path" # 添加GPU分区适配器
# 设置VRAM、编解码和计算资源分配(单位:字节)
$vmobject | Set-VMGpuPartitionAdapter `
-MinPartitionVRAM 80000000 `
-MaxPartitionVRAM 100000000 `
-OptimalPartitionVRAM 100000000 `
-MinPartitionEncode 80000000 `
-MaxPartitionEncode 100000000 `
-OptimalPartitionEncode 100000000 `
-MinPartitionDecode 80000000 `
-MaxPartitionDecode 100000000 `
-OptimalPartitionDecode 100000000 `
-MinPartitionCompute 80000000 `
-MaxPartitionCompute 100000000 `
-OptimalPartitionCompute 100000000
# 配置虚拟机内存映射参数
$vmobject | Set-VM `
-GuestControlledCacheTypes $true `
-LowMemoryMappedIoSpace 1GB `
-HighMemoryMappedIoSpace 32GB
Write-Host "Done"
# 显示后续操作提示
if ($scriptWritten) {
Write-Host "重要提示:请以管理员身份在虚拟机中运行系统盘根目录的 GPUPAdditionalSetup.bat 文件以完成驱动安装。"
Write-Host "该操作将启用视频编解码器和图形计算API支持。"
}
#endregion