朝から昼寝

整理しておきたいIT関連の小ネタ

1回のGet-VMで色々なVMプロパティを取得(PowerCLI)

概要

PowerCLIでvCenterから仮想マシン情報を取得可能ですが、目的のプロパティ群がGet-VMやGet-VMGuestなど複数のコマンドレットの出力にまたがる場合、各コマンドレットを実行しそれらの出力をマージするというのは煩雑です。
本記事は、シンプルに1回のGet-VMコマンドレット実行から、Get-VMの出力に含まれないプロパティ情報も合わせて取得し、CSVファイルに保存する方法をまとめたものです。

本記事の目的

  • 1回のGet-VMコマンドレット実行で仮想マシンの各プロパティを取得する。


目次

基本

環境設定

既に以下の環境設定は完了しているものとします。

  • PowerCLIのインストール
  • PowerCLIからvCenterへの接続確認(Connect-VIServer)

仮想マシンの各プロパティを取得するスクリプト

Connect-VIServerにてvCenterに接続後、以下の例のようにスクリプトを実行すると、各プロパティを取得できます。取得するプロパティは変更可能です。

vmlist.ps1

# 複数NICを持つVMのVLAN/NetworkAdapterプロパティは複数値になるので":"で結合する関数を用意
function concatNetworkAdapters {
    Param($VM)
    $var = @()
    $Adapters = @(Get-NetworkAdapter -VM $VM | Select Name, NetworkName)

    ForEach ($Adapter in  $Adapters) {
        $var += $Adapter.NetworkName + "(" + $Adapter.Name + ")"
    }

    Return [String]::join(":", $var)
}

$date = Get-Date

# Get-VMにて全VMのオブジェクトを取得し、目的のプロパティをハッシュテーブルに格納
$out = Get-VM | Select Name, 
    @{N="PowerState"; E={[String] $_.PowerState}},
    @{N="Host"; E={$_.VMHost.name}},
    NumCpu,
    MemoryGB,
    @{N="ProvisionedSpaceGB"; E={[Math]::Round(($_.ProvisionedSpaceGB),0)}},
    @{N="UsedSpaceGB"; E={[Math]::Round(($_.UsedSpaceGB),0)}},
    @{N="GuestOS"; E={$_.Guest.OSFullName}},
    HardwareVersion,
    @{N="IPAddress"; E={[string]::Join(':',$_.Guest.IPAddress)}},
    @{N="VLAN"; E={concatNetworkAdapters $_.Name}},
    @{N="VmxPath"; E={$_.ExtensionData.Summary.Config.VmPathName}},
    CreateDate,
    @{N="UptimeDays";E={(New-TimeSpan -Start $_.Extensiondata.Runtime.BootTime.ToLocalTime() -End $date).Days}},
    @{N="ToolsInstallType"; E={$_.ExtensionData.Guest.ToolsInstallType}},
    @{N="ToolsVersion"; E={$_.ExtensionData.Guest.ToolsVersion}},
    @{N="ToolsStatus"; E={$_.ExtensionData.Guest.ToolsStatus}},
    Notes

# CSVファイルに出力
$out | Export-CSV -NoTypeInformation -encoding UTF8 "C:\vmlist\vmlist.csv"

CSV出力例

出力されたCSVファイルの例です。(列が多いので画像2枚に分けてあります。また例なので1行分のみですが実際には全VM分の行が出力されます)

CSV出力例CSV出力例
CSV出力例

スクリプトの注意点

以下、注意点です。

  • スクリプトの中でファイルパス等にマルチバイト文字(非Ascii文字)を使用する場合、PowerShellの環境の都合上、スクリプト文字コードUTF-8(BOM付)で保存する等の対応が必要です(参考情報はこちら)。

  • 上記の例では、型指定([String]等)の有無等は統一しきれていません。

詳細

スクリプトの説明

このスクリプトは、後述の参考URL等にあるVMwareのコミュニティ情報を元にしたものです。内容を簡単に説明します。

  • function concatNetworkAdapters
    複数NICを持つVMのVLAN(ポートグループ)やNetworkAdapterの情報は、複数値になるので、各値を":"で結合し、CSVの1フィールドに収まるよう整形する関数(適切なプロパティが別途あるかもしれないが、この関数の中ではGet-NetworkAdapterを使用)
  • $out = Get-VM |
    Get-VMにて全VMのオブジェクトを取得し、パイプラインに渡す。パイプライン以降の処理が終わった結果を変数outに格納する。
  • | select以降
    VMのオブジェクトを渡された後は、Select経由でハッシュテーブル(@{Name=xxx, Expression=xxx}、もしくは省略形の@{N=xxx, E=xxx})に格納する。
    Get-VMの出力に含まれるプロパティのままで良いものは、ハッシュテーブルの記載(@{})を省略可。
    逆に、Get-VMの出力に含まれないプロパティを参照するときは、$_.ExtensionData.xxxのように、オブジェクトのメンバ情報から目的のプロパティを指定する(目的のプロパティ名の探し方は後述)。
    • Name : 仮想マシン
    • @{N="PowerState"; E={[String] $_.PowerState}} : 電源状態
    • @{N="Host"; E={$_.VMHost.name}} : 稼働ホスト
    • NumCpu : 仮想CPU数(総コア数)
    • MemoryGB : メモリ量[GB]
    • @{N="ProvisionedSpaceGB"; E={[Math]::Round(($_.ProvisionedSpaceGB),0)}}, @{N="UsedSpaceGB"; E={[Math]::Round(($_.UsedSpaceGB),0)}} : それぞれ、プロビジョニングした容量[GB]、使用容量[GB] ※小数点以下はRound()で四捨五入
    • @{N="GuestOS"; E={$_.Guest.OSFullName}} : ゲストOS名
    • HardwareVersion : 仮想マシンバージョン
    • @{N="IPAddress"; E={[string]::Join(':',$_.Guest.IPAddress)}} : IPアドレス ※複数のIPアドレスがある場合、Join()にて":"で結合
    • @{N="VLAN"; E={concatNetworkAdapters $_.Name}} : 前述の concatNetworkAdapters関数にて取得したVLAN(ポートグループ)情報
    • @{N="VmxPath"; E={$_.ExtensionData.Summary.Config.VmPathName}} : 格納先データストア(vmxファイルのパス)
    • CreateDate : 仮想マシンの作成日時 ※参考までに、Cross vCenter VMotion実行された仮想マシンは、その実行日時にリセットされるようです
    • @{N="UptimeDays";E={(New-TimeSpan -Start $_.Extensiondata.Runtime.BootTime.ToLocalTime() -End $date).Days}} :稼働日数(Uptimeから日数だけを取り出したもの)
    • @{N="ToolsInstallType"; E={$_.ExtensionData.Guest.ToolsInstallType}},@{N="ToolsVersion"; E={$_.ExtensionData.Guest.ToolsVersion}},@{N="ToolsStatus"; E={$_.ExtensionData.Guest.ToolsStatus}} : VMwareTools関連の情報
    • Notes : vCenter上の"注"

目的のプロパティ名の探し方

  • Get-Member
    適当な仮想マシンのオブジェクトをGet-VM等で取得し、Get-Memberで辿りながら地道に探す方法があります。ExtensionDataExtensionData.Guest仮想マシン管理に使えるプロパティがあると思います。
> $vm = Get-VM -name vm01
> $vm | Get-Member
> $vm.ExtensionData | Get-Member
> $vm.ExtensionData.Guest | Get-Member
  • VMware社公式ドキュメント (例:Get-VM RelatedObject)
    2022/5現在、Beta版のようですが、VMware Developer Documentation等でコマンドレットのRelatedObjectを参照すると、各プロパティを参照できます。ただ、Get-VM で取得したオブジェクトから全プロパティを簡単にリンクで辿れる訳ではなさそうです。
    その他、vSphere Web Services APIでもプロパティの説明など参考になりそうな記載があります。

あとは、後述のVMwareコミュニティのやり取りを参考にするのが一番実用的のように思います。

参考URL等

VMwareコミュニティのやり取りから、目的のプロパティの記載が見つかる場合もあります。PowerCLI関連の話題は、詳細に回答されて方がいるようで、非常に参考になります。