ESXiのみ環境でPowerCLIを使ってテンプレートもどきの動作をする手法


vCenterサーバがない、ESXiサーバのみ環境ではテンプレート機能が使用できない。

とはいえ、テンプレート化した仮想マシンの中身を見ると、ふつうと同じく仮想ハードディスクのvmdkファイルが存在しているので、vmdkファイルをコピーして、新規仮想マシンを作成するPowerCLIスクリプトをかけば、似たようなことができるな、と実験。

準備するもの

・PowerCLIをインストールした環境
Windows 10で実行したが、Linux環境にPowerShell+PowerCLIをセットアップしてもいけるはず。

・Windowsの場合、sysprepを実行してシャットダウンしたvmdkファイル
sysprepを実行して、次回起動時に初期セットアップが開始されるようにしたvmdkファイル。
VMware-toolsはインストール済みであることが望ましい。

・Linuxの場合、下記の情報などを削除
RHEL7の仮想化の導入および管理ガイド第4章 仮想マシンのクローン作成によれば
/etc/udev/rules.d/70-persistent-net.rules を削除
/etc/ssh/ssh_host_* を削除
/etc/sysconfig/network-scripts/ifcfg-eth* などから IPADDRESS,NETMASK,HWADDRなどの値削除

スクリプト本体

Import-Module VMware.VimAutomation.Core

#Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false

$vcenterserver="ESXiサーバ"
$vcenteruser="ユーザ名"
$vcenterpassword="パスワード"

$targetdatastore="仮想マシンをおくデータストア名"

# 仮想マシンの名前 / ランダムで作成して、あとから変更する手法
$vmnamebase="NewVM_"
$vmnametmp=Get-Random
$vmname=$vmnamebase+$vmnametmp

# 仮想マシンスペックと接続ネットワーク指定
$vcpu=2
$vmem=6
$network="VM Network"

# 指定できるGuestOSのIDを調べるには下記を実行すること
#   PowerCLIがサポートしている一覧 
#   [VMware.Vim.VirtualMachineGuestOsIdentifier].GetEnumValues()
# 代表的なもの
# windows8Server64Guest = Windows2012
# windows9Server64Guest = Windows2016
#$vmguestosid="windows9Server64Guest"

# 元ネタのWindowsが入ったvmdkファイルの指定
# 構築時にBIOS環境かEFI環境のどちらで作ったのか注意
$vmdkfilepath="[データストア名] windows2019/windows2019.vmdk"
$vmguestosid="windows9Server64Guest"
#$vmdkfilepath="[データストア名] win2016/win2016.vmdk"
#$vmguestosid="windows9Server64Guest"
#$vmdkfilepath="[データストア名] win2012/win2012.vmdk"
#$vmguestosid="windows8Server64Guest"
# 上記の元ネタが置いてあるデータストア名を下記でも指定する
$sourcedatastore ="データストア名"

# vCenterまたはESXiサーバに接続
Connect-VIServer -Server $vcenterserver -User $vcenteruser -Password $vcenterpassword -WarningAction 0
# パスワードを書きたくない場合は
# New-VICredentialStoreItem -Host $vcenterserver -User $vcenteruser -Password $vcenterpassword
# を実行すると、資格情報保存域に登録され、以降は下記だけで接続できるようになる
# Connect-VIServer -Server $vcenterserver

$virtualportgroup=Get-VirtualPortGroup -Name $network
$datastore=Get-Datastore -Name $targetdatastore
$vm=New-VM -Name $vmname -NumCpu $vcpu -MemoryGB $vmem -Portgroup $virtualportgroup -Datastore $datastore -DiskStorageFormat Thin -GuestID $vmguestosid -HardwareVersion vmx-14


$olddiskinfo=Get-Vm $vmname|Get-Harddisk # 一時的に作られたディスクの情報を保存
$sourcevmdk=Get-HardDisk -Datastore $sourcedatastore -DatastorePath $vmdkfilepath
# ディスクの削除
Remove-HardDisk -HardDisk $olddiskinfo -Confirm:$false


# コピー先データストアのパスを生成
$targetvmdktmp=$olddiskinfo.Filename
$ed=$targetvmdktmp.LastIndexOf("/")
$targetvmdk=$targetvmdktmp.Substring(0,$ed+1) # コピー先のパス

# OSが入ったvmdkのコピー
$adddiskinfo=Copy-HardDisk -Harddisk $sourcevmdk -DestinationPath $targetvmdk -DestinationStorageFormat Thin

#$vm = get-Vm $vmname
New-HardDisk -VM $vm -DiskPath $adddiskinfo.Filename

Get-ScsiController -VM $vm | Set-ScsiController -Type VirtualLsiLogicSAS

# 仮想マシン設定変更用オブジェクト定義
$newSpec = New-Object VMware.Vim.VirtualMachineConfigSpec

# USBコントローラの追加
# これがないとWindows環境でマウスが動かない
# https://communities.vmware.com/t5/VMware-PowerCLI-Discussions/Where-is-the-quot-Get-USBController-quot-cmdlet-Same-with-Remove/td-p/2155582
# 上記だとUSB 2.0コントローラ追加
$newSpec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (1)
$newSpec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec
$newSpec.deviceChange[0].operation = "add"
#$newSpec.deviceChange[0].device = New-Object VMware.Vim.VirtualUSBController # USB2.0コントローラ
$newSpec.deviceChange[0].device = New-Object VMware.Vim.VirtualUSBXHCIController # USB3.0コントローラ

# EFIかBIOSか
# https://docs.vmware.com/jp/VMware-Cloud-on-AWS/services/com.vmware.vsphere.vmc-aws-manage-vms.doc/GUID-898217D4-689D-4EB5-866C-888353FE241C.html
#https://github.com/vmware/PowerCLI-Example-Scripts/blob/master/Scripts/SecureBoot.ps1
# BIOSを設定する場合は、SecureBootをdisableにする必要がある
#$newSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
# 仮想マシン起動オプション変更用オブジェクト定義
$bootOptions = New-Object VMware.Vim.VirtualMachineBootOptions
#$newSpec.Firmware = [VMware.Vim.GuestOsDescriptorFirmwareType]::efi
#$bootOptions.EfiSecureBootEnabled = $true
$newSpec.Firmware = [VMware.Vim.GuestOsDescriptorFirmwareType]::bios
$bootOptions.EfiSecureBootEnabled = $false
$newSpec.BootOptions=$bootOptions


# 仮想マシンへの設定反映
#(get-view $vm).ReconfigVM_Task($newSpec)
$vm.ExtensionData.ReconfigVM($newSpec)


# 接続切断
Disconnect-VIServer -Server $vcenterserver -Confirm:$false

解説

仮想マシンにハードディスクを追加する

仮想マシンに新しく空っぽのハードディスクを追加する場合は、「New-HardDisk -VM 仮想マシン ~」で指定するが、Copy-HardDiskでコピーしてきたハードディスクを登録する場合が分かりづらかった。

結果としては、新規と同じく「New-HardDisk -VM 仮想マシン ~」でよかった。

今回の場合は、CopyHardDiskを実行した結果を変数にいれて、それをNew-HardDIskで登録、という形にした。

$adddiskinfo=Copy-HardDisk -Harddisk $sourcevmdk -DestinationPath $targetvmdk -DestinationStorageFormat Thin

$vm = get-Vm $vmname
New-HardDisk -VM $vm -DiskPath $adddiskinfo.Filename

仮想マシンハードウェアにUSB 3.0コントローラを追加する

Host Clientから作成した場合は、USB 3.0コントローラが作成されていたが、New-VMコマンドでは作成されなかった。このため、Windowsが起動した後にUSBマウスが存在できず、マウス操作ができなかった。(キーボードはPS/2キーボード扱いとして使えたようだった)

このUSB 3.0コントローラを追加するための操作がわからず、いろいろ調べたところ「Where is the “Get-USBController” cmdlet? (Same with Remove- and New-)」の記述を見て、USB 2.0コントローラの追加手法が分かった。

その後、VirtualUSBController を起点に調べることで、 xHCIはVirtualUSBXHCIControllerという名前であることがわかり、解決した

$vm=Get-VM -Name 仮想マシン名
$newSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
$newSpec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (1)
$newSpec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec
$newSpec.deviceChange[0].operation = "add"
#$newSpec.deviceChange[0].device = New-Object VMware.Vim.VirtualUSBController # USB2.0コントローラ
$newSpec.deviceChange[0].device = New-Object VMware.Vim.VirtualUSBXHCIController # USB3.0コントローラ

# 仮想マシンへの設定反映
#(get-view $vm).ReconfigVM_Task($newSpec)
$vm.ExtensionData.ReconfigVM($newSpec)

設定を反映する部分は、ネタ元では「Get-View」を使っていたが、後述のSecureBootについての結果ではGet-VM経由で実施しているスクリプトがあったので、それを使用している。

BIOS/EFI切り替え

仮想マシンをBIOS起動にするか、EFI起動にするかを設定する手法。

2021現在のPowerCLIでNew-VMした時のデフォルトはEFI起動でセキュアブート有効になっている。

これをBIOS起動に設定する場合は、セキュアブートを無効にしてからBIOSに切り替える必要があるので下記にようになる。

$vm=Get-VM -Name 仮想マシン名
$newSpec = New-Object VMware.Vim.VirtualMachineConfigSpec

$bootOptions = New-Object VMware.Vim.VirtualMachineBootOptions
$bootOptions.EfiSecureBootEnabled = $false
$newSpec.BootOptions=$bootOptions

$newSpec.Firmware = [VMware.Vim.GuestOsDescriptorFirmwareType]::bios

$vm.ExtensionData.ReconfigVM($newSpec)



ADG 100W GaN Charger & Hub が届いた


2020年7月にクラウドファンディングを開始した「ADG 100W GaN Charger & Hub」が、当初予定の2020年8月出荷予定から盛大に遅れて、2021年5月1日に到着した。

(企業名は当初ADG(ADG wireless)だったのがいつの間にかINVZI変わった模様)

3月中旬に出荷します!というアップデートがあったきり、なんの連絡もないので、どうなるか不安だったのですが、発送連絡もなく突然届きました。

え?と思ってIndiegogoのMy Contributionsページを確認するとTracking numberが追加されてるという・・・いつの間に???

さて、荷物は中国から4pxの集約出荷サービスのようなものを使ってるのか、日本で国内配送用のラベルが追加されて到着しました。

画像
画像

こちらの製品のパッケージはこんな感じで、USB Type-C PD 100W電源にUSB Hub機能とHDMI出力、SDカードスロット/microSDカードスロット、1Gb NIC、オーディオ入出力がついている、というものです。

画像
画像

中身はこんな感じ

画像

認証マークに菱形のPSEマークもありますが、ちゃんとしたやつなのかは確証が得られませんでした(菱形PSEマークについての責任の所在/企業体が書かれていないので)

画像

さて、さしあたって手持ちのUSB PD対応機器であるGPD Pocketにつないで見ると、12Vの供給が開始され使用できそうです。

画像

接続する場合の注意点があります。

各ポートに機器を繋いだ場合、下記のような動作します。

そう、HDMIとかかれていますが、おそらくDisplayPort Alternate Modeに対応した機器の出力専用なようで、非対応のGPD Pocketでは「USB 2.0 BILLBOARD」デバイスとしてしか認識されません。(BILLBOARDデバイスはDisplayPort Altモードの検出用デバイスらしい:CQ出版【USBコラム11】Alternate Modeに関する情報を通知する「ビルボード・デバイス・クラス」

オーディオ端子に何もつなげていない場合は上記のようになっていますが、イヤフォン(マイクなし)を繋ぐと、デバイスが追加認識され、下記の様になります。

マイク付きのヘッドセットにつなぎ替えると下記の様なデバイス構成に変更されます。

HDMI出力ができないのは残念ですが、GPD Pocketで電源供給しつつUSBデバイスをつなげる、ということは可能なようなので一安心です。

ケーブルの問題を疑って下記のThunderbolt4ケーブルを買ってみました。

これでGPD Pocketに繋いでみると、デバイスの認識状況に変化が・・・

汎用USBハブが2つ(汎用USBハブと汎用SuperSpeed USBハブ)に分離しました。(上記はオーディオ未接続状態)

ただ、それでもHDMI出力はできませんでした。

Type-C出力ができそうな機械を探すとhp ProBook 430 G5がありましたので同じくThunderbolt4ケーブルで繋いでみると、こちらはHDMI出力ができました。

ちゃんとしたケーブルを使えば問題なく動く、ということのようですね。

ただ・・・ADGの難点としては、やっぱりちょっと大きいということがありますね

手持ちのUSB アダプターも兼ねている10000mAhバッテリーより大きくて重いんですよね

ちょっと悩みどころで、今回私は送料込みで$69で買ったのですが、おそらく1万円以上するとなると悩む感じですね。

いまからだと SlimQのクラウドファンディングThe most portable 240W laptop charger のが面白いかなぁ?とは思います。

USB Hub機能は無いですが、USB PD 100W機器を2個同時接続可能というあたりですね。


参考情報

MacBook Air (M1, 2020) Big Sur 11.2.1環境ではHDMI出力が動作しなかった、ケーブルをE-Markチップ内蔵タイプに変更したらHDMI出力が動作したとのこと。

MacBook Air (M1, 2020) – 技術仕様 では「Thunderbolt 3デジタルビデオ出力USB-C経由でDisplayPort出力に標準対応」と書いてあるので対応していそうなのですが、ダメだった、とのこと

https://twitter.com/naitwo2/status/1389393674920816641

ThinkPad X1 Carbonでは可能だったとのこと。

ThinkPad X1 Carbon 製品仕様書(2017版)ThinkPad X1 Carbon 製品仕様書(2018版) 共に 「Type-C USB3.1 2個 (DC-in、Thunderbolt3、Video-out機能付き)」とある。

DELL XPS 7590, GPD MicroPC, Surface Go 2で動作したとのこと。

この結果をうけてGPD Pocket(初代)の仕様を再確認したところ、Displayport Altモードに対応はしているものの、USB PD充電中は使用できない、という面倒くさい設定なようでした・・・