AnsibleでWindowsサーバーを管理するには、Linuxと違って接続方式の準備が先に必要です。この記事では、2026年10月時点のansible-core 2.21系とansible.windows 3.8.0を例に、制御ノードへのpywinrmの導入、Windows側のWinRMリスナー作成、認証方式の選び方、win_pingでの疎通確認、IIS導入と更新プログラム適用のPlaybookまでを、コピーして試せるコードで解説します。Windows Server 2022以降で使えるSSH接続や、WinRMでは失敗するタスクの回避方法も扱います。
まとめ|ドメイン参加はWinRMとKerberos、単体サーバーはHTTPSかSSHで接続
制御ノードにはpywinrm(またはpypsrp)とansible.windowsコレクションを入れ、Windows側ではWinRMのリスナーとファイアウォールを開けます。Active Directoryに参加しているサーバーならKerberos認証、ワークグループの単体サーバーならHTTPSリスナーとNTLMの組み合わせが公式の推奨です。
Windows Server 2022以降だけを相手にするなら、OpenSSHサーバーを有効にしてSSHで接続する方法も公式サポートの対象になりました。どの方式でも、Windows Updateの適用やSQL Serverのインストールのように資格情報の委任が要る処理は失敗しやすいため、該当タスクだけbecomeで実行する前提でPlaybookを組んでください。
Windows管理の仕組みとwinrm・psrp・sshの3つの接続方式の違い
Ansibleがエージェントを入れずに対象へ接続して手順を流す仕組みはAnsibleとは?エージェントレスの仕組みとメリット・デメリットで解説しています。Windowsでは、その「接続」の部分が変わります。
接続プラグイン3種の特徴と対応するWindowsの版を比較表で整理
Windows管理の公式ガイドは、接続プラグインとしてwinrm・psrp・sshの3つを挙げています。管理対象はWindows Server 2016またはWindows 10以降です。
| 接続方式 | 通信 | 必要なもの |
|---|---|---|
| winrm | WinRM(HTTP/HTTPS) | pywinrm |
| psrp | WinRM経由のPS Remoting | pypsrp |
| ssh | OpenSSH(22番) | Server 2022以降 |
表のPS RemotingはPowerShell Remotingを指し、psrpではWinRM上で通信します。psrpはwinrmより新しく、ガイドでは少し速く、負荷が高いときのタイムアウトに強く、プロキシにも対応しやすいと説明されています。どちらもWindows側のWinRMリスナーを使うため、Windows側の準備は共通です。sshはドメイン外の環境で準備しやすく、鍵認証が使え、ファイル転送が速いという特徴があります。
2026年10月時点のWindows管理環境とコレクションの導入要件
ここではansible-core 2.21系とansible.windows 3.8.0の要件を確認します。Galaxyで確認したansible.windowsの最新は3.8.0(2026年8月26日公開)で、ansible-core 2.16.0以上を要求します。PyPIのansible-coreは2.21.5(2026年10月5日)が最新で、制御ノードにはPython 3.12以上が必要です。
Windows側はPowerShell 5.1があれば追加の要件はありません。Windows Server 2016とWindows 10以降には最初から入っています。win_featureなどWindows専用のモジュールはansible-coreには含まれないので、コレクションは別に入れます。Active Directoryを操作するならmicrosoft.ad(1.12.1)、ansible.windowsに無いモジュールはcommunity.windows(3.3.0)が担当です。
制御ノードにpywinrm・pypsrpとansible.windowsを導入する手順
制御ノードはLinuxかmacOSを使います。Windows上で制御ノードを動かしたい場合はWSLのLinux環境に入れてください。
venvにansible-coreとpywinrmを入れてコレクションを追加するコマンド
WinRMの公式ガイドによると、winrm接続にはpywinrm>=0.4.0、psrp接続にはpypsrp<=1.0.0が必要で、どちらもAnsibleのパッケージには同梱されていません。PyPIの最新はpywinrmが0.5.0、pypsrpが0.9.1で、どちらも条件を満たします。
python3 -m venv ~/.venv/win
source ~/.venv/win/bin/activate
pip install ansible-core "pywinrm>=0.4.0" "pypsrp<=1.0.0"
ansible-galaxy collection install ansible.windows community.windows microsoft.ad
ansible-galaxy collection list | grep -E "windows|microsoft"
CredSSP認証を使う場合だけ、pywinrm[credssp]のように追加の依存を付けて入れ直します。macOSの制御ノードでは、winrmとpsrpの接続が最近の版で失敗しやすいとガイドが警告しており、回避には環境変数OBJC_DISABLE_INITIALIZE_FORK_SAFETY=yesとno_proxy=*の設定、Kerberos認証の不使用が必要です。本番の制御ノードはLinuxに置くほうが手間はかかりません。ansible.windowsなどのコレクションをrequirements.ymlに書いて版を固定する方法は、Ansible Galaxyの使い方とrequirements.ymlでの依存管理を解説した記事で扱っています。
Windows側でWinRMリスナーを作りHTTP・HTTPSのポートを開ける手順
WinRMはWindows Server 2012以降で既定で有効ですが、Ansibleから接続するにはリスナーとファイアウォールの設定が必要になる場合があります。以下は管理者権限のPowerShellで実行します。
Enable-PSRemotingでHTTPリスナーを有効にしローカル管理者で接続する
公式ガイドの最小構成は、Enable-PSRemotingでWinRMサービスとHTTPリスナーを有効にし、5985番を開ける手順です。ローカルアカウントで接続する場合は、LocalAccountTokenFilterPolicyも設定します。
# WinRMサービスとHTTPリスナー(5985番)を有効化
Enable-PSRemoting -Force
# 5985番の受信を許可
$firewallParams = @{
Action = 'Allow'
Direction = 'Inbound'
DisplayName = 'Windows Remote Management (HTTP-In)'
LocalPort = 5985
Profile = 'Any'
Protocol = 'TCP'
}
New-NetFirewallRule @firewallParams
# ローカルアカウントでの接続を許可(ドメインアカウントだけなら不要)
New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' `
-Name 'LocalAccountTokenFilterPolicy' -Value 1 -PropertyType DWORD -Force
# リスナーの確認
winrm enumerate winrm/config/Listener
ガイド自身が、この手順は説明用であり、全プロファイルでのポート開放やローカルアカウントの許可は環境によって適さないと注意しています。本番ではProfileをDomainに絞り、送信元を制御ノードのアドレスに限定するルールに書き換えてください。既定ではローカルのAdministratorsグループのアカウントしかWinRMで接続できない点も覚えておきます。
自己署名証明書でHTTPSリスナー(5986番)を追加し証明書検証を設定
ワークグループのサーバーにNTLMやBasicで接続するなら、HTTPSリスナーを作ります。証明書はLocalMachine\Myに入っている必要があり、リスナーには拇印(サムプリント)を指定します。
# 検証用の自己署名証明書(有効期限1年)
$cert = New-SelfSignedCertificate -CertStoreLocation 'Cert:\LocalMachine\My' `
-DnsName $env:COMPUTERNAME -Subject "CN=$env:COMPUTERNAME" `
-NotAfter (Get-Date).AddYears(1) -Provider 'Microsoft Software Key Storage Provider'
# HTTPSリスナー(5986番)を作成
New-Item -Path 'WSMan:\localhost\Listener' -Address '*' -Transport 'HTTPS' -Port 5986 `
-CertificateThumbprint $cert.Thumbprint -Enabled $true -Force
New-NetFirewallRule -DisplayName 'Windows Remote Management (HTTPS-In)' `
-Direction Inbound -Action Allow -Protocol TCP -LocalPort 5986 -Profile Any
自己署名証明書は制御ノードから信頼されないため、そのままでは接続に失敗します。検証環境ではansible_winrm_server_cert_validation: ignoreで検証を外せますが、本番ではAD CSなどで署名した証明書をリスナーに使い、発行元のCA証明書をPEM形式で制御ノードに置いてansible_winrm_ca_trust_pathで指定します。AllowUnencryptedを有効にして暗号化の要件を外す設定は、ガイドが開発とデバッグ専用としているので本番には持ち込みません。
認証方式の比較:Basic・NTLM・Kerberos・CredSSPの使い分け
WinRMで選べる認証方式は5つです。公式ガイドの表を、実務で選ぶときの観点に絞って並べました。
| 方式 | ローカル | AD | 委任 | HTTP暗号化 |
|---|---|---|---|---|
| Basic | 可 | 不可 | 不可 | なし |
| Certificate | 可 | 不可 | 不可 | なし |
| NTLM | 可 | 可 | 不可 | あり |
| Kerberos | 不可 | 可 | 可 | あり |
| CredSSP | 可 | 可 | 可 | あり |
ガイドの推奨は、ドメイン環境ならHTTP上のKerberos、ローカルアカウントならHTTPS上のBasicかNTLMです。BasicとNTLMはHTTPのリスナーで使わないよう明記されています。CredSSPは無制約の委任を伴うため、本当に必要な場合に限るとされています。迷ったら、ドメイン参加のサーバーはKerberos、それ以外はHTTPSとNTLMの2択で決めてください。
インベントリとgroup_varsを書きwin_pingで疎通を確かめる手順
Windows側の準備ができたら、制御ノードで接続変数を書きます。Playbookの基本構文はAnsible Playbookの書き方と実行手順にまとめています。
group_varsにWinRMの接続変数をまとめパスワードはVaultで隠す
接続方式や認証方式はホストごとではなくグループの変数にまとめると、Linuxのホストと同じインベントリに混在させても管理が崩れません。HTTPSとNTLMで接続する例です。
# inventory.ini
[windows]
web01 ansible_host=192.0.2.21
web02 ansible_host=192.0.2.22
# group_vars/windows.yml
ansible_connection: winrm
ansible_port: 5986
ansible_winrm_scheme: https
ansible_winrm_transport: ntlm
ansible_winrm_ca_trust_path: /etc/ansible/certs/corp-ca.pem
ansible_user: ansible-admin
ansible_password: "{{ vault_win_password }}"
vault_win_passwordはAnsible Vaultで暗号化した別ファイルに置きます。psrpに切り替えるときは、ansible_connection: psrpにして認証方式をansible_psrp_auth: negotiateとします。negotiateはKerberosを試し、使えなければNTLMに落とす指定で、winrm接続には無い選択肢です。Kerberosの場合、ansible_userはUPN形式(ユーザー名、@、大文字のレルム名をつなげた形)で書きます。
win_pingとsetupで疎通を確認しwinrsとncで失敗原因を切り分ける
Windowsではpingモジュールの代わりにansible.windows.win_pingを使います。疎通できたらsetupでOSの情報を取ります。
ansible windows -i inventory.ini -m ansible.windows.win_ping --ask-vault-pass
ansible web01 -i inventory.ini -m ansible.builtin.setup -a "filter=ansible_os_name" --ask-vault-pass
# 失敗したら制御ノードからポートと証明書を確認
nc -zv 192.0.2.21 5986
echo '' | openssl s_client -connect 192.0.2.21:5986
公式ガイドのトラブルシューティングは、まず別のWindowsからwinrs -r:https://server:5986/wsman -u:Username -p:Password -ssl ipconfigを実行し、Windows側の設定の問題かを切り分ける手順を勧めています。winrsで成功してAnsibleだけ失敗するなら制御ノード側の変数か証明書、winrsでも失敗するならリスナーかファイアウォールが原因です。
IIS導入・サービス起動・Windows更新適用をまとめたPlaybook例
使用するモジュールはwin_feature・win_service・win_updatesで、それぞれIIS導入・サービス起動・更新適用を担当します。
IISの導入、サービスの自動起動、セキュリティ更新の適用を1本のPlaybookにまとめた例です。モジュールの引数はwin_featureの文書とwin_updatesの文書に沿っています。
---
- name: WebサーバーにIISを入れて更新を適用する
hosts: windows
gather_facts: false
tasks:
- name: IISを管理ツール付きで追加
ansible.windows.win_feature:
name: Web-Server
include_management_tools: true
state: present
register: iis
- name: 機能の追加で再起動が必要なら再起動
ansible.windows.win_reboot:
when: iis.reboot_required
- name: W3SVCを自動起動にして起動
ansible.windows.win_service:
name: W3SVC
start_mode: auto
state: started
- name: 重要とセキュリティの更新を適用
ansible.windows.win_updates:
category_names:
- SecurityUpdates
- CriticalUpdates
reboot: true
reboot_timeout: 1800
register: wu
- name: 適用した更新の件数を表示
ansible.builtin.debug:
var: wu.installed_update_count
win_featureはWindows Server専用で、クライアントOSでは使えません。win_updatesはrebootの既定がfalseなので、再起動を伴う更新を最後まで当てたいときは明示します。reboot_timeoutの既定は1200秒で、更新の件数が多いサーバーでは足りないことがあります。文書には数時間かかる場合があるとも書かれているので、業務時間帯の実行は避けてください。
Windows Server 2022以降でSSH接続を使う設定とWinRMとの使い分け
Windows SSHの公式ガイドによると、SSHでの接続はAnsible 2.8から動いていましたが、公式サポートは2.18からです。対象はWindowsに同梱されたOpenSSHの7.9.0.0以上に限られ、Windows Server 2019の同梱版は7.7.2.1なので、実質的にはServer 2022以降が対象になります。
OpenSSHサーバーの追加とDefaultShellをPowerShellに変える設定
Windows側では、OpenSSHサーバーを機能として追加し、既定のシェルをcmd.exeからpowershell.exeに変えます。ガイドは、PowerShellのほうがテストが充実していて速いとしています。
Get-WindowsCapability -Name OpenSSH.Server* -Online | Add-WindowsCapability -Online
Set-Service -Name sshd -StartupType Automatic -Status Running
New-NetFirewallRule -Name 'sshd-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd) TCP 22' `
-Direction Inbound -Action Allow -Enabled True -Profile Any -Protocol TCP -LocalPort 22
New-ItemProperty -Path 'HKLM:\SOFTWARE\OpenSSH' -Name 'DefaultShell' `
-Value 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' -PropertyType String -Force
シェルの変更は次のSSH接続から反映され、sshdの再起動は要りません。Ansibleからシェルを変える場合は、win_regeditの直後にansible.builtin.meta: reset_connectionを置かないと、後続のタスクが古いシェルのまま動きます。OpenSSH自体の版の確認方法はOpenSSHとは?最新バージョンの確認方法とアップデート手順で扱っています。
ansible_shell_typeの指定と鍵認証で起きるダブルホップの問題
制御ノード側で必要な変数は2つだけです。
# group_vars/win_ssh.yml
ansible_connection: ssh
ansible_shell_type: powershell
ansible_user: ansible-admin
ansible_shell_typeはWindows側のDefaultShellと一致させます。公開鍵は、一般ユーザーならプロファイルの.ssh\authorized_keysですが、管理者ユーザーはC:\ProgramData\ssh\administrators_authorized_keysに置く点がLinuxとの違いです。鍵認証ではリモートのセッションが資格情報を持たないため、ファイルサーバーなどネットワーク上の資源にアクセスするタスクは失敗します。ドメイン参加のサーバーに鍵認証で入るなら、共有フォルダーを触るタスクだけbecomeで資格情報を渡す設計にしてください。
WinRMの制限で失敗するタスクとbecome・PowerShell 7の注意点
接続まで通っても、特定の処理だけが原因の分かりにくいエラーで止まることがあります。多くはWinRMというプロトコルの制限によるものです。
Windows UpdateやSQL Serverの導入失敗要因とbecomeでの回避
公式ガイドの制限事項には、多くの認証方式で資格情報が委任されないこと、Windows Update APIの呼び出しの多くがWinRM越しでは拒否されること、セッションが非対話であること、DPAPIを使う処理(SQL Serverのインストーラーなど)が動かないことが挙げられています。win_updatesが既定でタスクスケジューラ経由で動くのは、この制限を避けるためです。
- name: インストーラーをSYSTEM権限で実行
ansible.windows.win_package:
path: C:\Temp\setup.exe
arguments: /quiet /norestart
state: present
become: true
become_method: runas
become_user: SYSTEM
ガイドによると、becomeはローカルで実行したのと同じ状態にするため、非対話の制約とWindows Update API・DPAPIの制約をまとめて外せます。スケジュールタスクでも回避できますが、実行できるのはコマンドだけでモジュールは動きません。失敗したタスクにだけbecomeを付ける運用が手堅い選択です。
ansible-core 2.21対応のPowerShell 7(pwsh)の指定方法
PowerShell 7対応の公式ページによると、ansible-core 2.21からモジュールをPowerShell 7で動かせるようになりました。指定しなければ、従来どおりWindows PowerShell 5.1で動きます。
# group_vars/windows.yml に追記
ansible_pwsh_interpreter: pwsh
# psrp接続ならタスクごとのプロセス起動を避けるために指定
ansible_psrp_configuration_name: PowerShell.7
PowerShell.7のセッション構成は、PowerShell 7のインストール時のオプションか、PowerShell 7からEnable-PSRemotingを実行したときに登録されます。PowerShell 7をサーバーに入れる手順はPowerShellのインストール手順を参照してください。既存のPlaybookは5.1で動いているはずなので、急いで切り替える必要はありません。PowerShell 7でしか動かない自作モジュールを書くときに使う設定です。
AnsibleでWindowsサーバーを管理する条件と見送る場面の判断基準
判断の軸は、台数と、Linuxと同じ仕組みで管理する価値があるかの2つです。
Ansibleで進める条件:Linuxと混在し同じ変更を複数台へ流す運用
LinuxサーバーとWindowsサーバーが混在していて、パッチ適用・IISの設定・サービスの監視設定を同じ手順で回したい場合は、Ansibleに寄せる価値があります。インベントリとPlaybookをGitで管理し、変更をレビューしてから流す体制を作れるなら、Windowsだけ手作業という状態を解消できる仕組みです。どの運用作業から手を付けるかはAnsibleによる運用自動化の進め方で整理しています。
実行を画面から行いたい、誰がいつ流したかを監査に残したい場合は、Ansible Towerの機能と設定手順やAWXをKubernetesへ導入する手順を検討します。
見送る場面:グループポリシーやWSUSで既に一元管理できている環境
全台がドメインに参加していて、設定はグループポリシー、更新はWSUSで既に回っているなら、Ansibleを足すと管理が二重になります。この場合は、グループポリシーで扱えないアプリケーションの配置やIISのサイト設定だけをAnsibleに任せる線引きにしてください。Windowsサーバーが2〜3台で変更が年に数回なら、WinRMの証明書更新やPlaybookの保守のほうが重くなるので、手順書での運用を続けるほうが現実的です。
LinuxとWindowsが混在するサーバー群の構成管理を、CI/CDのパイプラインに組み込んでレビューから実行まで回す仕組みを整えたい場合は、DevOps・CI/CD導入支援でご相談を承っています。
よくある質問
AnsibleとWindowsの組み合わせについて、検索されることの多い質問に答えます。
AnsibleをWindowsのパソコンに入れて制御ノードにできますか?
Windowsそのものは制御ノードとして動かせません。Windowsのパソコンから使いたい場合は、WSLでUbuntuなどのLinux環境を用意し、その中にansible-coreとpywinrmを入れます。WSLの中から同じネットワークのWindowsサーバーへWinRMで接続する形です。管理対象としてのWindowsと、Ansibleを動かす制御ノードとしてのWindowsは扱いが別だと考えてください。
Windows 11やWindows 10のクライアントPCも管理できますか?
管理対象にはできます。公式ガイドの対象はWindows Server 2016またはWindows 10以降で、テストはServer版で行われていますが、デスクトップ版でも互換性があるとされています。ただしwin_featureのようにServerのコマンドレットに依存するモジュールはクライアントOSで動きません。PCを多数管理する用途では、Intuneなど端末管理の仕組みと役割を分けて使います。
LinuxのcopyやshellモジュールはWindowsでも使えますか?
多くは使えません。Ansibleのコアモジュールの大半はPythonで書かれているため、Windowsでは動きません。ファイルのコピーはwin_copy、コマンドの実行はwin_shellやwin_commandのように、ansible.windowsの対応するモジュールに置き換えます。debug・fetch・setup・slurpなど一部のモジュールはWindowsにもそのまま使えます。
Active DirectoryのユーザーやグループもAnsibleで管理できますか?
管理できます。microsoft.adコレクション(2026年10月時点で1.12.1)に、ユーザー・グループ・OU・ドメイン参加を扱うモジュールがまとまっています。ドメインコントローラーへの接続にはKerberos認証を使うのが前提です。ユーザーの一括作成は失敗したときの影響が大きいので、最初は検証用のOUに対して流し、結果を確認してから対象を広げてください。
winrmとpsrpはどちらの接続方式を選ぶべきですか?
新しく始めるならpsrpが無難です。公式ガイドは、psrpのほうが少し速く、負荷が高いときのタイムアウトに強く、プロキシにも対応しやすいとしています。認証方式でnegotiateを選べるので、Kerberosが使えない環境でもNTLMへの自動切り替えが可能です。Windows側の準備はどちらも同じWinRMリスナーなので、変数を書き換えるだけで後から切り替えられます。
関連記事
- Ansibleとは?エージェントレスの仕組みとメリット・デメリット、Red Hat AAPの制約:Ansible本体の仕組み。
- Ansible Playbookの書き方と実行手順:–checkでのdry-runとhandlers【2.21系】:本記事のPlaybookを読むための文法。
- Ansibleネットワーク自動化の始め方:network_cliで設定変更とバックアップを自動化する手順【2.21系】:Linux・Windows以外のネットワーク機器を扱う方法。
- Ansible Towerとは:automation controllerへの改称とSurvey・Webhook・RBACの設定手順【AAP 2.7】:Windowsの更新適用を承認付きで実行する基盤。
- Ansibleによる運用自動化の進め方:対象作業の選び方と費用対効果・失敗パターン:どの作業から自動化するかの判断。