vmware_vm_shellを使ってPowershellのスクリプトをPlaybookに直書きできないか確認してみました。
環境
項目 | バージョン | 備考 |
---|---|---|
vCenter | 6.7.0 | |
Windows Server | 2016 | Powershellを実行する対象ホスト |
Powershellスクリプト
今回は簡単に検証するので以下のシンプルなPowershellスクリプトを使います。
1 2 3 4 5 6 7 |
$interface = Get-WmiObject Win32_NetworkAdapterConfiguration -filter "ipenabled = 'true'" ` | ? { $_.IPAddress -match "192.168.0.131"} if($interface) { $interface.SetDnsDomain("example.local") $interface.SetDynamicDNSRegistration($true,$true) } |
上記のスクリプトは以下赤枠のNIC設定をするものです。
NICのオブジェクトからIPアドレスでフィルタリングして設定します。
これをvmware_vm_shellで実装すると次のようなPlaybookになります。
Playbook
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
--- - name: test powershell script in playbook using vmware_vm_shell module hosts: localhost gather_facts: no vars: hostname: vCenter IP username: administrator@vsphere.local password: password datacenter: DC folder: /vm name: WINSRV002 vm_username: administrator vm_password: guest user password tasks: - name: run powershell script in guest os vmware_vm_shell: hostname: "{{ hostname }}" username: "{{ username }}" password: "{{ password }}" validate_certs: no datacenter: "{{ datacenter }}" folder: "{{ folder }}" vm_id: "{{ name }}" vm_username: "{{ vm_username }}" vm_password: "{{ vm_password }}" wait_for_process: yes vm_shell: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe vm_shell_args: >- -c "&{ $interface = Get-WmiObject Win32_NetworkAdapterConfiguration -filter "{ ipenabled = 'true' }" ` | ? { $_.IPAddress -match "{{ ip_addr }}" } if($interface) { $interface.SetDnsDomain({"example.local"}) $interface.SetDynamicDNSRegistration($true,$true) } }" vars: ip_addr: 192.168.0.131 register: result - debug: var=result |
スクリプトの内容はpowershellコマンドの引数で渡す必要があります。
そのため -Command
オプションを使用しています。
-Command
オプションの場合、普通に書くとエスケープが必要になるので、ここではスクリプトブロックを使用しています。
powershellスクリプトをそのまま貼り付けて使うことは出来ないので少し面倒ですがいくつかの部分でスクリプトブロックを使う必要が出てきます。
ここでは -filter
オプションの引数やメソッドに渡す文字列を {}
で囲むように改修しています。
Ansibleの変数も問題なく使うことができます。
実機で直接動作確認する場合は、以下のように実行してエラーが無ければPlaybook内でも実行できると思います。
1 2 |
powershell.exe -c '&{処理}' |
以下は実際に動作確認した時の例です。
1 2 3 4 5 6 7 8 9 |
powershell -c '&{ $interface = Get-WmiObject Win32_NetworkAdapterConfiguration -filter "{ipenabled = 'true'}" ` | ? { $_.IPAddress -match "192.168.0.131"} if($interface) { $interface.SetDnsDomain({"example.local"}) $interface.SetDynamicDNSRegistration($true,$false) } }' |
実行
実行して設定が反映されることを確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
$ ansible-playbook main.yml [WARNING]: No inventory was parsed, only implicit localhost is available [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' [WARNING]: Found variable using reserved name: name PLAY [test powershell script in playbook using vmware_vm_shell module] ********************************************************************************************** TASK [hoge] ********************************************************************************************************************************************************* changed: [localhost] TASK [debug] ******************************************************************************************************************************************************** ok: [localhost] => { "result": { "changed": true, "cmd_line": "\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" -c \"&{\n $interface = Get-WmiObject Win32_NetworkAdapterConfiguration -filter \"{ ipenabled = 'true' }\" `\n | ? { $_.IPAddress -match \"192.168.0.131\" }\n if($interface) {\n $interface.SetDnsDomain({ example.local })\n $interface.SetDynamicDNSRegistration($true,$true)\n }\n }\"", "end_time": "2019-10-09T10:59:16+00:00", "exit_code": 0, "failed": false, "name": "powershell.exe", "owner": "administrator", "start_time": "2019-10-09T10:59:14+00:00", "uuid": "423016ab-c45a-df44-dbef-190d6baec5b7" } } PLAY RECAP ********************************************************************************************************************************************************** localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 |
最後に
「Powershellスクリプトを送り込んで実行する」というのは少し面倒ですが、直接Playbookに書けると楽になりますね(Playbook向けに改修が必要ですが) 🙂
WinRMが設定されていなかったりネットワークのリーチャビリティーが無くて簡単なpowershellスクリプトを実行したい時とかは便利かもしれません。
例えば、VMデプロイ後の初期設定とかですかね 🙂
これで、Playbookと一緒にPowershellスクリプトの管理も一緒に出来そうです!
それでは、みんなでハッピーオートメーション!