以往的DOS命令提示字元在Windows的作業系統中只能夠提供一些簡單的輔助管理功能,例如基礎的檔案與資料夾的管理、執行Ping來測試網路連線狀態,或是執行Telnet命令工具來診斷網路連接埠或服務等等。
直到Windows PowerShell推出後,情況有了很大的變化,因為它不再只是一個簡單的輔助工具,而是一個能夠完全掌控整個作業系統、Active Directory、各種伺服器管理以及連接並管理第三方應用系統的強大命令工具,並且可以自行撰寫成因應各種情境需求的Script來達到自動化流程作業的管理目標。
關於PowerShell的使用方式,有多種可以選擇,內建部分可直接使用Windows PowerShell命令提示字元視窗,適合系統管理員用來快速執行命令。若要用來撰寫與測試Script,則可以使用Windows PowerShell ISE。
如果想要使用更強大的開源免費設計工具,則可以另外下載安裝Visual Studio Code工具(https://code.visualstudio.com/download),然後只要再搭配安裝PowerShell Extension延伸模組,如圖1所示,即可取代PowerShell ISE,提供更強大的Script編輯與除錯功能。除此之外,PowerShell也可安裝在Linux與macOS平台中的套件,讓跨平台的IT人員也能夠使用。

接下來,就以實戰講解的方式介紹如何善用PowerShell命令與自製Script,輕鬆化解Hyper-V在平日維運中的各類難題。
安裝PowerShell的Hyper-V模組
想要在PowerShell中以命令或Script來管理Hyper-V主機,不一定得在Hyper-V本機執行,只要使用的Windows電腦內有安裝PowerShell的Hyper-V模組即可。
至於具體的操作方法,以Windows Server 2025為例,只要在「新增角色及功能」開啟後,確認已在「功能」頁面中勾選「角色管理工具」→「Hyper-V管理工具」→「適用於Windows PowerShell的Hyper-V模組」完成安裝即可。
若使用的是Windows 10/11專業版作業系統,則先開啟「設定」中的「應用程式」管理頁面。緊接著,在「應用程式與功能」頁面中,點選「相關設定」區域內的「程式和功能」超連結。最後,點選「開啟或關閉Windows功能」超連結,並勾選「Hyper-V」→「Hyper-V管理工具」節點下的「適用於Windows PowerShell的Hyper-V模組」完成安裝即可。
如果想要使用PowerShell命令來安裝Hyper-V的完整管理工具,無論是在Windows Server 2025還是Windows 10/11,都只需要執行以下的命參數即可:
Add-WindowsFeature RSAT-Hyper-V-
Tools -IncludeAllSubFeature
學會PowerShell命令基本技巧
若要深入瞭解特定的PowerShell命令用法,可以善用Get-Help命令。例如,想要知道Get-VM的用法,只要執行「Get-Help Get-VM」命令,即可得知該命令的所有可用參數描述。若只想要查看此命令的相關使用範例,可以搭配-Examples參數。如果想要一次查看此命令的完整說明,則改成搭配-Detailed參數。

緊接著,就來試試這一個讓所有Hyper-V管理員在首次使用PowerShell時都一定會使用的「Get-VM」命令。如圖2所示,在不添加任何參數的情況下,將會顯示目前Hyper-V主機上的所有虛擬機器的名稱、開機狀態、CPU與記憶體的使用情形、上線時間、作業狀況以及版本。
當虛擬機器的數量很多時,如果想要以某一個欄位值作為條件並進行篩選,則可以執行像是「Get-VM | where{$_.State -eq 'Running'}」的命令參數,如此一來,便只會顯示目前開機狀態(State)處於Running的虛擬機器。若僅想要檢視所有處於關閉狀態的虛擬機器,則執行「Get-VM | where{$_.State -eq 'Off'}」。
執行以下的命令範例,除了可以查詢SERVER02主機中全部的虛擬機器外,還能進一步查詢哪些是屬於叢集虛擬機器:
Get-VM -ComputerName SERVER02
Get-ClusterGroup | Where-Object
{$_.GroupType -eq 'VirtualMachine'
-and $_.OwnerNode -eq 'SERVER02'}
| Select-Object Name, OwnerNode,
State
在開關機的管理部分,若想透過命令來啟動已關閉的VM02虛擬機器,可執行「Start-VM -Name VM02」命令來完成。如果只是要暫停VM02虛擬機器的運行,則執行「Suspend-VM -Name VM02」,至於若需要恢復暫停中的VM02虛擬機器,只要執行「Resume-VM -Name VM02」即可。
若是要一次啟動所有關閉中的虛擬機器,則改為執行「Get-VM | where{$_.State -eq 'Off'} | Start-VM」命令。相反地,若是要關閉所有已啟動的虛擬機器,就執行「Get-VM | where{$_.State -eq 'Running'} | Stop-VM」。

接下來,一同來學習有關於Hyper-V虛擬機器的快照(檢查點)管理。如圖3所示,首先執行以下的命令,依序在VM02新增一個名為「snapshot01」與「snapshot02」的快照,並且檢查此虛擬機器上的所有快照:
Get-VM -Name VM02 | Checkpoint-VM
-SnapshotName snapshot01
Get-VM -Name VM02 | Checkpoint-VM
-SnapshotName snapshot02
Get-VMCheckpoint -VMName "VM02"
緊接著,如果想要還原VM02虛擬機器的snapshot02快照,就執行「Restore-VMSnapshot -Name'snapshot02' -VMName VM02」命令。若要移除snapshot01快照,則執行「Remove-VMSnapshot -Name'snapshot01' -VMName VM02」。最後,無論執行過哪一些關於快照的管理命令,都建議再次執行「Get-VMCheckpoint -VMName "VM02"」,檢查現行的快照清單。
哪一些主機安裝Hyper-V
想要查詢目前的Active Directory網域中究竟有哪些Windows Server已經安裝Hyper-V,並且列且出它們的主機名稱與完整DNS名稱,可以參考以下命令範例:
Get-ADComputer -Filter * -Properties
ServicePrincipalName | Where-Object
{ $_.ServicePrincipalName -match

"Hyper-V" } | Select-Object Name,
DNSHostName
執行命令後,如圖4所示,便會發現已有四台主機安裝Hyper-V,其中ReplicaBroker這台主機是叢集架構下的「Hyper-V複本代理人」角色,也同樣會顯示在其中。
如果現行網路內並沒有部署Active Directory網域服務,但又想要查詢選定的幾台獨立的Windows Server是否已經安裝Hyper-V,可以參考以下的命令範例:
$servers @("SERVER01",
"SERVER02", "SERVER03")
foreach ($s in $servers) {
Invoke-Command -ComputerName
$s -ScriptBlock {
Get-WindowsFeature -Name
Hyper-V | FT
執行之後,就會發現在命令參數中所選定的SERVER01、SERVER02以及SERVER03皆已安裝Hyper-V。
查詢虛擬磁碟大小與路徑
當IT人員發現Hyper-V主機或共用的儲存設備已被占用大量的儲存空間,而想要調整虛擬機器的存放位置或是刪除不必要的虛擬磁碟時,若受管理的虛擬機器數量並不多,只要透過「Hyper-V管理員」介面逐一檢視每一台虛擬機器的虛擬磁碟路徑和大小,並手動進行完整的記錄,即可作為後續VM空間調整計畫的參考。
然而,當Hyper-V主機上的虛擬機器數量很多時,若還是以人工逐一檢查的方式進行,肯定會很沒有效率。此時,只要執行以下這個PowerShell Script,便可以迅速檢視到所有虛擬機器的虛擬磁碟大小與路徑:
# 取得所有虛擬機器的虛擬磁碟大小與
路徑
$results = @()
Get-VM ForEach-Object {
$vmName = $_.Name
$disks = Get-VMHardDiskDrive
-VMName $vmName
foreach ($disk in $disks) {
$vhdPath = $disk.Path
if (Test-Path $vhdPath) {
$sizeMB = [math]
Round((Get-Item $vhd
Path).Length 1MB, 2)
} else {
$sizeMB = 找不到檔案
$results += [PSCustomObject]@{
VM名稱 = $vmName
虛擬磁碟路徑 = $vhdPath
檔案大小MB = $sizeMB
# 顯示表格
$results Format-Table -AutoSize
如何快速建立大量虛擬機器
想要在Hyper-V的虛擬化平台上快速建立大量的虛擬機器,只要使用PowerShell命令即可輕鬆完成,不過其實方法有很多種,在此先示範第一種最簡易且快速的做法。
如圖5所示,從Visual Studio Code介面中範例所示的執行結果中可以發現,這裡是使用foreach迴圈命令來一次完成5個虛擬機器(LabVM1至LabVM5)的建立,並且在建立過程中完成每一個虛擬機器的記憶體、虛擬磁碟、虛擬處理器以及虛擬網路的設定:
foreach ($i in 1..5) {
$name = "LabVM$i"
$vmPath = "X:VMs$name"
$vhdPath = "$vmPath$name.vhdx"
# 建立VM
New-VM $name -Memory
StartupBytes 4GB -Generation
2 -NewVHDPath $vhdPath
-NewVHDSizeBytes 40GB -Path $vmPath
# 設定虛擬處理器數量
Set-VMProcessor -VMName
$name -Count 2
# 加入網路

Add-VMNetworkAdapter -VMName
$name -SwitchName "InternalSwitch"

在成功執行上述的PowerShell Script範例後,便可以在「Hyper-V管理員」介面中查看到LabVM1至LabVM5的虛擬機器。若需要進行個別虛擬機器的進階配置,只要開啟【設定】選項來完成即可。此外,也可以在此介面中一次選取多個虛擬機器來執行連線、啟動或刪除等操作,如圖6所示。
結合CSV批次建立虛擬機器
前一個建立大量虛擬機器的PowerShell Script範例雖然寫法簡單,但是無法自定義每一台虛擬機器的名稱、記憶大小、處理器數量、虛擬磁碟路徑與大小等設定。
如果想要透過PowerShell Script來大量新增自定義的虛擬機器配置,最好的方式是結合CSV檔案來完成。預先準備好一個CSV檔案,其中內容依序定義每一個虛擬機器設定的欄位名稱,如圖7所示,包括虛擬機器名稱(Name)、記憶體起始大小(MemoryStartupBytes)、虛擬磁碟路徑(VHDPath)、虛擬交換器名稱(SwitchName)、處理器數量(ProcessorCount)以及虛擬磁碟大小(VHDDiskSizeGB)。

準備好上述的CSV檔案後,接下來只要執行以下的PowerShell Script,就可以透過讀取此CSV檔案內容來建立並設定所有的虛擬機器。其中針對CSV檔案的名稱與路徑,只要修改$vmList這項變數設定即可。此外,在這個Script中還加入針對已存在虛擬磁碟檔案的檢查,若發現虛擬磁碟檔案已存在便會略過,而不會覆蓋現有的虛擬磁碟檔案:
# Import VM configuration from CSV file
$vmList = Import-Csv -Path "X:VMs
VMList.csv"
foreach ($vm in $vmList) {
# Calculate virtual disk size in bytes
$sizeInBytes [int64]$vm.
VHDDiskSizeGB * 50GB
# Check if VHD already exists to avoid
duplicate creation
New-VHD $vm.VHDPath
} else {
$($vm.VHDPath) — skipping
creation"
-MemoryStartupBytes $vm.
MemoryStartupBytes `
-VHDPath $vm.VHDPath `
-Generation 2
if (-not (Test-Path $vm.VHDPath)) {
完整移動虛擬機器
-SizeBytes $sizeInBytes -Dynamic
當一個Active Directory網域中有多台Hyper-V主機時,無論這些Hyper-V
Write-Host "VHD already exists:
主機是獨立運行還是執行在叢集架構下,只要有效能、安全或管理方面的考量,往往就會安排進行虛擬機器的移動操作,例如將某一台原本測試階段的虛擬機器,從測試區的Hyper-V主
# Create the virtual machine
機移動到正式區的Hyper-V主機。
New-VM -Name $vm.Name `
如圖8所示,便是透過以下PowerShell的命令參數,將VM03虛擬機器的虛擬硬碟與組態檔案一起從
-SwitchName $vm.SwitchName `
SERVER01移動到SERVER02:
# Set number of virtual processors Move-VM -Name "VM03" -ComputerName
Set-VMProcessor -VMName $vm.Name "SERVER01" -DestinationHost
-Count $vm.ProcessorCount "SERVER02" -IncludeStorage
-DestinationStoragePath "C:VMs
Write-Host "VM created: $($vm. VM03"
Name) | CPU: $($vm.ProcessorCount)
不過,執行後卻出現VM03虛擬機器
| Disk: $($vm.VHDDiskSizeGB) GB"
不相容於SERVER02的錯誤訊息,導致移轉任務執行失敗。至於失敗的原因,仔細看錯誤訊息的內容,便會發現是因為在SERVER02的Hyper-V主機上並沒有「InternalSwitch」這個虛擬交換器,因此只要先到SERVER02新增一個名為「InternalSwitch」的虛擬交換器,即可解決此問題。

另一種常見的移動虛擬機器情境則是,當兩台Hyper-V主機共用相同的儲存(例如使用共享儲存或叢集磁碟),此時的需求通常只是要變換運行虛擬機器的Hyper-V主機,而不是要移動虛擬磁碟的存放位置,為此可以執行如下的命令參數,表示只移動虛擬機器,但不包含虛擬磁碟位置:
Move-VM "VM03"
-ComputerName "SERVER01"
-DestinationHost "SERVER02"
為了讓執行虛擬機器的移動操作能夠順利,也可以事先使用Compare-VM命令來評估選定的虛擬機器是否能夠順利移動到目的地Hyper-V主機:

$report = Compare-VM -Name "VM04"
-DestinationHost "SERVER02"
-ComputerName "SERVER01"
$report.Incompatibilities
完整移除虛擬機器
想要透過圖形介面來移除Hyper-V主機上的虛擬機器與虛擬磁碟檔案,必須分成好幾個操作步驟才能完成,尤其是當一個虛擬機器同時掛載數個虛擬磁碟的情境下,管理員還必須事先查明每一個虛擬磁碟檔案的存放路徑,否則將會造成遺漏的檔案持續占用儲存空間而不自知。
但是如果預先撰寫好一個如下的PowerShell Script,便只需要修改其中的$vm變數來對應所要刪除的虛擬機器名稱。執行之後,只要目標虛擬機器正處於關閉狀態,其執行結果便會如圖9所示,顯示已移除虛擬機器與相關虛擬磁碟檔案,完全無須擔心會有漏網之魚的情況發生:
# 取得 VM05物件
$vm Get-VM "VM05"
-ErrorAction SilentlyContinue
if ($null -eq $vm) {
Write-Host "找不到名為VM05的虛擬
機器。" -ForegroundColor Yellow
} else {
# 檢查執行狀態
if ($vm.State -eq "Running") {
Write-Host "VM05 正在執行中,請
先停止它。" -ForegroundColor Red
} else {
Write-Host "VM05 已停止,開始清除
相關檔案…" -ForegroundColor Cyan
# 取得虛擬磁碟路徑並刪除
$VHDPaths = Get-VMHardDiskDrive
-VMName "VM05" | Select-Object
-ExpandProperty Path
foreach ($path in $VHDPaths) {
if (Test-Path $path) {
Remove-Item -Path $path -Force
Write-Host "已刪除虛擬磁碟:
$path" -ForegroundColor Green
} else {
Write-Host "找不到磁碟檔案:
$path" -ForegroundColor Yellow
# 移除虛擬機器本身
Remove-VM -Name "VM05" -Force
"已移除虛擬機器
Write-Host
VM05。" -ForegroundColor Magenta
登入並管理Guest OS
善用Hyper-V所提供的PowerShell Direct功能,可以在不依賴網路連線或虛擬機器組態的情況下,直接從Hyper-V主機與虛擬機器的Guest OS進行互動,例如進行服務、處理程序、效能計數器、使用者與群組的查詢,或是安裝伺服器角色功能、建立使用者帳號等等。
PowerShell Direct提供許多好用的命令工具,其中有兩個命令是最常使用的,分別是可進入互動式PowerShell連線操作的Enter-PSSession,以及可藉由執行單一命令來完成PowerShell連線操作的Invoke-Command。
想要使用PowerShell Direct功能,只要Hyper-V的作業系統版本是Windows 10/11或Windows Server 2016以上版本,並且虛擬機器所使用的作業系統是Windows即可。
首先來試試Enter-PSSession命令的使用。如圖10所示,執行以下命令,表示即將以指定的Windows帳號連線管理Cluster-VM01這台虛擬機器。執行後輸入一個具備管理員權限的帳號與密碼即可:
Enter-PSSession -VMName
"Cluster-VM01" -Credential (Get-
Credential)

成功連線登入後,緊接著便會進入該虛擬機器名稱的提示字元。接下來,就可以開始執行任何所要使用的命令,查詢、新增、修改或刪除任何的配置。如圖11所示,在此以執行「Get-ComputerInfo」命令為例,此命令可以查詢到此電腦的完整資訊,包括作業系統版本、作業系統安裝資訊、所屬的工作群組或網域、虛擬硬體架構等資訊。

接著,如果想要查看所有的處理程序,只要執行Get-Process命令即可。若進一步需要中止某一個執行中的處理程序,只要先記住它的ID(例如3540),再執行「Stop-Process -Id 3540 -Force」命令即可。
當所要查看的並非處理程序而是服務,可以改執行Get-Service命令,即可完整取得所有服務清單與狀態。若想要停止某一個選定的服務,只要先查看它所對應的名稱,即可進行停止,例如需要停止的服務是Windows Update,此時只要執行「Stop-Service-Name "wuauserv"」命令,當需要進行啟動時,就改為執行「Start-Service -Name "wuauserv"」命令。如果是要直接重新啟動該服務,則執行「Restart-Service -Name "wuauserv"」命令。
在運行效能的監視部分,也可以善用Get-Counter命令來取得系統效能計數器。由於Get-Counter命令可以即時回報CPU、記憶體、磁碟、網路等資源使用狀況,因此非常適合用在虛擬機監控的Script設計中。例如透過執行Get-Counter命令「Get-Counter -Counter "Processor(_Total)%Processor Time"」來查詢CPU運行效能,如圖12所示。
如果想每間隔30秒取得一次記憶體的可用量,並且連續取得10次。只要執行以下命令即可達成:
Get-Counter "MemoryAvailable
MBytes" -SampleInterval 30
-MaxSamples 10
若想知道目前所有磁碟的啟用時間,可以參考以下命令的執行:
Get-Counter -Counter "
PhysicalDisk(_Total)% Disk Time"
想要透過PowerShell來管理本機的帳號與群組,也是一件相當容易的事。首先,執行「Get-LocalUser」命令來查詢目前所有帳號的清單,若是執行「Get-LocalGroupMember-Name Administrators」命令,則可以查看目前Administrators群組中的帳號有哪一些。
接下來,可以嘗試在此主機中新增一個帳號(例如JoviKu),並且將此帳號的密碼設定為「12345@Abcd」,然後將此帳號加入至Administrators群組中。具體怎麼實作呢?很簡單,只要依序執行以下的命令即可:

$Username = "JoviKu"
$Password = ConvertTo-SecureString
"12345@Abcd" -AsPlainText -Force
New-LocalUser $Username
-Password $Password -FullName
"JoviKu" -Description "本機管理員
帳號"
Add-LocalGroupMember -Group
"Administrators" -Member $Username
那要如何刪除選定的帳號(例如JoviKu)以及個人預設的資料夾呢?只要執行如下的命令:
Remove-LocalUser -Name "JoviKu"
Remove-Item "C:Users
JoviKu" -Recurse -Force
針對軟體安裝的檢查部分,如果想要查詢的是包含所有更新程式以及軟體的安裝清單,只要執行「Get-Package」命令即可。但如果想要經過篩選掉更新程式的清單,建議執行以下命令與條件參數的設定:
Get-Package | Where-Object {
$_.ProviderName -ne "msu"
-and $_.Name -notmatch "Update"
如果想要透過一道命令參數就完成指定命令在虛擬機器Guest OS中的執行,可以善用Invoke-Command命令,例如經由執行以下命令來取得Cluster-VM01的Guest OS中所有處理程序:
Invoke-Command -VMName "Cluster-
VM01" -Credential (Get-Credential)
-ScriptBlock {Get-Process}
另一個常用的命令範例,則是透過執行如下的命令參數,完成設定PowerShell執行原則並安裝IIS網頁伺服器:
Invoke-Command -VMName "
Cluster-VM01" -ScriptBlock {
Set-ExecutionPolicy RemoteSigned
-Force
Install-WindowsFeature
Web-Server
最後一個Invoke-Command應用範例,是透過net user命令建立一個名為MISAdmin的本機帳號,並且把密碼設定為「P@ssw0rd123」,再使用net localgroup命令把此帳號加入至本機管理員群組(Administrators)中:
Invoke-Command -VMName " Cluster-
VM01" -ScriptBlock {
net user MISAdmin P@ssw0rd123 /add
net localgroup Administrators
MISAdmin /add
從主機複製檔案至Guest OS
想要在不啟用網路分享或SMB設定的情況下,直接從Hyper-V主機複製檔案到虛擬機器的Guest OS中,最好用的命令工具不外乎是Copy-VMFile,而它其實也是PowerShell Direct所提供的便利命令之一。不過必須注意的是,此命令的使用須先確認目標虛擬機器的Guest OS是運行Windows,並且已啟用Hyper-V整合服務功能。
如圖13所示,當嘗試執行以下命令來複製檔案,執行後卻出現「The device is not ready」的錯誤訊息,這表示目前目標虛擬機器尚未啟用Hyper-V整合服務功能:
Copy-VMFile -Name "Cluster-VM01"
-SourcePath "C:TempECL.pdf"
-DestinationPath "C:TempECL.pdf"
-CreateFullPath -FileSource Host
如何確認目標虛擬機器已經啟用Hyper-V整合服務功能?只要在執行「Get-VMIntegrationService -VMName"Cluster-VM01" | Where-Object {$_.Name -eq "Guest Service Interface"}」命令後,查看其中的Enabled欄位值是否為Ture即可。

當發現Enabled欄位值為False時,便可執行「Enable-VMIntegrationService-VMName "Cluster-VM01" -Name"Guest Service Interface"」命令,完成啟用Hyper-V整合服務功能。
若執行Copy-VMFile時遭遇目的地檔案已經存在,只要直接增加-Froce參數,即可強制覆蓋過去。
關於Hyper-V整合服務功能的啟用,也可透過「Hyper-V管理員」介面來完成。只要先開啟目標虛擬機器的「設定」頁面,如圖14所示,再點選至「整合服務」頁面並勾選「客體服務」即可。
前面介紹的Copy-VMFile命令範例,僅能夠複製單一檔案至目標虛擬機器的Guest OS中,若需要複製「C:Temp」資料夾中的所有檔案至Guest OS中,便需要搭配foreach迴圈命令才能夠逐一複製檔案,因為Copy-VMFile並不支援整個資料夾遞迴參數,可參考以下的PowerShell Script:
$sourcePath = "C:Temp"
$destinationPath = "C:Temp"
$vmName = "Cluster-VM01"
$files Get-ChildItem
$sourcePath -File

Guest Run Time'
$sample Get-Counter -Counter
$counterPath -SampleInterval 1
-MaxSamples 1
名稱分組
$vmCpuUsage $sample.
$_.InstanceName -notmatch
'Total|_Total'
} | Group-Object {
#
稱,例如VM1:VP0 → VM1
} | ForEach-Object {
$vmName = $_.Name
$avgUsage ($_.Group |
Measure-Object CookedValue
-Average).Average
[PSCustomObject]@{
虛擬機器名稱 = $vmName
-f $avgUsage
使用率 -Descending
foreach ($file in $files) {
Copy-VMFile -Name $vmName `
# 擷取一次樣本(可依需求調整
-SourcePath $file.FullName `
SampleInterval與MaxSamples設定值)
-DestinationPath
"$destinationPath$($file.Name)"
`
-CreateFullPath `
-FileSource Host
# 整理資料:排除總計,並依虛擬機器
監視VM平均CPU使用率
CounterSamples | Where-Object {
前面示範過如何在使用PowerShell Direct的狀態下,透過執行Get-Counter命令與相關參數來取得該虛擬機器CPU的效能資訊。然而,如
從InstanceName中擷取VM名
果今天想要一次查看所有運行中虛擬機器的平均CPU使用率,該怎麼
($_.InstanceName -split ':')[0]
很簡單,只要參考以下的腳本範例即可。其中SampleInterval與MaxSamples兩個參數是Get-Counter命令中非常關鍵的設定,用來控制資料擷取的頻率與次數。若想觀察CPU使用率的變化趨勢,建議
平均CPU使用率 = '{0:N2}%'
SampleInterval可設定為1~5秒。如果想計算平均值,建議MaxSamples可擷取多次(例如3~10次)再取平均值:
# 顯示結果,依使用率由高至低排序
$vmCpuUsage | Sort-Object 平均CPU # 設定要擷取的計數器路徑
$counterPath = 'Hyper-V Hyper
visor Virtual Processor(*)%
您好,系統偵測到虛擬機器
[Cluster-
VM01]
($threshold%)。
目前剩餘空間:{0}%
此為自動通知,請勿直接回覆。
Lab02 系統監控中心
"@
try {
# 建立 CIM Session
$session New-CimSession
-ComputerName $vmIp
# 取得C槽磁碟資訊
$disk Get-CimInstance
Win32_LogicalDisk -Filter
# 計算剩餘空間百分比
$freePercent
/
$disk.Size) * 100, 2)
# 判斷是否低於門檻
if ($freePercent -lt
$threshold) {
$body [string]::Format
監視VM系統磁碟空間
無論是對於Hyper-V叢集架構,還是Hyper-V獨立主機下的重要虛擬機器運行,常見的除了需要監視CPU、記憶體以及磁碟的效能外,如果能夠定時監視系統磁碟的可用空間肯定會更好,因為一旦系統磁碟空間用盡,將會直接導致所有應用系統停擺。為了避免這種狀況發生,最好能夠讓磁碟可用空間維持在20%以上。
的系統磁碟剩餘空間低於設定門檻請儘速處理以避免系統效能下降或服務中斷。
在此提供以下的PowerShell Script範例,只要修改其中的設定參數,包括$vmIp、$threshold、$smtpServer、$recipient以及$sender,即可在指定的虛擬機器系統磁碟可用空間低於所設定的百分比時(例如20%)時,自動透過指定的SMTP服務,發送警示通知
-CimSession $session -ClassName
到指定的Email地址。若檢測的結果低於所設定的門檻,則會直接顯示「系
"DeviceID='C:' AND DriveType=3"
統磁碟空間正常」的訊息,而不會發送Email的警示通知:
# 設定參數
[math]::Round(($disk.FreeSpace
$vmIp = "虛擬機器IP位址"
$threshold = 20
$smtpServer = "SMTP主機IP位址"
$recipient = "收件者Email地址"
$sender = "寄件者Email地址"
$subject = "系統磁碟空間不足警告 -
Cluster-VM01" ($bodyTemplate, $freePercent)
$bodyTemplate = @"
Send-MailMessage -To $recipient `
-From $sender `
-Subject $subject `
-Body $body `
-SmtpServer $smtpServer `
-Encoding UTF8
Write-Host "已發送警告通
知:剩餘空間 $freePercent%"
} else {
Write-Host "系統磁碟空間正
常:$freePercent%"
# 清除 Session
Remove-CimSession -CimSession
$session
catch {
"錯誤:無法連線至
Write-Host
$vmIp或取得磁碟資訊。"
Write-Host $_.Exception.
Message
確認上述的PowerShell Script範例可正常執行後,就可以開啟Windows Server內建的「工作排程器」,建立定期自動執行此腳本的設定。
首先在「動作」窗格中點選「建立工作」,接著在「一般」頁面中先輸入工作名稱,再選取「不論使用者登入與否均執行」和「以最高權限執行」設定。然後,在「觸發程序」頁面中按下〔新增〕按鈕,如圖15所示,接著設定「重複工作每隔」時間,例如1小時或30分鐘等等。


緊接著,在「動作」頁面中按下〔新增〕按鈕,設定執行的程式名稱為「powershell.exe」,而新增引數的欄位內輸入「-ExecutionPolicy Bypass -File "C:ScriptsCluster-VM01_SysDiskAlert.ps1"」,其中腳本檔案的名稱與路徑可以根據實際情況調整。
完成工作排程器的設定後,未來只要此PowerShell Script執行後,發現選定的虛擬機器系統磁碟可用空間低於所設定的百分比,便會收到類似如圖16所示的Email警示通知。
簡易備份與還原虛擬機器
使用PowerShell的Export-VM和Import-VM命令,是Hyper-V管理中進行虛擬機備份與還原的方式之一,尤其適合在無第三方備份軟體的情境下進行快速遷移或災害復原。
可透過以下的命令範例,將指定虛擬機器(例如MRP)的設定、虛擬硬碟(VHD/VHDX)、快照等完整匯出至指定資料夾:
$vmName = "MRP"
$exportPath = "D:Backup$vmName"
Export-VM $vmName
$exportPath -Verbose
若要將已匯出的虛擬機器還原至目前所在的Hyper-V主機,可以參考以下命令範例。其中的-Copy參數可將虛擬機器資料複製到Hyper-V預設的虛擬機器資料夾。至於-GenerateNewId參數,則可以避免與原虛擬機器的GUID衝突,適用於同一主機還原的情境中:
$importPath "D:BackupMRP
Virtual MachinesD35057A6-E810-
4E92-95B5-7BD76254F87E.vmcx"
Import-VM -Path $importPath -Copy
-GenerateNewId -Verbose
進行Hyper-V健康檢查
在一個以虛擬化平台為基礎運行的IT環境,除了硬體設備的檢測外,管理員肯定需要定期對於相關的主機與虛擬機器進行健康檢查,才能確保各項應用系統與服務持續正常運行。
針對Hyper-V主機與虛擬機器的健康檢查,在此準備以下PowerShell Script的完整範例,大家若要應用在自己的IT環境中,只要修改其中的$hypervHosts變數設定,並將所要檢查的Hyper-V主機名稱一一輸入即可。
執行之後,除了會在命令視窗中立即顯示檢查結果外,還會在「C:Reports」路徑下,分別產生主機健康報告(Hosts.csv)、虛擬機器健康報告(VMs.csv)以及複寫健康報告(Replicas.csv)。
在此範例中,可以發現其中的一台「Cluster-VM01」虛擬機器,目前的複寫狀態(ReplicationState)處於等待重新執行複寫中,此時便需要透過「Hyper-V管理員」介面的操作或使用
# Retrieve host resource
information
$hostInfo Get-VMHost
-ComputerName $hvHost |
$hvHost |
Status, ComputerName
$vmResults += $vms
if applicable
$replicas Get-VMReplication
SilentlyContinue
if ($replicas) {
} catch {
to ${hvHost}: $($_.Exception.
Message)"
PowerShell命令,讓該虛擬機器的複寫重新執行即可解決:
# Define Hyper-V host list
Select-Object ComputerName, $hypervHosts @("SERVER01",
"SERVER02", "SERVER03") LogicalProcessorCount,
MemoryCapacity, MemoryAvailable
$hostResults += $hostInfo # Initialize data containers
$vmResults = @()
# Retrieve VM status info $replicaResults = @()
$vms = Get-VM -ComputerName $hostResults = @()
Select-Object Name, State, # Set up timestamp and output folder
$timestamp = Get-Date -Format
"yyyyMMdd-HHmm"
$reportRoot = "C:Reports"
$reportPath Join-Path # Retrieve replication status
$reportRoot "HyperV-Health-
$timestamp"
-ComputerName $hvHost -ErrorAction
# Create output directory if it
does not exist
if (-not (Test-Path $reportPath)) $replicaResults += $replicas |
Select-Object Name, ReplicationState, {
ReplicationHealth, ComputerName New-Item $reportPath
-ItemType Directory -Force | Out-
Null
Write-Warning "Cannot connect
foreach ($hvHost in $hypervHosts) {
try {
Write-Host "Connecting to host:
$hvHost..." -ForegroundColor Cyan
-ForegroundColor Cyan
-AutoSize
-ForegroundColor Green
-AutoSize
# Export to CSV
$hostCsv Join-Path
$reportPath "Hosts.csv"
$vmCsv Join-Path
$reportPath "VMs.csv"
$replicaCsv Join-Path
# Display summary to console
Write-Host "Hyper-V Host Summary:" $hostResults | Export-Csv
$hostCsv -NoTypeInformation
$hostResults | Format-Table -Encoding UTF8
$vmResults | Export-Csv
$vmCsv -NoTypeInformation
Write-Host "VM Status Summary:" -Encoding UTF8
$vmResults | Format-Table -AutoSize if ($replicaResults.Count -gt 0) {
$replicaResults | Export-
if ($replicaResults.Count -gt 0) { Csv $replicaCsv
Write-Host "Replication Status -NoTypeInformation -Encoding UTF8
Summary:" -ForegroundColor Yellow
$replicaResults | Format-Table
Write-Host "Health check
completed. Reports saved to:"
-ForegroundColor Green
Write-Host $reportPath
-ForegroundColor Yellow
上述PowerShell Script範例執行後所產生的三種CSV報告,將會根據執行的日期與時間,自動於「C:Reports」路徑下建立存放的資料夾,當然這個
$reportPath "Replicas.csv"
預設路徑的設定只要修改其中的$reportRoot變數即可變更。如圖17所示,則是一份虛擬機器健檢報告,大家可能會發現為何其中的狀態顯示,有些是中文有些是英文。其實,主要是因為該虛擬機器所在的Hyper-V主機,其作業系統所設定使用的介面語言不同所導致。
