PowerCLI によるESXiシャットダウンの自動化

はじめに

ESXi を停止させたいときに仮想マシンを一つ一つ選択してシャットダウンしていくのは大変ですよね。

本記事では PowerCLI を利用して、「仮想マシンのシャットダウンからホストの停止までの自動化を行う方法」を紹介します。
PowerCLI の導入方法はこちらの記事 (macOS で PowerCLI を使えるようにする) を御覧ください。

概要

スクリプトの構成は以下です。

  1. ESXi ホストに接続
  2. vCLS を除くホスト上の全仮想マシンをシャットダウン
  3. vCLS を除くホスト上の全仮想マシンをパワーオフ
  4. vCLS をシャットダウン
  5. ホストをメンテナンスモードに移行(任意)
  6. ホストをシャットダウン

補足1
vCenter に接続してオペレーションを行うのが一般的かもしれませんが、ホスト数も多くなく、このやり方だと vCSA のシャットダウン順序を考慮しなくてもいいので、ESXi に接続してシャットダウンを実施するスクリプトにしています。

補足2
vCLS のシャットダウン順序を考慮しているのはvCSAが起動している状態でシャットダウンを実行すると再度自動的にパワーオンされる為です。

補足2
3.のパワーオフ作業に関しては何らかの原因によって仮想マシンのシャットダウンが失敗してしまった場合の保険です。
例えば仮想マシン上で VMwareTools が実行されていない場合、シャットダウンアクションは失敗します。

補足3
メンテナンスモードに移行した上でシャットダウンする運用のほうがより安全と言えます。
稼働中のVMがあった場合にそのデータが失われる可能性があるためです。

スクリプト詳細

以下にスクリプトを記載しているのでよければ参考にしてください。

各コードで実行している内容についてはなるべくコメントで補足をしています。
スクリプトは「.ps1」の拡張子で保存して実行します。

#変数の定義
#########################################
#接続先ホスト#1
$ESXi1="172.xx.xx.xx"

#ESXiログイン時のクレデンシャル
$esxiUser="xxxx"
$esxiPassword="xxxx"
#########################################

#ESXi1のシャットダウン
############################################
#ESXi#1に接続
Connect-VIServer -server $ESXi1 -User $esxiUser -Password $esxiPassword -force

#仮想マシン(vCLS以外)をシャットダウンする
Write-Host "Shut down VMs"

foreach ($vm in Get-VM){

   #仮想マシンの稼働状況に応じてマークする
   $isPoweredOff = $false
   if($vm.PowerState -eq "PoweredOff"){
     $isPoweredOff = $true
   }

   # VMがvCLSに該当するかどうか確認する
   $isVCLS = $false
   if($vm.Name -match "^vCLS"){
     $isVCLS = $true
   }

   # vCLS以外でパワーオフ状態でなかったVMであればシャットダウンする
   if((-not $isVCLS) -and (-not $isPoweredOff)){
     Stop-VMGuest $vm -Confirm:$false
   }
}

#シャットダウン完了を30秒待つ
Write-Host "Waiting for shutdown completion..."
Start-Sleep -Seconds 30

#シャットダウンされているか確認
Get-VM | Format-Table -AutoSize -Wrap

#####

#何らかの理由でシャットダウンできなかったVMをパワーオフする

Write-Host "Power Off VMs"

foreach ($vmAfterShutDown in Get-VM){

   #仮想マシンの稼働状況に応じてマークする
   $isPoweredOff = $false
   if($vmAfterShutDown.PowerState -eq "PoweredOff"){
     $isPoweredOff = $true
   }

   # VMがvCLSに該当するかどうか確認する
   $isVCLS = $false
   if($vmAfterShutDown.Name -match "^vCLS"){
     $isVCLS = $true
   }
   # vCLS以外でパワーオフ状態でなかったVMであればパワーオフする
   if((-not $isVCLS) -and (-not $isPoweredOff)){
     Stop-VM $vmAfterShutDown -Confirm:$false
   }
}

#パワーオフ完了を30秒待つ
Write-Host "Waiting for power-off completion..."
Start-Sleep -Seconds 30

#パワーオフされているか確認
Get-VM | Format-Table -AutoSize -Wrap

#####

#vCLSをシャットダウンする

Write-Host "Shutdown vCLS"

foreach ($vm2 in Get-VM){
   if($vm2.Name -match "^vCLS"){
     Stop-VMGuest $vm2 -Confirm:$false
   }
}

#シャットダウン完了を10秒待つ
Write-Host "Waiting for shutdown completion..."
Start-Sleep -Seconds 10

#####

#メンテナンスモードに移行
#Set-VMHost $ESXi1 -State "Maintenance" -Confirm:$False
#Start-Sleep -Seconds 10

#ESXi#1ホストをシャットダウンする
Stop-VMHost $ESXi1 -Confirm:$False -force
Disconnect-VIServer -Confirm:$False 

Write-Host $ESXi1 + "Operation Complete !"
#########################################################

以上です!