Bật Hyper-V trên Windows 11 và tạo máy ảo bằng PowerShell: Tips thực chiến cho lập trình viên

Virtualization tutorial - IT technology blog
Virtualization tutorial - IT technology blog

Vấn đề: Máy dev Windows nhưng CI/CD chạy Linux

Gần như mọi lập trình viên làm việc trên Windows đều quen thuộc với tình huống này: pipeline CI/CD chạy Ubuntu, server production là Debian, nhưng máy dev lại là Windows 11. Kết quả là “works on my machine” nhưng build fail trên server, hay script bash chạy tốt trên máy đồng nghiệp Mac nhưng lại báo lỗi ngay dòng đầu tiên.

Giải pháp thường thấy là WSL2 — và đúng là WSL2 tốt hơn nhiều so với trước. Nhưng WSL2 không phải VM thật. Không có kernel riêng độc lập, không test được network stack, không giả lập được môi trường multi-host. Chưa kể một số service yêu cầu systemd đầy đủ thì cài không được.

Mình chạy homelab với Proxmox VE quản lý 12 VM và container — đây là playground để test mọi thứ trước khi đưa lên production. Nhưng không phải lúc nào cũng muốn SSH vào server homelab chỉ để test nhanh một script. Khi cần môi trường Linux ngay trên máy Windows mà không cài thêm phần mềm nào, Hyper-V là thứ đã có sẵn — chỉ cần bật lên là dùng.

Tại sao Hyper-V thay vì cài VirtualBox?

VirtualBox và VMware Workstation đều là Type-2 hypervisor — chạy bên trên Windows như một ứng dụng bình thường. Hyper-V là Type-1 hypervisor (bare-metal), nghĩa là Windows 11 của bạn thực ra đang chạy trên Hyper-V, không phải bên dưới nó.

So sánh trực tiếp trên cùng phần cứng:

  • Hiệu năng: VM Hyper-V dùng CPU virtualization trực tiếp, không qua lớp emulation. Khởi động Ubuntu 24.04 mất khoảng 8–10 giây so với 20–25 giây trên VirtualBox.
  • Tích hợp PowerShell: Toàn bộ vòng đời VM — tạo, snapshot, clone, xóa — đều quản lý được qua cmdlet, thích hợp để viết script tự động hóa.
  • Không xung đột: Chạy Hyper-V không cần tắt WSL2, Docker Desktop, hay Android Emulator như trước (Windows 11 đã fix từ build 22H2).

Nhược điểm cần biết: Hyper-V chỉ có trên Windows 11 Pro, Enterprise, và Education. Dùng Windows 11 Home thì cần upgrade license hoặc quay về VirtualBox.

Kiểm tra và bật Hyper-V

Kiểm tra CPU hỗ trợ virtualization

Chạy PowerShell với quyền Administrator:

# Kiểm tra CPU có hỗ trợ virtualization không
Get-ComputerInfo -Property HyperV*

# Hoặc dùng systeminfo để xem nhanh
systeminfo | findstr /C:"Hyper-V"

Nếu thấy HyperVisorPresent: False và CPU hỗ trợ virtualization, vào BIOS/UEFI bật Intel VT-x (Intel) hoặc AMD-V/SVM (AMD). Tên menu tùy mainboard nhưng thường nằm trong tab Advanced → CPU Configuration.

Bật Hyper-V qua PowerShell

# Bật Hyper-V và các công cụ đi kèm (cần quyền Admin, yêu cầu reboot)
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All -All

# Sau khi reboot, kiểm tra lại
Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V | Select-Object State

Máy khởi động lại xong, Start Menu có thêm Hyper-V Manager và các cmdlet Hyper-V trong PowerShell là dùng được ngay.

Tạo máy ảo Linux bằng PowerShell

Chuẩn bị: Tạo Virtual Switch

Trước khi tạo VM, cần có virtual switch để VM kết nối mạng. Có hai loại phổ biến:

  • External: VM có IP riêng trên LAN nhà bạn, ping được từ máy khác. Dùng khi cần test ứng dụng từ điện thoại hay máy khác.
  • Internal: VM chỉ giao tiếp được với host Windows, không expose ra ngoài. An toàn hơn cho môi trường dev.
# Xem adapter mạng vật lý đang có
Get-NetAdapter | Where-Object {$_.Status -eq "Up"}

# Tạo External Switch (thay "Wi-Fi" bằng tên adapter thực tế)
New-VMSwitch -Name "ExternalSwitch" -NetAdapterName "Wi-Fi" -AllowManagementOS $true

# Hoặc tạo Internal Switch (không cần adapter vật lý)
New-VMSwitch -Name "InternalSwitch" -SwitchType Internal

Tạo VM Ubuntu 24.04

Tải ISO Ubuntu Server về, rồi chạy theo thứ tự:

# Định nghĩa biến cho gọn
$VMName    = "ubuntu-dev"
$VMPath    = "D:\Hyper-V\VMs"
$ISOPath   = "D:\ISOs\ubuntu-24.04-live-server-amd64.iso"
$VHDSize   = 40GB

# Tạo VM Generation 2 (UEFI, cho Linux hiện đại)
New-VM `
  -Name $VMName `
  -Path $VMPath `
  -Generation 2 `
  -MemoryStartupBytes 2GB `
  -SwitchName "ExternalSwitch"

# Tạo ổ đĩa ảo (dynamic VHDX)
New-VHD -Path "$VMPath\$VMName\$VMName.vhdx" -SizeBytes $VHDSize -Dynamic
Add-VMHardDiskDrive -VMName $VMName -Path "$VMPath\$VMName\$VMName.vhdx"

# Gắn ISO
Add-VMDvdDrive -VMName $VMName -Path $ISOPath

# Cấu hình boot từ DVD trước
$DVDDrive = Get-VMDvdDrive -VMName $VMName
Set-VMFirmware -VMName $VMName -FirstBootDevice $DVDDrive

# Tắt Secure Boot (bắt buộc cho Linux nếu không có shim)
Set-VMFirmware -VMName $VMName -EnableSecureBoot Off

# Bật Dynamic Memory (tiết kiệm RAM khi VM idle)
Set-VMMemory -VMName $VMName -DynamicMemoryEnabled $true -MinimumBytes 512MB -MaximumBytes 4GB

# Gán 2 CPU core
Set-VMProcessor -VMName $VMName -Count 2

# Khởi động VM
Start-VM -Name $VMName

# Mở console để cài đặt
VMConnect localhost $VMName

Tips quan trọng: Bật Integration Services

Bước hay bị bỏ qua nhưng quan trọng: bên trong VM Ubuntu vừa cài xong, chạy lệnh dưới để bật Hyper-V Integration Services. Thiếu nó, copy-paste sẽ không hoạt động, đồng hồ VM bị lệch, và host không thể graceful shutdown:

# Trên Ubuntu guest
sudo apt update && sudo apt install -y linux-image-virtual linux-tools-virtual linux-cloud-tools-virtual
sudo systemctl enable hv_kvp_daemon hv_vss_daemon
sudo reboot

Quản lý VM hàng ngày bằng PowerShell

Đây là phần mình dùng nhiều nhất — thay vì click trong Hyper-V Manager, viết script một lần dùng mãi:

# Xem trạng thái tất cả VM
Get-VM | Select-Object Name, State, CPUUsage, MemoryAssigned, Uptime

# Start / Stop / Suspend
Start-VM -Name "ubuntu-dev"
Stop-VM -Name "ubuntu-dev" -Force          # Tắt cứng
Stop-VM -Name "ubuntu-dev" -TurnOff:$false  # Shutdown sạch (cần integration services)
Suspend-VM -Name "ubuntu-dev"               # Hibernate VM

# Snapshot (checkpoint)
Checkpoint-VM -Name "ubuntu-dev" -SnapshotName "before-upgrade-$(Get-Date -Format 'yyyyMMdd')"
Get-VMSnapshot -VMName "ubuntu-dev"
Restore-VMSnapshot -VMName "ubuntu-dev" -Name "before-upgrade-20260616"

# Xóa snapshot cũ (giải phóng disk)
Remove-VMSnapshot -VMName "ubuntu-dev" -Name "before-upgrade-20260616"

# Clone VM bằng cách export/import
Export-VM -Name "ubuntu-dev" -Path "D:\Hyper-V\Exports"
Import-VM -Path "D:\Hyper-V\Exports\ubuntu-dev\Virtual Machines\*.vmcx" -Copy -GenerateNewId

Cách tốt nhất: Kết hợp Hyper-V với script tự động hóa

Tạo VM thủ công kiểu đó lần nào cũng mất 15–20 phút — phần lớn là click, đợi wizard, click tiếp. Mình gom hết vào script New-DevVM.ps1, cả quá trình xuống còn khoảng 2 phút:

# New-DevVM.ps1 — Tạo VM Ubuntu dev environment nhanh
param(
  [string]$Name = "ubuntu-$(Get-Date -Format 'MMdd')",
  [int]$CPUCount = 2,
  [long]$RAMBytes = 2GB,
  [long]$DiskBytes = 40GB,
  [string]$ISOPath = "D:\ISOs\ubuntu-24.04-live-server-amd64.iso",
  [string]$VMBasePath = "D:\Hyper-V\VMs",
  [string]$SwitchName = "InternalSwitch"
)

$VHDPath = "$VMBasePath\$Name\$Name.vhdx"

New-VM -Name $Name -Path $VMBasePath -Generation 2 -MemoryStartupBytes $RAMBytes -SwitchName $SwitchName
New-VHD -Path $VHDPath -SizeBytes $DiskBytes -Dynamic
Add-VMHardDiskDrive -VMName $Name -Path $VHDPath
Add-VMDvdDrive -VMName $Name -Path $ISOPath
Set-VMFirmware -VMName $Name -FirstBootDevice (Get-VMDvdDrive -VMName $Name) -EnableSecureBoot Off
Set-VMProcessor -VMName $Name -Count $CPUCount
Set-VMMemory -VMName $Name -DynamicMemoryEnabled $true -MinimumBytes 512MB -MaximumBytes ($RAMBytes * 2)

Write-Host "[OK] VM '$Name' created. Starting..."
Start-VM -Name $Name
VMConnect localhost $Name

Gọi như này:

# Tạo VM với tên tự động
.\New-DevVM.ps1

# Tạo VM tùy chỉnh
.\New-DevVM.ps1 -Name "test-nginx" -CPUCount 4 -RAMBytes 4GB

Kết nối SSH thay vì dùng console

Hyper-V Manager console khá clunky — input lag, không scroll được lịch sử lệnh. Bật SSH ngay trong VM, rồi kết nối từ Windows Terminal:

# Trên Ubuntu guest — bật SSH
sudo apt install -y openssh-server
sudo systemctl enable --now ssh

# Lấy IP của VM
ip -4 addr show eth0
# Trên Windows host — lấy IP VM qua PowerShell
(Get-VMNetworkAdapter -VMName "ubuntu-dev").IPAddresses

# SSH vào VM
ssh [email protected]

Những lỗi thường gặp và cách xử lý

  • “Hyper-V cannot be installed: A hypervisor is already running”: Thường do Docker Desktop đang dùng WSL2 backend. Thử restart lại máy hoặc kiểm tra trong Task Manager xem có process vmwp.exe nào đang chạy không.
  • VM tạo xong không boot được ISO: Với Generation 2 và Linux, nhớ tắt Secure Boot (Set-VMFirmware -EnableSecureBoot Off) hoặc chọn CA certificate phù hợp.
  • VM bị mất mạng sau suspend: Lỗi cũ của Hyper-V, vẫn xuất hiện đôi khi. Fix bằng cách restart network adapter trong VM (sudo ip link set eth0 down && sudo ip link set eth0 up) hoặc bật hv_netvsc driver.
  • VHDX phình to sau nhiều snapshot: Dùng Optimize-VHD -Path path\to.vhdx -Mode Full định kỳ để compact file.

Share: