Ansible win_powershellスクリプト実行:引数渡しと結果取得の完全マニュアル

2025-03-21

Ansibleの "win_powershell" モジュールとは?

Ansibleの "win_powershell" モジュールは、Windowsターゲットマシン上でPowerShellスクリプトを実行するためのモジュールです。このモジュールを使用することで、AnsibleのプレイブックからWindows環境に対してPowerShellコマンドやスクリプトを実行し、システムの構成管理や自動化を行うことができます。

主な機能と使い方

  • 冪等性
    • 冪等性を考慮したPowerShellスクリプトを作成することで、同じタスクを複数回実行しても結果が変わらないようにすることができます。
  • エラー処理
    • PowerShellスクリプトの実行結果に基づいて、Ansibleのタスクの成功・失敗を判定できます。
  • 引数の受け渡し
    • "arguments" パラメータを使用することで、PowerShellスクリプトに引数を渡すことができます。
  • PowerShellスクリプトの実行
    • "script" パラメータにPowerShellスクリプトのパスを指定することで、そのスクリプトを実行できます。
    • "inline" パラメータに直接PowerShellコードを記述することも可能です。


- name: PowerShellスクリプトを実行する
  win_powershell:
    script: C:\scripts\my_script.ps1
    arguments: -Param1 "value1" -Param2 "value2"

- name: インラインPowerShellコードを実行する
  win_powershell:
    inline: |
      Get-Process | Where-Object {$_.ProcessName -eq "notepad"} | Stop-Process

詳細

  • 冪等性を確保するために、スクリプトは、実行するたびに同じ結果が返るように記述する必要があります。
  • Ansibleの変数やファクトをPowerShellスクリプト内で使用することができます。
  • モジュールは、PowerShellの出力(標準出力、標準エラー出力)をキャプチャし、Ansibleのログに表示します。
  • PowerShellスクリプトの実行結果は、Ansibleのタスクの結果として返されます。
  • "win_powershell" モジュールは、Windowsリモート管理 (WinRM) を使用してターゲットマシンと通信します。

利点

  • システムの構成管理やアプリケーションのデプロイなどを自動化できます。
  • Ansibleの豊富な機能とPowerShellの強力な機能を組み合わせることができます。
  • Windows環境の自動化をPowerShellで柔軟に行うことができます。

Ansibleの "win_powershell" モジュールは、Windows環境の自動化に不可欠なツールです。PowerShellスクリプトをAnsibleのプレイブックに統合することで、Windowsシステムの管理を効率化し、自動化を実現できます。



よくあるエラーとトラブルシューティング

  1. WinRM接続の問題
    • エラー
      "Failed to connect to the host via WinRM."
    • 原因
      WinRMがターゲットマシンで正しく設定されていない、ファイアウォールがポートをブロックしている、認証情報が間違っているなど。
    • トラブルシューティング
      • ターゲットマシンで winrm quickconfig を実行し、WinRMが有効になっているか確認します。
      • ファイアウォールでWinRMポート (通常は5985または5986) が開いているか確認します。
      • Ansibleのインベントリファイルで正しい認証情報 (ユーザー名、パスワード) を指定しているか確認します。
      • ansible_winrm_transportbasic, ntlm, kerberos など適切なものに設定します。
  2. PowerShellスクリプトのエラー
    • エラー
      PowerShellスクリプトの実行結果がエラーになる、または予期しない結果になる。
    • 原因
      スクリプトの構文エラー、論理エラー、必要なモジュールがインストールされていないなど。
    • トラブルシューティング
      • ターゲットマシンで直接PowerShellスクリプトを実行し、エラーメッセージを確認します。
      • AnsibleのログでPowerShellスクリプトの出力 (標準出力、標準エラー出力) を確認します。 verbosity を上げることでより詳細なログが確認できます。
      • 必要なPowerShellモジュールがターゲットマシンにインストールされているか確認します。 Install-Module などで必要なモジュールをインストールします。
      • スクリプト内でエラー処理を適切に行い、エラー発生時に詳細な情報を出力するようにします。
  3. 文字コードの問題
    • エラー
      PowerShellスクリプトの出力が文字化けする。
    • 原因
      Ansibleとターゲットマシンの文字コード設定が一致していない。
    • トラブルシューティング
      • PowerShellスクリプトのエンコーディングをUTF-8に設定します。
      • Ansibleの ansible_encoding 変数を適切な文字コードに設定します。
      • ターゲットマシンのPowerShellのデフォルトエンコーディングをUTF-8に変更します。
  4. 権限の問題
    • エラー
      "Access is denied." などの権限エラーが発生する。
    • 原因
      Ansibleのユーザーアカウントにターゲットマシンで必要な権限がない。
    • トラブルシューティング
      • Ansibleのユーザーアカウントに管理者権限があるか確認します。
      • PowerShellスクリプトで必要な権限を持つユーザーアカウントで実行するようにします。
      • UAC (ユーザーアカウント制御) が問題を引き起こしている場合は、UACを一時的に無効化してテストします。
  5. モジュールの依存関係の問題
    • エラー
      モジュールがみつからないなどのエラーがでる。
    • 原因
      モジュールに必要な依存関係がインストールされていない。
    • トラブルシューティング
      • 必要なモジュールを Install-Module などでインストールします。
      • モジュールの依存関係を確認し、不足しているものをインストールします。
  6. 冪等性の問題
    • エラー
      同じタスクを複数回実行すると、結果が変わってしまう。
    • 原因
      PowerShellスクリプトが冪等性を考慮して作成されていない。
    • トラブルシューティング
      • PowerShellスクリプト内で、すでに実行済みの状態をチェックし、必要な場合にのみ処理を実行するようにします。
      • Test-PathGet-Item などのコマンドレットを使用して、対象の状態を確認します。
  7. スクリプト実行パスの問題
    • エラー
      スクリプトが見つからないというエラーがでる。
    • 原因
      スクリプトのパスが間違っている。
    • トラブルシューティング
      • スクリプトパスが正しいか確認します。
      • 絶対パスで指定します。
      • Ansibleのファイル転送モジュールでスクリプトを転送してから実行するようにします。
  • Ansibleの debug モジュールを使用して、変数や状態を確認します。
  • PowerShellスクリプト内で Write-HostWrite-Output を使用して、デバッグ情報を出力します。
  • ターゲットマシンで直接PowerShellスクリプトを実行し、エラーメッセージを確認します。
  • verbosity を上げてAnsibleのログを詳細に表示します (-vvv など)。


例1: ファイルの存在確認と作成

- name: ファイルが存在するか確認し、存在しない場合は作成する
  win_powershell: |
    if (!(Test-Path -Path "C:\example\test.txt")) {
      New-Item -ItemType File -Path "C:\example\test.txt"
    }
  register: result

- name: 結果を表示する
  debug:
    var: result.stdout_lines

説明

  • debug モジュールで、result.stdout_lines (標準出力) を表示します。
  • register: result で、実行結果を result 変数に格納します。
  • ファイルが存在しない場合、New-Item コマンドレットでファイルを作成します。
  • Test-Path コマンドレットで "C:\example\test.txt" ファイルの存在を確認します。
  • win_powershell モジュールを使用して、PowerShellスクリプトをインラインで実行します。

例2: レジストリ値の変更

- name: レジストリ値を変更する
  win_powershell: |
    Set-ItemProperty -Path "HKLM:\SOFTWARE\Example" -Name "ValueName" -Value "NewValue" -Force
  register: result

- name: 結果を表示する
  debug:
    var: result.stdout_lines

説明

  • registerdebug モジュールを使用して、結果を表示します。
  • -Force パラメータで、既存の値を上書きします。
  • Set-ItemProperty コマンドレットを使用して、レジストリ値 "HKLM:\SOFTWARE\Example\ValueName" を "NewValue" に変更します。

例3: サービスの起動と停止

- name: サービスを起動する
  win_powershell: |
    Start-Service -Name "Spooler"
  register: start_result

- name: サービスを停止する
  win_powershell: |
    Stop-Service -Name "Spooler"
  register: stop_result

- name: 起動結果を表示する
  debug:
    var: start_result.stdout_lines

- name: 停止結果を表示する
  debug:
    var: stop_result.stdout_lines

説明

  • それぞれの結果を registerdebug モジュールで表示します。
  • Stop-Service コマンドレットで "Spooler" サービスを停止します。
  • Start-Service コマンドレットで "Spooler" サービスを起動します。

例4: スクリプトファイルの実行と引数の受け渡し

- name: スクリプトファイルを実行し、引数を渡す
  win_powershell:
    script: C:\scripts\my_script.ps1
    arguments: -Param1 "value1" -Param2 "value2"
  register: script_result

- name: スクリプト実行結果を表示する
  debug:
    var: script_result.stdout_lines

説明

  • registerdebug モジュールを使用して、スクリプトの実行結果を表示します。
  • arguments パラメータで、-Param1 "value1"-Param2 "value2" の引数をスクリプトに渡します。
  • script パラメータで、"C:\scripts\my_script.ps1" スクリプトファイルを実行します。

例5: モジュールのインストールと使用

- name: PowerShellモジュールをインストールする
  win_powershell: |
    Install-Module -Name "PSWindowsUpdate" -Force
  register: install_result

- name: Windows Updateを実行する
  win_powershell: |
    Import-Module PSWindowsUpdate
    Get-WindowsUpdate -Install -AcceptAll
  register: update_result

- name: モジュールインストール結果を表示する
  debug:
    var: install_result.stdout_lines

- name: Windows Update結果を表示する
  debug:
    var: update_result.stdout_lines
  • それぞれの結果を registerdebug モジュールで表示します。
  • Import-Module コマンドレットでモジュールをインポートし、Get-WindowsUpdate コマンドレットでWindows Updateを実行します。
  • Install-Module コマンドレットで "PSWindowsUpdate" モジュールをインストールします。


代替方法

    • win_command モジュールを使用して、powershell.exe を直接実行し、PowerShellスクリプトやコマンドを実行します。
    • この方法は、簡単なコマンドやスクリプトを実行する場合に便利ですが、複雑なスクリプトや引数の受け渡しには不向きな場合があります。
    • 例:
      - name: PowerShellコマンドを実行する
        win_command: powershell.exe -Command "Get-Process | Where-Object {$_.ProcessName -eq 'notepad'}"
        register: command_result
      
      - name: 結果を表示する
        debug:
          var: command_result.stdout_lines
      
    • 例:スクリプト実行
      - name: PowerShellスクリプトを実行する
        win_command: powershell.exe -File C:\scripts\my_script.ps1
        register: script_result
      
      - name: 結果を表示する
        debug:
          var: script_result.stdout_lines
      
  1. win_shell モジュール

    • win_shell モジュールは、Windowsシェル (cmd.exe) を使用してコマンドを実行します。
    • PowerShellコマンドも実行できますが、powershell.exe を明示的に指定する必要があります。
    • win_command と同様に、複雑なスクリプトや引数の受け渡しには不向きな場合があります。
    • 例:
      - name: PowerShellコマンドを実行する
        win_shell: powershell.exe -Command "Get-Process | Where-Object {$_.ProcessName -eq 'notepad'}"
        register: shell_result
      
      - name: 結果を表示する
        debug:
          var: shell_result.stdout_lines
      
  2. script モジュールと win_copy モジュール

    • script モジュールは、ローカルマシン上のスクリプトをリモートマシンにコピーして実行します。
    • win_copy モジュールを使用して、PowerShellスクリプトをリモートマシンにコピーし、script モジュールで実行します。
    • この方法は、複雑なスクリプトを実行する場合や、スクリプトファイルを管理する場合に便利です。
    • 例:
      - name: PowerShellスクリプトをコピーする
        win_copy:
          src: ./my_script.ps1
          dest: C:\scripts\my_script.ps1
      
      - name: PowerShellスクリプトを実行する
        script: C:\scripts\my_script.ps1
        register: script_result
      
      - name: 結果を表示する
        debug:
          var: script_result.stdout_lines
      
  3. win_template モジュール

    • win_template モジュールは、Jinja2テンプレートを使用してリモートマシン上にファイルを生成します。
    • PowerShellスクリプトをテンプレートとして作成し、変数を埋め込んで生成できます。
    • この方法は、設定ファイルやスクリプトを動的に生成する場合に便利です。
    • 例:
      - name: PowerShellスクリプトをテンプレートから生成する
        win_template:
          src: my_script.ps1.j2
          dest: C:\scripts\my_script.ps1
          vars:
            param1: "value1"
            param2: "value2"
      
      - name: PowerShellスクリプトを実行する
        script: C:\scripts\my_script.ps1
        register: template_result
      
      - name: 結果を表示する
        debug:
          var: template_result.stdout_lines
      
    • my_script.ps1.j2 の例:
      Write-Host "Param1: {{ param1 }}"
      Write-Host "Param2: {{ param2 }}"
      
  4. カスタムモジュールの作成

    • PowerShellスクリプトをラップするカスタムAnsibleモジュールを作成できます。
    • この方法は、特定のタスクを繰り返し実行する場合や、複雑なロジックを実装する場合に便利です。
    • カスタムモジュールは、PowerShellで記述することも、Pythonで記述することもできます。

それぞれの方法の使い分け

  • 特定のタスクの繰り返しや複雑なロジック
    カスタムモジュール
  • 動的なスクリプト生成
    win_template
  • 複雑なスクリプトや引数の受け渡し
    scriptwin_copy、または win_template
  • 簡単なコマンドやスクリプト
    win_command または win_shell