«

VMware PowerCLI

Paladin 发布于 阅读:10 oTher


1. 環境安裝

1.1 確認 PowerShell 版本

# 查詢 PowerShell 版本(建議使用 PowerShell 7)
$PSVersionTable.PSVersion

1.2 安裝 PowerCLI

# PowerShell 7(推薦)
Install-Module -Name VMware.PowerCLI -Scope CurrentUser -Force -AllowClobber

# PowerShell 5.1
Install-Module -Name VMware.PowerCLI -Scope CurrentUser -Force

1.3 設定(每次使用前執行一次即可)

# 忽略 SSL 憑證錯誤(實驗室/內網環境必備)
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false -Scope AllUsers

# 停止參加 CEIP(客戶經驗改善計劃)
Set-PowerCLIConfiguration -Scope AllUsers -ParticipateInCeip $false -Confirm:$false

# 顯示多個 vCenter 連線時不詢問
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Confirm:$false -Scope AllUsers

1.4 模組路徑說明

PowerShell 版本 模組安裝路徑
PowerShell 5.1(Windows PowerShell) D:\UserData\User\Documents\WindowsPowerShell\Modules
PowerShell 7+(PowerShell Core) D:\UserData\User\Documents\PowerShell\Modules
# 查詢已安裝的 PowerCLI 版本
Get-Module -ListAvailable VMware.PowerCLI | Select-Object Name, Version

2. 連線與斷開

2.1 基本連線

# 匯入模組
Import-Module VMware.PowerCLI

# 連線到 vCenter Server
Connect-VIServer -Server <vCenter主機名或IP> -User <帳號> -Password <密碼> -Force

# 範例
Connect-VIServer -Server vchost -User "user@vsphere.local" -Password "YourPass" -Force

💡 -Force 參數:接受未信任的 SSL 憑證,避免每次連線都跳出確認

2.2 多種帳號格式

# UPN 格式(常用)
Connect-VIServer -Server vchost -User "user@vsphere.local" -Password "YourPass" -Force

# vSphere SSO 網域格式
Connect-VIServer -Server vchost -User "vsphere.local\user" -Password "YourPass" -Force

# AD 網域格式
Connect-VIServer -Server vchost -User "CNZS\user" -Password "YourPass" -Force

2.3 中斷連線

# 中斷當前所有連線
Disconnect-VIServer -Server * -Confirm:$false

# 中斷特定 vCenter
Disconnect-VIServer -Server vchost -Confirm:$false

2.4 查詢連線狀態

# 查看目前連線的 vCenter
Get-VIServer

# 查看已連線的 ESXi 主機
Get-VMHost

3. VM 基本查詢

3.1 查詢所有 VM

# 取得所有 VM(預設排序)
Get-VM

# 按名稱排序
Get-VM | Sort-Object Name

# 取得 VM 詳細資訊
Get-VM | Select-Object Name, PowerState, NumCpu, MemoryGB, VMHost, Folder

3.2 查詢特定 VM

# 依名稱查詢(支援萬用字元)
Get-VM -Name "ZS*"

# 查詢已開機的 VM
Get-VM | Where-Object { $_.PowerState -eq "PoweredOn" }

# 查詢已關機的 VM
Get-VM | Where-Object { $_.PowerState -eq "PoweredOff" }

# 依據 ESXi 主機查詢
Get-VM -VMHost vcip

# 依據資料夾查詢
Get-Folder -Name vm | Get-VM

3.3 查詢 VM 詳細屬性

# 取得單一 VM 的所有屬性
$vm = Get-VM -Name "hostname"
$vm | Select-Object *

# 查詢 VM 的 IP 位址
(Get-VM -Name "hostname").Guest.IPAddress

# 查詢 VM 的作業系統
(Get-VM -Name "hostname").Guest.OSFullName

# 查詢 VM 的工具狀態
(Get-VM -Name "hostname").Guest.VmToolsVersion

3.4 查詢 VM 資源使用率

# 即時 CPU / 記憶體使用率
Get-VM | Where-Object { $_.PowerState -eq "PoweredOn" } | ForEach-Object {
    [PSCustomObject]@{
        Name       = $_.Name
        CPU_Usage  = "$($_.CPUUsageMhz) MHz"
        Mem_Usage  = "$([math]::Round($_.MemoryUsageMB / 1024, 2)) GB"
        Status     = $_.Guest.VmToolsStatus
    }
} | Format-Table -AutoSize

# 查詢 VM 開機時間(天數)
Get-VM | Where-Object { $_.PowerState -eq "PoweredOn" } | ForEach-Object {
    $uptime = $_.ExtensionData.Summary.QuickStats.UptimeSeconds
    [PSCustomObject]@{
        Name       = $_.Name
        UptimeDays = [math]::Round($uptime / 86400, 1)
    }
} | Sort-Object UptimeDays | Format-Table -AutoSize

4. VM 電源管理

4.1 開機 / 關機 / 重啟

# 開機
Start-VM -VM "VM名稱"

# 關機(需安裝 VMware Tools,會優雅關機)
Stop-VM -VM "VM名稱" -Confirm:$false

# 強制關機(直接切斷電源)
Stop-VM -VM "VM名稱" -Kill -Confirm:$false

# 重新開機
Restart-VM -VM "VM名稱" -Confirm:$false

# 多台 VM 同時開機
"ZSAD01", "ZSAD02", "ZSFile-srv" | Start-VM

4.2 批量電源管理

# 關閉所有已開機的 VM(需先確認!)
Get-VM | Where-Object { $_.PowerState -eq "PoweredOn" } | Stop-VM -Confirm:$false

# 啟動所有已關機的 VM
Get-VM | Where-Object { $_.PowerState -eq "PoweredOff" } | Start-VM

# 批次重啟特定 VM(ZSWEB 系列)
Get-VM -Name "ZSWEB*" | Restart-VM -Confirm:$false

5. 快照管理

5.1 查詢快照

# 查詢所有 VM 的快照
Get-VM | Get-Snapshot | Select-Object VM, Name, Created, SizeGB, Description | Format-Table -AutoSize

# 查詢特定 VM 的快照
Get-VM -Name "ZSAD01" | Get-Snapshot

# 查詢所有 VM 的快照數量
Get-VM | ForEach-Object {
    $snap = $_ | Get-Snapshot
    [PSCustomObject]@{
        VMName      = $_.Name
        SnapCount   = $snap.Count
        TotalSizeGB = [math]::Round(($snap | Measure-Object -Property SizeGB -Sum).Sum, 2)
    }
} | Where-Object { $_.SnapCount -gt 0 } | Sort-Object SnapCount -Descending | Format-Table -AutoSize

5.2 建立快照

# 基本快照
New-Snapshot -VM "VM名稱" -Name "快照名稱" -Description "這是快照描述"

# 快照當前系統狀態
New-Snapshot -VM "ZSAD01" -Name "BeforePatching_$(Get-Date -Format 'yyyyMMdd')" -Description "更新前快照"

# 一次性建立多台 VM 快照
"ZSAD01", "ZSAD02", "ZSCCDDB01" | ForEach-Object {
    New-Snapshot -VM $_ -Name "Backup_$(Get-Date -Format 'yyyyMMdd_HHmm')" -Confirm:$false
}

5.3 還原快照

# 還原至最新快照
Set-VMSnapshot -VM "VM名稱" -Snapshot (Get-VM "VM名稱" | Get-Snapshot | Select-Object -Last 1) -Confirm:$false

# 還原至指定快照名稱
Set-VMSnapshot -VM "ZSAD01" -Snapshot "快照名稱" -Confirm:$false

# 還原並自動啟動 VM
Set-VMSnapshot -VM "ZSAD01" -Snapshot "BackupPoint1" -Confirm:$false | Start-VM

5.4 刪除快照

# 刪除特定 VM 的特定快照
Get-VM -Name "ZSAD01" | Get-Snapshot -Name "快照名稱" | Remove-Snapshot -Confirm:$false

# 刪除 VM 的所有快照
Get-VM -Name "ZSAD01" | Get-Snapshot | Remove-Snapshot -Confirm:$false

# 刪除所有 VM 的所有快照(⚠️ 非常危險,請確認後執行)
Get-VM | Get-Snapshot | Remove-Snapshot -Confirm:$false

6. 主機與叢集

6.1 主機查詢

# 查詢所有 ESXi 主機
Get-VMHost | Select-Object Name, ConnectionState, PowerState, MemoryTotalGB, CpuTotalMhz | Format-Table -AutoSize

# 查詢主機資源
Get-VMHost | ForEach-Object {
    [PSCustomObject]@{
        Name         = $_.Name
        State        = $_.ConnectionState
        CPU_UsageMHz = $_.CpuUsageMhz
        CPU_TotalMHz = $_.CpuTotalMhz
        Mem_UsageGB  = [math]::Round($_.MemoryUsageGB, 1)
        Mem_TotalGB  = [math]::Round($_.MemoryTotalGB, 1)
    }
} | Format-Table -AutoSize

6.2 進入維護模式

# 將主機進入維護模式
Set-VMHost -VMHost 192.168.64.52 -State Maintenance -Confirm:$false

# 將主機退出維護模式
Set-VMHost -VMHost 192.168.64.52 -State Connected -Confirm:$false

# 將 VM 從主機移出(進入維護模式前必做)
Get-VMHost 192.168.64.52 | Get-VM | Move-VM -Destination (Get-VMHost 192.168.64.53)

6.3 叢集查詢

# 查詢叢集
Get-Cluster

# 查詢叢集內的主機
Get-Cluster -Name "叢集名稱" | Get-VMHost

# 查詢叢集內的 VM
Get-Cluster -Name "叢集名稱" | Get-VM

7. 儲存管理

7.1 Datastore 查詢

# 查詢所有 Datastore
Get-Datastore | Select-Object Name, Type, CapacityGB, FreeSpaceGB,
    @{N="使用率%";E={[math]::Round((1 - $_.FreeSpaceGB / $_.CapacityGB) * 100, 1)}} |
    Sort-Object Name | Format-Table -AutoSize

# 查詢特定 Datastore
Get-Datastore -Name "Datastore名稱"

# 查詢使用率超過 80% 的 Datastore
Get-Datastore | Where-Object {
    ($_.FreeSpaceGB / $_.CapacityGB) -lt 0.2
} | Select-Object Name, CapacityGB, FreeSpaceGB,
    @{N="使用率%";E={[math]::Round((1 - $_.FreeSpaceGB / $_.CapacityGB) * 100, 1)}}

7.2 Datastore 掛載

# 將 Datastore 掛載到主機
New-Datastore -VMHost 192.168.64.52 -Name "NFS-Datastore" -Path "/mnt/nfs" -Type Nas -NfsHost "192.168.1.100"

# 從主機卸載 Datastore
Remove-Datastore -Datastore "Datastore名稱" -VMHost 192.168.64.52 -Confirm:$false

7.3 查詢 VM 的 Datastore 使用量

Get-VM | ForEach-Object {
    $hardDisks = $_ | Get-HardDisk
    [PSCustomObject]@{
        VMName      = $_.Name
        DiskCount   = $hardDisks.Count
        TotalDiskGB = [math]::Round(($hardDisks | Measure-Object -Property CapacityGB -Sum).Sum, 2)
        Datastore   = ($hardDisks | Select-Object -First 1).Filename.Split(']')[0].TrimStart('[')
    }
} | Format-Table -AutoSize

8. 網路管理

8.1 查詢虛擬交換器

# 查詢標準交換器
Get-VirtualSwitch -VMHost 192.168.64.52

# 查詢分散式交換器(需 vCenter)
Get-VDSwitch

# 查詢埠群組
Get-VirtualPortGroup -VMHost 192.168.64.52

8.2 查詢 VM 網路卡

# 查詢 VM 的網路卡資訊
Get-VM -Name "ZSAD01" | Get-NetworkAdapter | Select-Object Parent, Name, NetworkName, MacAddress, ConnectionState | Format-Table -AutoSize

8.3 網路卡管理

# 新增網路卡
New-NetworkAdapter -VM "VM名稱" -NetworkName "VM Network" -Type Vmxnet3 -StartConnected

# 移除網路卡
Get-VM -Name "VM名稱" | Get-NetworkAdapter -Name "Network adapter 2" | Remove-NetworkAdapter -Confirm:$false

# 斷開 / 連接網路卡
Get-VM -Name "VM名稱" | Get-NetworkAdapter -Name "Network adapter 1" | Set-NetworkAdapter -Connected $false -Confirm:$false

9. 報表匯出

9.1 VM 清單 CSV

Connect-VIServer -Server zsvc03 -User "Z3526@vsphere.local" -Password "cnZS@admin20260422" -Force | Out-Null

$VMs = Get-VM | Sort-Object Name
$result = @()
foreach ($vm in $VMs) {
    $ip = ""
    try { $ip = ($vm.Guest.Nics | Where-Object { $_.ConnectionState -eq "Connected" } | Select-Object -First 1).IPAddress -join ", " } catch {}

    $uptimeDays = "N/A"
    if ($vm.PowerState -eq "PoweredOn") {
        try { $uptimeDays = [math]::Round($vm.ExtensionData.Summary.QuickStats.UptimeSeconds / 86400, 1) } catch {}
    }

    $result += [PSCustomObject]@{
        VMName     = $vm.Name
        PowerState = $vm.PowerState
        vCPU       = $vm.NumCpu
        MemoryGB   = [math]::Round($vm.MemoryGB, 1)
        OS         = $vm.Guest.OSFullName
        IPAddress  = $ip
        Host       = $vm.VMHost.Name
        Folder     = $vm.Folder.Name
        UptimeDays = $uptimeDays
    }
}

$CSVPath = "D:\UserData\z3526\Desktop\VM清單_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
$result | Export-Csv -Path $CSVPath -Encoding UTF8 -NoTypeInformation
Write-Host "已匯出: $CSVPath" -ForegroundColor Green

Disconnect-VIServer -Server zsvc03 -Confirm:$false

9.2 統計摘要

Connect-VIServer -Server zsvc03 -User "Z3526@vsphere.local" -Password "cnZS@admin20260422" -Force | Out-Null

$VMs = Get-VM
$poweredOn = ($VMs | Where-Object { $_.PowerState -eq "PoweredOn" }).Count
$poweredOff = ($VMs | Where-Object { $_.PowerState -eq "PoweredOff" }).Count
$totalMem = [math]::Round(($VMs | Measure-Object -Property MemoryGB -Sum).Sum, 1)
$onMem = [math]::Round(($VMs | Where-Object { $_.PowerState -eq "PoweredOn" } | Measure-Object -Property MemoryGB -Sum).Sum, 1)

Write-Host "===== vCenter 統計報告 =====" -ForegroundColor Cyan
Write-Host "vCenter: zsvc03"
Write-Host "VM 總數: $($VMs.Count)"
Write-Host "已開機: $poweredOn"
Write-Host "已關機: $poweredOff"
Write-Host "總記憶體: ${totalMem} GB(已開機: ${onMem} GB)"
Write-Host "生成時間: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"

Disconnect-VIServer -Server zsvc03 -Confirm:$false

9.3 主機資源使用率報表

Connect-VIServer -Server zsvc03 -User "Z3526@vsphere.local" -Password "cnZS@admin20260422" -Force | Out-Null

Get-VMHost | ForEach-Object {
    $cpuPct = [math]::Round($_.CpuUsageMhz / $_.CpuTotalMhz * 100, 1)
    $memPct = [math]::Round($_.MemoryUsageGB / $_.MemoryTotalGB * 100, 1)
    [PSCustomObject]@{
        主機IP       = $_.Name
        連線狀態     = $_.ConnectionState
        CPU使用率    = "$cpuPct%"
        記憶體使用率 = "$memPct%"
        CPU總數MHz   = $_.CpuTotalMhz
        記憶體總GB   = [math]::Round($_.MemoryTotalGB, 1)
        VM數量       = ($_ | Get-VM).Count
    }
} | Format-Table -AutoSize

Disconnect-VIServer -Server zsvc03 -Confirm:$false

10. 常用指令速查表

連線

Connect-VIServer -Server <主機> -User <帳號> -Password <密碼> -Force
Disconnect-VIServer -Server * -Confirm:$false

VM 操作

Get-VM                              # 列出所有 VM
Get-VM -Name "名稱*"                # 萬用字元查詢
Start-VM -VM "名稱"                 # 開機
Stop-VM -VM "名稱" -Confirm:$false  # 關機
Restart-VM -VM "名稱" -Confirm:$false  # 重啟
Move-VM -VM "名稱" -Destination <主機>  # 搬移 VM

快照

Get-VM | Get-Snapshot               # 列出所有快照
New-Snapshot -VM "名稱" -Name "快照名"  # 建立快照
Set-VMSnapshot -VM "名稱" -Snapshot "快照名"  # 還原快照
Get-Snapshot -VM "名稱" | Remove-Snapshot  # 刪除快照

主機

Get-VMHost                          # 列出所有 ESXi 主機
Set-VMHost -VMHost <主機> -State Maintenance  # 進入維護模式

儲存

Get-Datastore                       # 列出所有 Datastore
Get-Datastore | Get-HardDisk        # 查詢磁碟使用

匯出

Get-VM | Export-Csv -Path "路徑.csv" -Encoding UTF8 -NoTypeInformation
Get-VM | ConvertTo-Html | Out-File "路徑.html"

⚠️ 安全提醒

  1. 千萬不要將密碼寫死在指令碼中,建議使用 Get-Credential 或認證檔案
  2. 批量刪除 / 關機操作前務必先查詢確認
  3. 生產環境操作前建議先建立快照
  4. 定期更換 vCenter 密碼,不要使用弱密碼

使用 Get-Credential 安全輸入密碼

# 安全的密碼輸入方式(彈出輸入框,不留痕跡)
$creds = Get-Credential -Message "請輸入 vCenter 帳號"
Connect-VIServer -Server zsvc03 -Credential $creds -Force

🔧 疑難排解

問題 解決方式
憑證不被信任 加入 -Force 或執行 Set-PowerCLIConfiguration -InvalidCertificateAction Ignore
連線被拒絕 確認 vCenter IP 可達、防火牆是否開放 443 埠
登入失敗 確認帳號格式(使用 UPN:user@vsphere.local
模組找不到 確認使用正確的 PowerShell 版本,並將模組複製到對應路徑
中文路徑輸出 CSV 亂碼 使用 -Encoding UTF8 參數

VMware PowerCLI