Help us understand the problem. What is going on with this article?

AnsibleでWindowsにプログラムをインストールする(win_msiとwin_package)

More than 3 years have passed since last update.

ansibleでWindowsにプログラムをインストールする(win_msiとwin_package)

プロビジョニング・ツール(環境構築ツール)のAnsibleがバージョン2.0となりました。Linuxだけではなく、Windows対応も充実してきていました。

今回は、Windowsへアプリケーションをインストールする操作を、Ansibleで実施する際のメモです。

win_msiとwin_package

Ansible 2.0では、Windows OSの管理ノードに対して、アプリケーションのインストーラファイルからインストールする作業を直接サポートするモジュールとして従来からのwin_msiモジュールに加えてwin_packageモジュールが提供されています。

win_msiモジュール

win_msiモジュールは、指定したパスにあるmsi形式のインストーラファイルを実行します。ただし、同じバージョンがインストール済みかどうかはチェックせずに常にmsiexecを実行します。そのため、Ansible上ではこのモジュールの実行結果がインストールが実施されたかどうかによらず常にchangedになってしまいます。

また、インストール可能なファイルはMSI形式に限定されます。

win_msiモジュールのマニュアルは次です。
http://docs.ansible.com/ansible/win_msi_module.html

使用例は次のようになります。

  - name: アナログ時計プログラムのインストール
    win_msi: path="\\\\fs.example.local\\installers\\Analog Clock-0.1.0.msi"

サイレントインストール・オプションを指定しなくてもいいのがうれしいですね。

しかしながら、毎回changedになってしまうのはいただけません。

win_packageモジュール

win_packageモジュールは、指定したパスにあるインストーラファイル(msi形式でもexe形式でも可)を実行します。また、インストール済みかどうかを調べてインストール済みであればchangedにはなりません。ただ、インストール済みかどうかの判断に使う情報としてProduct_IDを指定する必要があります。win_packageモジュールは、既にインストール済みかを判断する際に、このProduct_IDを使用します。

win_packageモジュールのマニュアルは次です。
http://docs.ansible.com/ansible/win_package_module.html

使用例は次のようになります。

  - name: アナログ時計プログラムのインストール
    win_package:
      path="\\\\fs.example.com\\installers\\Analog Clock-0.1.0.msi"
      Product_Id="122902F6-FD9F-40FC-80A7-8EA75CF382E1"
      arguments="/q"

サイレントインストールのオプションを指定します。MSI形式であれば"/q"ですが、それ以外のインストーラはそれぞれで用意されているサイレントインストールのオプションを調べて記述します。

このProduct_IDを取得するには、いったん対象ソフトウェアをインストールしてからOSのコマンドで、あるいはレジストリを調べるのが手っ取り早いです。インストールせずに調べるとしたら、Windows SDKに含まれるOrcaを使うか、後述する方法で調べるかあたりとなります。

インストールされているプログラムのProduct_Idをコマンドで調べるにはPowerShellからGet-WmiObjectコマンドで確認できます。次のWikiページにGet-WmiObjectでソフトウェア情報を取得する方法を記述しています。

Windows Management Instrumentation - インストールされているソフトウェアの情報を取得する

または、レジストリを調べることでも確認できます。

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

この下に、Product_Idのツリーが並んでいます。MSI形式インストーラでインストールされたものは大抵がUUIDとなっています。その他のインストーラでインストールしたものは、ソフトウェア名になっているものがあります。

MSI形式インストーラファイルからProduct_Idを調べるには、次のURLで紹介されているPowerShellスクリプトを使うと便利です。
http://www.scconfigmgr.com/2014/08/22/how-to-get-msi-file-information-with-powershell/

PowerShellスクリプトでエラー

"5" 個の引数を指定して "InvokeMember" を呼び出し中に例外が発生しました: "OpenDatabase,DatabasePath,OpenMode
発生場所 行:1 文字:114
+ ... ase", "InvokeMethod", $Null, $windowsInstaller, @($Path.FullName, 0))
+                                                       ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : COMException

このエラーは、MSIファイル名を相対パス(またはファイル名のみ指定)で指定したとき、$Path.FullNameが実在とは別なパスを返したために発生しました。

  • D:\users\work\foo.msi
    • $Path.FullName -> C:\Users\torutk\foo.msi

デバッグのためスクリプト中で$Path.FullNameを表示させると、環境変数USERPROFILEの直下にあるパスとなっていました。

PS> $pwd
Path
----
D:\users\work

PS> [System.environment]::CurrentDirectory
C:\Users\torutk

$Path.FullNameは、PowerShellコンソール上でカレントディレクトリを移動させても、それを反映していないように見えます。これを次のように書き換えます。

- @($Path.FullName, 0)
+ @((Resolve-Path $Path).Path, 0)

ドメイン環境でのUNCの使用は問題あり

workgroupでは問題なく使えたUNCパスですが、ドメイン環境では問題が発生しました。
"double hop"問題と言われ、クライアント(ここではAnsible実行マシン)、管理ノード、ファイル共有サーバーがそれぞれ別のマシンである場合、認証の制約でファイルへのアクセス権が得られないといったものです。
回避策は、UNCの使用をやめて、httpでインストーラーファイルを取得することです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした