Windows下免费的虚拟平台:Hyper-V

hyper-v与vmware ws各有优缺点,只有是否适合。

linux的kvm,windows的hyper-v,还有vm的esxi/ws,各有特点;hyper-v的场景,应该与esxi相同,而hyper-v之前的vpc与vm ws是同一个场景。

虚拟磁盘格式转换

转换之前先删除快照,后卸载增强工具(比如vmware tools/来宾服务/virt等)。

  1. diskgenius 克隆磁盘功能,支持按文件克隆,没有文件碎片,且已经删除的占用块,不会复制过来。
    • 缺点:vhdx/qcow2为只读支持,但为了缩小vhdx/qcow2文件体积,可以使用vmdk中转,再把vmdk转回vhdx/qcow2。
  2. StarWind V2V Converte:GUI操作,也支持P2V的转换。
  3. Qemu-img for Windows x64:CUI操作,v2.3,zip文件只有3.5M。
qemu-img.exe info put.vhdx # 获取磁盘映像信息
qemu-img -h | grep "Supported formats" # 支持的虚拟磁盘格式的类型
qemu-img convert input.vmdk -O vhdx output.vhdx # vmdk转vhxd,一般可以自动识别input.vmdk文件格式。
qemu-img convert -f 源类型 -O 目标类型 input.vmdk output.vhdx # 指定源格式转换。

Hyper-V 注意事项与优化

  1. 虚拟硬盘文件必须是未压缩和未加密的文件并且不能是稀疏文件。
    • 在ubuntu下使用qemu-img convert,从vmdk转换的vhdx,在启动时报错:虚拟硬盘文件必须是未压缩和未加密的文件并且不能是稀疏文件。但vhdx文件属性–高级–压缩与加密都没有选中,qemu-img版本是8.?。
    • 在Widows下使用qemu-img convert,从vmdk转换的vhdx,启动没有问题,qemu-img版本是2.3。
  2. linux虚拟主机的安全启动要设置为【Microsoft uefi证书颁发机构】,其他值启动不了;正确配置了启动顺序,还是会卡在 start pxe over ipv4。
  3. 在桌面场景下 ,同时,最多只会启动一个虚拟机,可考虑以下配置:
    • 关闭动态内存功能;
    • 使用静态Mac地址:网络适配器–高级功能–静态
    • 关闭自动检查点,但检查点功能保持启用;
    • 自动启动操作=无
    • 自动停止操作=关闭来宾操作系统
  4. 虚拟机系统中,使用远程usb设备的解决方案
    • 远程桌面的usb映射,但加密狗类usb无效
    • 使用三方 USB over IP 解决方案,支持加密狗
  5. Hyper-V中host与guest文件共享:没有这个功能,要使用正常的网络传输,比如FTP/samba之类。
    • 另外,guest与host是相互共享了剪贴板的,或者使用共享磁盘。

Hyper-V 来宾服务的启用

官方文档,先在 Hyper-V 管理器的虚拟机[设置–>集成服务]中,勾选来宾服务;再根据不同的guest系统,做不同操作:

guest为早于 Windows Server 2016 和 Windows 10 (不含)

添加DVD驱动器设备,再到连接器启动后,使用菜单【操作–安装 Hyper-V 集成服务】进行安装。

guest为Windows 10或之后的版本

会自动启动来宾服务,可使用以下方法检查:

  • 在 services.msc 中, 查找以 Hyper-V 开头的服务,右键单击要启动或停止的服务。
  • 在 PowerShell 中,启动或停止集成服务。
PS C:\> Get-Service -Name vmic* | FT -AutoSize

Status  Name               DisplayName
------  ----               -----------
Running vmicguestinterface Hyper-V Guest Service Interface
Running vmicheartbeat      Hyper-V Heartbeat Service
Running vmickvpexchange    Hyper-V Data Exchange Service
Running vmicrdv            Hyper-V 远程桌面虚拟化服务
Running vmicshutdown       Hyper-V Guest Shutdown Service
Running vmictimesync       Hyper-V Time Synchronization Service
Stopped vmicvmsession      Hyper-V PowerShell Direct Service
Running vmicvss            Hyper-V 卷影复制请求程序

运行 Start-Service 或 Stop-Service。 例如,若要关闭 Windows PowerShell Direct,请运行:

Stop-Service -Name vmicvmsession

检查来宾的集成服务版本(通过WIN自动更新服务升级):

REG QUERY "HKLM\Software\Microsoft\Virtual Machine\Auto" /v IntegrationServicesVersion

guset为Linux

通过 Linux 内核提供,集成服务驱动程序称为hv_utils。

lsmod | grep hv_utils # 是否加载了hv_utils
compgen -c hv # 哪些守护程序可用
ps -ef | grep hv # 守护程序是否正在运行

如果缺少以下任何关键内容,则可能是系统不支持,或者可能尚未安装。(安装好后,实际多于3个)

  • hv_vss_daemon:创建实时 Linux 虚拟机备份需要此守护程序。
  • hv_kvp_daemon:此守护程序允许设置和查询内部和外部密钥值对。
  • hv_fcopy_daemon:此守护程序在主机和来宾之间实现文件复制服务。

guset 使用固定IP 地址

Hyper-V 的默认交换机(Default Switch)无法直接设置固定IP,在Host上也没有单独网卡,因为其网关地址会在主机重启后动态变化;但可以在管理器的主机网络页,看到具体ip地址。

guest两个网卡的实现方法

  1. 创建Hyper-V内部交换机,命名为Internal Switch;会在Host上增加一个网卡,名为【vEthernet (Internal Switch)】,设置IP地址与掩码(比如:192.168.7.25/24),不需要配置网关与DNS。
  2. 在guest上,挂两个网卡Default Switch(用于外网访问)、Internal Switch(用于内部通信)。
    • 如果只想挂一个网卡,在Host上将Internal Switch开启网络共享。
  3. 在guest上配置Internal Switch网卡,设置IP地址与掩码(比如:192.168.7.10/24),不需要配置网关与DNS。
# Windows PowerShell
Get-NetAdapter | FT -autosize
New-NetIPAddress -InterfaceIndex 5 -IPAddress 192.168.7.10 -PrefixLength 24

#Rocky Linux

guset一个网卡的实现方法:vmsetip.ps1

方法一:创建Hyper-V内部交换机,命名为Internal Switch;在Host上,将Internal Switch开启网络共享。

方法二:前提在Host上,vEthernet (Default Switch)网卡可操作。

<#
Set-ExecutionPolicy RemoteSigned	# 让powershell 可以不受限制地运行本地脚本,但从Internet下载的脚本,必须有签名才能运行。
Get-NetAdapter -Name "vEthernet (Default Switch)" | select Name, ifIndex	# 指定名称的记录,显示指定字段
$Age = Read-Host "Please enter your age"	# 将控制台输入,保存到变量Age
#>

# 从Get-NetAdapter中,获取Name="vEthernet (Default Switch)"的记录中,ifIndex字段值,赋给变量NAId,且显示变量NAId内容。
$NAName = "vEthernet (Default Switch)"
$NAId = (Get-NetAdapter | Where-Object { $_.Name -eq "$NAName"}).ifIndex
#Write-Output "$NAName ifIndex:$NAId"

$NAIPv4 = "172.17.96.1"
$NAPL = 20
$IPValue = (Get-NetIPAddress -InterfaceIndex $NAId -AddressFamily IPv4 | Where-Object { $_.IPAddress -eq "$NAIPv4"}).IPAddress
# 空值判断,关于 if 语句的各项须知内容:https://learn.microsoft.com/zh-cn/powershell/scripting/learn/deep-dives/everything-about-if
IF ($null -eq $IPValue) {
  # 附加IP地址到网卡上,替换的话要先执行: Remove-NetIPAddress -InterfaceIndex $NAId -AddressFamily IPv4 -IPAddress $(Get-NetIPAddress -InterfaceIndex $NAId -AddressFamily IPv4).IPAddress -Confirm:$false
  New-NetIPAddress -InterfaceIndex $NAId -AddressFamily IPv4 -IPAddress $NAIPv4 -PrefixLength $NAPL
} 
Get-NetIPAddress -InterfaceIndex $NAId -AddressFamily IPv4 | Format-Table -AutoSize

guest分辨率调整

windows guest直接在guest中调整就可以,但ubuntu guest是无法在guest中调整分辨率,默认是1024*768,在Host powershell上执行:

# 调整分辨率为1280*800
Set-VMVideo -VMName $VMName -HorizontalResolution 1280 -VerticalResolution 800 -ResolutionType Single

不用改 /etc/default/grub 中

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash video=hyperv_fb:1280x800"

而且微软提交新的 hyperv_drm 驱动,发行版本里不一定有 hyperv_fb 模块

Hyper-V 的端口占用

Hyper-V安装后,打开 ssh -D 1080,报错:

channel_setup_fwd_listener_tcpip: cannot listen to port: 1080
Could not request local forwarding.

使用 tcpview64 和 [netstat -ano|findstr “:1080”]都没有被占用,使用 ssh -D 10800 成功。

网上搜索,疑似与Hyper-V 的端口有关,但也没有找到证据。

C:\>netsh interface ipv4 show excludedportrange protocol=tcp

协议 tcp 端口排除范围

开始端口    结束端口
----------    --------
      1032        1131
      1132        1231
      1232        1331
      1332        1431
      1444        1543
      1615        1714
     50000       50059     *

* - 管理的端口排除。

C:\>netsh interface ipv4 show dynamicportrange protocol=tcp

协议 tcp 动态端口范围
---------------------------------
启动端口        : 1024
端口数          : 13977

PowerShell 管理 Hyper-V

  • 前提:以 Hyper-V 管理员身份打开PowerShell
  • 虚拟机列表:Get-VM
  • 启动虚拟机:Start-VM -Name TestVM
  • 关闭虚拟机:Stop-VM -Name TestVM [-Force|-TurnOff] -Force为强制关闭应用,-TurnOff为断电源。
  • 查看命令列表:Get-Command -Module hyper-v | Out-GridView

vmm.ps1

#Requires -RunAsAdministrator
#Requires -Modules Hyper-V
$VMName = $args[0]

# 获取所有虚拟机
$allVMs = Get-VM | Select-Object Name, State, Status

# 无参数运行时显示虚拟机列表 if (-not $PSBoundParameters.ContainsKey('VMName')) {
if ( $null -eq $VMName ) {
    $allVMs | Format-Table -AutoSize
    exit
}

# 检查目标虚拟机是否存在
$targetVM = $allVMs | Where-Object { $_.Name -eq $VMName }

if (-not $targetVM) {
    Write-Warning "虚拟机 '$VMName' 不存在,可用虚拟机列表:"
    $allVMs | Format-Table -AutoSize
    exit
}

# 根据虚拟机状态执行操作
switch ($targetVM.State) {
    'Off' {
        Write-Host "启动虚拟机: $VMName" -ForegroundColor Green
        Start-VM -Name $VMName -ErrorAction Stop
    }
    'Running' {
        Write-Host "关闭虚拟机: $VMName" -ForegroundColor Yellow
        Stop-VM -Name $VMName -Force -Confirm:$false
    }
    default {
        Write-Host "虚拟机 '$VMName' 当前状态: $($targetVM.State)" -ForegroundColor Cyan
        Write-Host "详细状态: $($targetVM.Status)"
    }
}

# 显示操作后状态
Get-VM -Name $VMName | Select-Object Name, State, Status | Format-Table -AutoSize

在Host上,使用 PowerShell Direct 管理 Guest Windows

前提:1、host/guest 的Windows 在10+,2、guest开机且启用了 PowerShell Direct,3、以 Hyper-V 管理员身份打开Host PowerShell

  1. 使用 Enter-PSSession -VMName 或 Enter-PSSession -VMId 连接 guest的PowerShell
  2. 输入虚拟机的凭据,就可以了。
  3. 使用 Exit-PSSession 关闭会话

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注