【VMware@SoftLayer】PowerCLIによるvMotion自動化編

#前回までのあらすじ

IBMとVMwareが[協業](http://www.publickey1.jp/blog/16/ibm_vmware.html)しましたね。

SoftLayer上でVMwareを使っていろいろできるかどうか確認するという趣味を持つ私としては嬉しい限りです。

前回までの詳しい流れについては[こちら](http://qiita.com/khayama/items/b8dc884c7ea273861a24)の記事をご覧ください

#今回やること

今回はPowerCLIを利用してvCenterをまたぐvMotionを実行してみたいと思います。

もちろんご存知の通りvMotionはvSphere Web Clientから実行することができるのですが、スクリプトを作成しておくことで自動化することができ、様々な場面で利用することが可能となります。

例えば一気に複数台をvMotionしたいケース、Web Clientにログインできないケースなどが考えられます。

また、**複数のvCenterでサイトを管理している環境下で拡張リンクモードになっていない場合(vMotionを行うvCenter間で複数のドメインが混在している場合)、**vCenterから対向のサイトを見ることができないため、vCenterをまたぐvMotionをする際にはどうしてもコマンドを叩く必要が出てきます。

こんな時のためにスクリプトはあらかじめ作成しておくと良いと思います。

#PowerCLI

PowerCLIはPowerShellを利用してvSphere環境の管理を行うツールです。vCenterから実行可能なほとんどの操作をスクリプトとして記述することができるため、様々なオペレーションを自動化することが可能となります。

どのようなコマンドがあるかは[こちら](https://code.vmware.com/doc/preview?id=5591)の一覧をご覧ください。

#PowerCLIのインストール

以前のバージョンではMSI形式のインストーラーをMy VMwareのサイトからダウンロードする必要がありましたが、バージョン6.5.1からはPowerShell Galleryからダウンロードすることができるようになりました！

これにより、下記のコマンドをPowerShell上で実行するだけでインストールは完了します。

```PowerShell:
Save-Module -Name VMware.PowerCLI -Path <任意のディレクトリ>
```
とても簡単になりました。とはいえ、インストールするマシンがインターネットに接続されていない場合、オフラインで導入する必要があります。

その際は、[こちら](http://blog.radler.jp/2017/06/15/%E3%82%AA%E3%83%95%E3%83%A9%E3%82%A4%E3%83%B3%E3%81%A7-vmware-powercli-6-5-1-%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B/)をご確認ください。

また、インストール後、PowerCLIを利用しようとすると最初は下記のセキュリティエラーが出るかもしれません。
![vmotion5.png](https://qiita-image-store.s3.amazonaws.com/0/103277/87ea57d0-769d-843f-be2b-eebd8d303092.png)

このエラーが出た場合は、PowerCLIのスクリプトの実行をPowerShell側で許可する必要があります。PowerShellを管理者権限で起動し、下記コマンドをプロンプトから実行してください(実行後は元のポリシーに戻した方が良いと思います。)


```PowerShell:
Set-ExecutionPolicy RemoteSigned
```

これでPowerCLIのセットアップは完了です。

#スクリプトの作成

とりあえず作成したコードが以下になります。例外処理などはしてません。

```PowerShell:vMotion_Script.ps1
#PowerShellでPowerCLIのコマンドを利用
Import-Module VMware.PowerCLI

#接続するvCenterのFQDNを記述
$vC1 = "xxxxx1.vsphere.local"
$vC2 = "xxxxx2.vsphere.local"

#vCenterのログイン情報を記述
$vCUser = "username@vsphere.local"
$vCPass = "password"

#vCenterに接続
Connect-VIServer -Server $vC1 -User $vCUser -Password $vCPass
Connect-VIServer -Server $vC2 -User $vCUser -Password $vCPass

#仮想マシンの選択
$VM = Get-VM | Out-GridView -Title "vMotionで移行するVMを選択してください" -PassThru

#ネットワークアダプターの取得
$NA = Get-VM $VM | Get-NetworkAdapter

#移行先ホストの選択
$ESXi = Get-VMHost | Out-GridView -Title "移行先のホストを指定してください" -PassThru

#移行先データストアの選択
$DS = Get-Datastore | Out-GridView -Title "移行先のデータストアを選択してください" -PassThru

#移行先ポートグループの選択
$PG = Get-VirtualPortgroup | Out-GridView -Title "移行先のポートグループを選択してください" -PassThru
		
#移行情報を確認
Write-Host "移行対象仮想マシン:" $VM
Write-Host "移行先ホスト:" $ESXi
Write-Host "移行先データストア:" $DS
Write-Host "vMotionを開始します"

#vMotionの実行
Move-VM -VM $VM -Destination $ESXi -Datastore $DS -NetworkAdapter $NA -PortGroup $PG

Write-Host "vMotionが完了しました"

#vCenter Serverの切断
Disconnect-VIServer -Server $vC1 -Confirm:$false
Disconnect-VIServer -Server $vC2 -Confirm:$false

```

いくつかポイントを下記に整理します。

##PowerShellからPowerCLIを利用する

バージョン6.5.1から、PowerShellのスクリプトファイル(.ps1)内でのPowerCLIの利用が非常に簡単になりました。下記の1行を追加するだけで実行可能です。

```PowerShell:vMotion_Script.ps1
#PowerShellでPowerCLIのコマンドを利用
Import-Module VMware.PowerCLI
```

##移行元、移行先のvCenter Serverとの接続を確立

各VM、ホストやリソースグループ、データストア、ポートグループ、ネットワークアダプターの情報を取得するため、スクリプトを実行するマシンは移行元のvCenter Serverと、移行先のvCenter Serverの両方にアクセスできる必要があります。


```PowerShell:vMotion_Script.ps1
#vCenterに接続
Connect-VIServer -Server $vC1 -User $vCUser -Password $vCPass
Connect-VIServer -Server $vC2 -User $vCUser -Password $vCPass
```

##Cross-vCenter-vMotionを実行する場合

vCenterを跨ぐvMotionを実行する場合、Move-VMに渡す[パラメータ](https://code.vmware.com/doc/preview?id=5591#/doc/Move-VM.html)のうち、最低でも下記の4つのパラメータが必須になります。

| パラメータ | 概要 |
|:-:|:----|
|Destination|仮想マシンの移行先(フォルダー、ホスト、クラスター、リソースプール)|
|Datastore|移行先のデータストア|
|NetworkAdapter|移行先のポートグループを割り当てるネットワークアダプター|
|PortGroup|移行先のポートグループ|


```PowerShell:vMotion_Script.ps1
#vMotionの実行
Move-VM -VM $VM -Destination $ESXi -Datastore $DS -NetworkAdapter $NA -PortGroup $PG
```

#スクリプトの実行

作成したスクリプトを実行します。PowerShellを管理者権限で開き、作成したps1ファイルを実行してください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103277/15b801f4-d2ce-1be7-fc2f-da5f7f8e9c0c.png)

実行するとまずは各vCenter Serverに接続します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103277/c9083712-b1d0-7e92-d437-5e2d0f02622a.png)

接続が完了すると、ウィンドウが開きます。移行したい仮想マシンを選択し、「OK」をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103277/02043d6e-c446-411c-4dc0-72f4e2a8730e.png)

同様に、**移行先**のホスト、データストア、ポートグループを選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103277/8c05ab90-97f2-04b9-44ac-78ad8bf5ad35.png)

これで完了です。あとはコマンドに変数が渡され、vMotionが実行されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103277/5f97c5a1-d52d-97e6-4f63-00eb74061933.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103277/21e2f17a-14b7-37ca-aafc-c4568e57bdb1.png)

vCenter側でタスクを確認すると、確かにvMotionが実行されています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103277/4d9fb3f0-16da-611a-400e-79d40e13f31f.png)
ちなみにPowerShell側の進行度とvCenter側の進行度はなぜか面白いほど同期されていません。

**vMotion完了！**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103277/347a017c-53ea-1137-eb61-a8111d83b35b.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103277/30812a9a-28db-4320-1345-8597f85f281e.png)


※vMotion完了までに時間がかかりすぎてPowerShell側でタイムアウトするようであれば下記のコマンドでタイムアウト時間を変更してみてください。なお、PowerShell側でタイムアウトしているだけでWeb Clientで見るとvMotionがきちんと完了している場合もあります。

```PowerShell:
Set-PowerCLIConfiguration -WebOperationTimeoutSeconds 3600
```


#複数台VMでのvMotion自動化への応用

上記で作成したスクリプトでは、同時に1つの仮想マシンしか移行できません。そこで、CSVなどの外部ファイルを読み込み、そこに記載されている仮想マシン全てにvMotionを実行するスクリプトを作成します。

まずは仮想マシンと、その移行先情報を入力したCSVファイルをあらかじめ作成します。
作成したCSVファイルは適当な名前をつけてスクリプトファイルと同じフォルダに置いておきます。

```csv:vMotion_Script_List.csv
VMName,HostName,DataStore,PortGroup
vMotion-test1,esx01.vsphere.local,Datastore1,vxw-dvs-xx-universalwire-xx-sid-xxxxxx-VXLAN
vMotion-test2,esx01.vsphere.local,Datastore1,vxw-dvs-xx-universalwire-xx-sid-xxxxxx-VXLAN
vMotion-test3,esx01.vsphere.local,Datastore1,vxw-dvs-xx-universalwire-xx-sid-xxxxxx-VXLAN
```


作成したスクリプトは下記になります。こちらも例外処理などはしてません。

```PowerShell:vMotion_Script_csv.ps1
#PowerShellでPowerCLIのコマンドを利用
Import-Module VMware.PowerCLI

#接続するvCenterのFQDNを記述
$vC1 = "xxxxx1.vsphere.local"
$vC2 = "xxxxx2.vsphere.local"

#vCenterのログイン情報を記述
$vCUser = "username@vsphere.local"
$vCPass = "password"

#vCenterに接続
Connect-VIServer -Server $vC1 -User $vCUser -Password $vCPass
Connect-VIServer -Server $vC2 -User $vCUser -Password $vCPass

#CSVファイルの読み込み
$List = Import-Csv .\vMotion_Script_List.csv

#移行仮想マシンの抽出
foreach ($VMList in $List){

    #仮想マシン名
    $VMName = $VMList.VMName
    $VM = Get-VM -Name $VMName
    
    #ネットワークアダプターの取得
    $NA = Get-VM $VMName | Get-NetworkAdapter
    
    #移行先ホスト
    $ESXiName = $VMList.HostName
    $ESXi = Get-VMHost -Name $ESXiName 
    
    #移行先データストア
    $DSName = $VMList.DataStore
    $DS = Get-Datastore -Name $DSName
    
    #移行先ポートグループ
    $PGName = $VMList.PortGroup
    $PG = Get-VirtualPortGroup -Name $PGName
    
    #vMotionの実行
    Move-VM -VM $VM -Destination $ESXi -Datastore $DS -NetworkAdapter $NA -PortGroup $PG   
}
    
#vCenter Serverの切断
Disconnect-VIServer -Server $vC1 -Confirm:$false
Disconnect-VIServer -Server $vC2 -Confirm:$false

```

実行します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103277/cf7eec70-1209-f5b8-b672-1f2e46294190.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103277/8e8ad148-b358-f3a2-d8ff-e0a485051a6e.png)


これでCSVファイルに列挙されている全ての仮想マシンを自動的にvMotionすることが可能となります。あらかじめ作成しておけばいざという時に利用できますね。環境が複雑化している複数のドメイン間のvMotion時には威力を発揮できそうです。

#まとめ

今回はvMotionをvCenterから行うのではなく、PowerCLIを利用してスクリプトを実行することでvMotionが可能なことを確認しました。PowerCLIを利用すれば、クラスターやホスト、vCenterやSSOドメインに関係なくvMotionを実行することが可能になります。(もちろんvMotionの要件は満たす必要があります。)

ぜひお試しください。