VI Perl Toolkit（vSphere CLI）で仮想マシンの構成変更

**※本記事は試行メモです。正しく動作することや、手順として妥当であることなどは一切保障しません。**

# 概要

VI Perl Toolkit（vSphere CLI）で仮想マシンの構成情報を取得、変更する。

# 詳細

## 仮想マシンの一覧出力

仮想マシン名には`$vm_view->name`、仮想マシンのメモには`$vm_view->config->annotation`でアクセスできる。

    #!/usr/bin/perl -w
    
    use strict;
    use warnings;
    use utf8;
    
    use FindBin;
    use lib "$FindBin::Bin/../";
    
    use VMware::VIRuntime;
    use AppUtil::VMUtil;
    
    $Util::script_version = "1.0";
    
    my %opts = (
        'vmname'      => { type => "=s", required => 0, help => "The name of the virtual machine", },
        'datacenter'  => { type => "=s", required => 0, variable => "datacenter", help => "Name of the datacenter", },
        'folder'      => { type => "=s", required => 0, variable => "folder", help => "Name of the folder" , },
        'pool'        => { type => "=s", required => 0, variable => "pool", help => "Name of the resource pool", },
        'host'        => { type => "=s", required => 0, variable => "host", help => "Name of the host" , },
        'ipaddress'   => { type => "=s", required => 0, help => "The IP address of virtual machine", },
        'guestos'     => { type => "=s", required => 0, help => "The guest OS running on virtual machine", }
    );
    
    Opts::add_options(%opts);
    Opts::parse();
    
    Util::connect();
    
    my @filter = map { Opts::get_option($_) } qw(vmname datacenter folder pool host);
    my %filterHash;
    $filterHash{'guest.ipAddress'} = Opts::get_option('ipaddress') if (Opts::get_option('ipaddress'));
    $filterHash{'config.guestFullName'} = qr/\Q&Opts::get_option('guestos')\E/i if (Opts::get_option('guestos'));
    my $vm_views = VMUtils::get_vms ('VirtualMachine', @filter, %filterHash);
    
    foreach my $vm_view (@$vm_views) {
        my $name     = $vm_view->name;
        my $memo     = $vm_view->config->annotation;
        my $devices  = $vm_view->config->hardware->{'device'};
        print "[vm] $name ($memo)\n";
    }
    
    Util::disconnect();

## 仮想マシンのパスの一覧出力

Utilクラスの`Util::get_inventory_path()`サブルーチンを使用すると、「仮想マシンとテンプレート」インベントリ上でのパスを取得できる。これの引数になる`$vim`オブジェクトは、`Util::connect()`でのサーバー接続時の返り値を使用する。

    #!/usr/bin/perl -w
    
    use strict;
    use warnings;
    use utf8;
    
    use FindBin;
    use lib "$FindBin::Bin/../";
    
    use VMware::VIRuntime;
    use AppUtil::VMUtil;
    
    $Util::script_version = "1.0";
    
    my %opts = (
        'vmname'      => { type => "=s", required => 0, help => "The name of the virtual machine", },
        'datacenter'  => { type => "=s", required => 0, variable => "datacenter", help => "Name of the datacenter", },
        'folder'      => { type => "=s", required => 0, variable => "folder", help => "Name of the folder" , },
        'pool'        => { type => "=s", required => 0, variable => "pool", help => "Name of the resource pool", },
        'host'        => { type => "=s", required => 0, variable => "host", help => "Name of the host" , },
        'ipaddress'   => { type => "=s", required => 0, help => "The IP address of virtual machine", },
        'guestos'     => { type => "=s", required => 0, help => "The guest OS running on virtual machine", }
    );
    
    Opts::add_options(%opts);
    Opts::parse();
    
    my $vim = Util::connect();
    
    my @filter = map { Opts::get_option($_) } qw(vmname datacenter folder pool host);
    my %filterHash;
    $filterHash{'guest.ipAddress'} = Opts::get_option('ipaddress') if (Opts::get_option('ipaddress'));
    $filterHash{'config.guestFullName'} = qr/\Q&Opts::get_option('guestos')\E/i if (Opts::get_option('guestos'));
    my $vm_views = VMUtils::get_vms ('VirtualMachine', @filter, %filterHash);
    
    foreach my $vm_view (@$vm_views) {
        my $path = Util::get_inventory_path($vm_view, $vim);
        my $memo = $vm_view->config->annotation;
        print "[vm] $path ($memo)\n";
    }
    
    Util::disconnect();

## 仮想マシンの仮想NICの一覧出力

仮想デバイスには`$vm_view->config->hardware->{'device'}`でアクセスできる。仮想デバイスのクラスは、`VirtualE1000`など種類毎にあるので、`ref($device)`で判別できる。また`VirtualE1000`は`VirtualEthernetCard`を継承しているなど、`$device->isa('親クラス')`でより大きなくくりでの種別を判断できる。

    #!/usr/bin/perl -w
    
    use strict;
    use warnings;
    use utf8;
    
    use FindBin;
    use lib "$FindBin::Bin/../";
    
    use VMware::VIRuntime;
    use AppUtil::VMUtil;
    
    $Util::script_version = "1.0";
    
    my %opts = (
        'vmname'      => { type => "=s", required => 0, help => "The name of the virtual machine", },
        'datacenter'  => { type => "=s", required => 0, variable => "datacenter", help => "Name of the datacenter", },
        'folder'      => { type => "=s", required => 0, variable => "folder", help => "Name of the folder" , },
        'pool'        => { type => "=s", required => 0, variable => "pool", help => "Name of the resource pool", },
        'host'        => { type => "=s", required => 0, variable => "host", help => "Name of the host" , },
        'ipaddress'   => { type => "=s", required => 0, help => "The IP address of virtual machine", },
        'guestos'     => { type => "=s", required => 0, help => "The guest OS running on virtual machine", }
    );
    
    Opts::add_options(%opts);
    Opts::parse();
    
    Util::connect();
    
    my @filter = map { Opts::get_option($_) } qw(vmname datacenter folder pool host);
    my %filterHash;
    $filterHash{'guest.ipAddress'} = Opts::get_option('ipaddress') if (Opts::get_option('ipaddress'));
    $filterHash{'config.guestFullName'} = qr/\Q&Opts::get_option('guestos')\E/i if (Opts::get_option('guestos'));
    my $vm_views = VMUtils::get_vms ('VirtualMachine', @filter, %filterHash);
    
    foreach my $vm_view (@$vm_views) {
        my $name     = $vm_view->name;
        my $memo     = $vm_view->config->annotation;
        my $devices  = $vm_view->config->hardware->{'device'};
        print "[vm] $name ($memo)\n";
        foreach my $device (@$devices) {
            next unless ($device->isa('VirtualEthernetCard'));
            printf("device:%s, type:%s, mac:%s, network:%s\n", ref($device), $device->{'addressType'}, $device->{'macAddress'}, $device->{'backing'}->{'deviceName'});
        }
    }
    
    Util::disconnect();

## 仮想マシンのメモの更新

仮想マシンのプロパティを変更するときは、変更内容を設定した`VirtualMachineConfigSpec`オブジェクトを生成して、`$vm_view->ReconfigVM_Task`メソッドで反映する。

    #!/usr/bin/perl -w
    
    use strict;
    use warnings;
    use utf8;
    
    use FindBin;
    use lib "$FindBin::Bin/../";
    
    use VMware::VIRuntime;
    use AppUtil::VMUtil;
    
    $Util::script_version = "1.0";
    
    my %opts = (
        'vmname'      => { type => "=s", required => 0, help => "The name of the virtual machine", },
        'datacenter'  => { type => "=s", required => 0, variable => "datacenter", help => "Name of the datacenter", },
        'folder'      => { type => "=s", required => 0, variable => "folder", help => "Name of the folder" , },
        'pool'        => { type => "=s", required => 0, variable => "pool", help => "Name of the resource pool", },
        'host'        => { type => "=s", required => 0, variable => "host", help => "Name of the host" , },
        'ipaddress'   => { type => "=s", required => 0, help => "The IP address of virtual machine", },
        'guestos'     => { type => "=s", required => 0, help => "The guest OS running on virtual machine", }
    );
    
    Opts::add_options(%opts);
    Opts::parse();
    
    Util::connect();
    
    my @filter = map { Opts::get_option($_) } qw(vmname datacenter folder pool host);
    my %filterHash;
    $filterHash{'guest.ipAddress'} = $ipaddress if ($ipaddress);
    $filterHash{'config.guestFullName'} = qr/\Q$guestos/i if ($guestos);
    my $vm_views = VMUtils::get_vms ('VirtualMachine', @filter, %filterHash);
    
    foreach my $vm_view (@$vm_views) {
        my $name     = $vm_view->name;
        my $config   = $vm_view->config;
        my $memo     = $config->annotation;
        print "[vm] $name ($memo)\n";
        $memo = localtime();
        my $spec = VirtualMachineConfigSpec->new (annotation => $memo);
        $vm_view->ReconfigVM_Task('spec' => $spec);
    }
    
    Util::disconnect();

----
本ページ内容は筆者が作業時の試行内容をまとめた個人的なメモです。内容を保証するものではなく、また筆者の所属組織等とは一切かかわりがありません。