VI PowerShell / vSphere PowerCLI についてよく聞かれる質問のひとつが、VI Perl Toolkit / vSphere SDK for Perlに比べてできることが少ないのではないかという点。これはある意味正しい。というのも、PowerShell版は簡単に使える代わりに抽象化度が高く、本来のAPIに含まれる機能についての網羅性に欠けているのだ。
ただ、PowerCLIの範囲ではできないことも、.Net上に実装されVI PowerShellのバックグラウンドで透過的に動いているSDK for .Netを直接利用することで、制約をうけずより広範な処理を記述できる。もちろん PowerCLI の範囲ですむ部分はそこですましながら必要に応じてスクリプトの中で使い分けられるのだ。
この切り替えは、主にGet-Viewというコマンドレットを使って行う。Get-ViewにのIdを渡す(オブジェクトそのもののパイプライン渡しも可)と、純然たるManaged Objectが得られる。あとは、vSphere APIに実装されているプロパティやメソッドが自由に使えるようになる。
たとえば、vSphere PowerCLIのMove-VMコマンドの制約についてまとめた下記の記事も、Get-Viewを使うことで回避することができる。
Move-VMコマンドレットでのVMotionのクセ
下記の例では、指定したESX上のパワーオン状態の仮想マシンを全て別のESXにVMotionさせている。
$src_esx = Get-VMHost <esx-name1>
$dst_esx = Get-VMHost <esx-name2>
$VMs = Get-VM -Location $src_esx
$res = Get-ResourcePool 'リソース' -Location $dst_esx
$esx_moref = ($dst_esx | Get-View).Moref
$res_moref = ($res | Get-View).Moref
$VMs | Where-Object { $_.PowerState -eq "PoweredOn" } | foreach {
($_ | Get-View).MigrateVM($res_moref, $esx_moref, "highPriority", "PoweredOn")
}
$dst_esx = Get-VMHost <esx-name2>
$VMs = Get-VM -Location $src_esx
$res = Get-ResourcePool 'リソース' -Location $dst_esx
$esx_moref = ($dst_esx | Get-View).Moref
$res_moref = ($res | Get-View).Moref
$VMs | Where-Object { $_.PowerState -eq "PoweredOn" } | foreach {
($_ | Get-View).MigrateVM($res_moref, $esx_moref, "highPriority", "PoweredOn")
}
PowerCLIの範囲をはみ出しているということを意識しなくてもよいくらいシームレスに使えてることが分かる。
ここで使われているMigrateVMはvSphere APIのメソッドであり、Move-VMはMigrateVMを透過的に使用しているPowerShellのコマンドレットなのだ。
最後に、SDK for .Netについて特徴をいくつか細くしておく。
- メソッドに()を使う(PowerCLIのコマンドレットでは()は不要)
- 引数にオブジェクトを使う場合Morefを使う(PowerCLIはオブジェクトそのものかIdをとる)
- MigrateVMとMigrateVM_Taskの違いはPowerCLIの-Asyncの有無に相当(非同期実行)
- Get-Viewの逆はGet-ViObjectByViewで行う
このあたりを先日のVMware Virtualization Forum 2009のセッションでしゃべった資料は下記。
VMware Virtualization Forum 2009 A66資料