解析ansible远程管理客户端【win终端为例】
阅读原文时间:2022年03月19日阅读:1

一、前提:

具体操作命令如下

set-executionpolicy remotesigned
winrm quickconfig
#配置auth
winrm set winrm/config/service/auth '@{Basic="true"}'
#为winrm service 配置加密方式为允许非加密
winrm set winrm/config/service '@{AllowUnencrypted="true"}'

在windows powershell中运行

  1. 管理终端必须为linux,且需要安装 Python的winrm模块

  2. 底层通讯基于 powershell,版本需要在4.0以上  $PSVersionTable.PSVersion获取版本号  或者  get-host | findstr version

  3. 远程windows机器开启winrm

二、ansible管理机部署安装

安装配置ansible:

安装ansible:

yum -y install ansible

如果没有安装pip, 请先安装对应于你的Python版本的pip:

easy_install pip

以下的Python模块也需要安装:

pip install PyYAML

配置hosts文件:

cat /etc/ansible/hosts
[windows]
10.0.0.1 ansible_ssh_user="Administrator" ansible_ssh_pass="123456" ansible_ssh_port=5985 ansible_connection="winrm" ansible_winrm_server_cert_validation=ignore

10.0.0.1 是windows服务器的IP。
/etc/ansible/hosts 中看可添加多个windows服务器的信息 ,可集体一次性管理,分发任务。
至此,ansible服务端配置完毕。

设置windows远程管理【WS-Management,winrm】

winrm service 默认都是未启用的状态,先查看状态;如无返回信息,则是没有启动;
winrm enumerate winrm/config/listener

针对winrm service 进行配置

针对winrm service 进行配置

winrm winrm quickconfig

输入 y 回车

为 winrm 配置 auth

为winrm service 配置auth:

winrm set winrm/config/service/auth @{Basic="true"}

为winrm service 配置加密方式为允许非加密

winrm set winrm/config/service '@{AllowUnencrypted="true"}'

关闭防火墙,并查看5985端口是否开启,并在监听中

netstat -ano | findstr 5985

windows下可用调试模块 win_ping

ansible -i hosts all -m win_ping
显示连接成功
SUCCESS => {
"changed": false,
"ping": "pong"

windows下可用传送文件模块  win_copy

ansible -i hosts all -m win_copy -a 'src=/etc/passwd dest=D:\passwd'

windows下 文件管理模块 win_file

删除D:\passwd
ansible -i hosts all -m win_file -a "path=D:\passwd state=absent"

获取ip地址
ansible -i hosts all -m raw -a "ipconfig"

获取window主机信息:
ansible -i hosts all -m setup

创建文件夹:
ansible -i hosts all -m raw -a 'md D:\dir'

移动文件:
ansible -i hosts all -m raw -a "cmd /c 'move /y D:\Software\wmi_export.exe D:\wmi_export.exe'"

三、具体windows机器管理模块

参考 https://docs.ansible.com/ansible/2.9/modules/list_of_windows_modules.html

ansible中 windows 和 linux 机器模块大同小异,windows除了模块名字前面多个 “win_”,除去这个后完全可以用于linux。

一般用来测试windows机器是否可以用ansible管理,结果是 pong 则证明可以正常连接

# Test connectivity to a windows host

ansible winserver -m win_ping

  • name: Example from an Ansible Playbook
    win_ping:

  • name: Induce an exception to see what happens # 异常查看
    win_ping:
    data: crash

一般执行单个命令,不支持管道符,例如查看一个ip     ansible winserver -m win_command -a "ipconfig"

- name: Save the result of 'whoami' in 'whoami_out'
win_command: whoami
register: whoami_out

  • name: Run command that only runs if folder exists and runs from a specific folder
    win_command: wbadmin -backupTarget:C:\backup\
    args:
    chdir: C:\somedir\
    creates: C:\backup\

  • name: Run an executable and send data to the stdin for the executable
    win_command: powershell.exe
    args:
    stdin: Write-Host test

与 win_command 不同的是,支持管道符,用powershell和cmd可以执行的命令,均可以批量执行

eg: ansible winserver -m win_shell -a "ipconfig | findstr IPv4"

# Execute a command in the remote shell; stdout goes to the specified

file on the remote.

  • win_shell: C:\somescript.ps1 >> C:\somelog.txt

Change the working directory to somedir/ before executing the command.

  • win_shell: C:\somescript.ps1 >> C:\somelog.txt chdir=C:\somedir

You can also use the 'args' form to provide the options. This command

will change the working directory to somedir/ and will only run when

somedir/somelog.txt doesn't exist.

  • win_shell: C:\somescript.ps1 >> C:\somelog.txt
    args:
    chdir: C:\somedir
    creates: C:\somelog.txt

Run a command under a non-Powershell interpreter (cmd in this case)

  • win_shell: echo %HOMEDIR%
    args:
    executable: cmd
    register: homedir_out

查看环境变量这一步由于linux/profile的影响,不识别 “ % ”,故使用如下语法方可获取:

ansible winserver -m raw -a 'echo $ENV:PATH'

  • name: Run multi-lined shell commands
    win_shell: |
    $value = Test-Path -Path C:\temp
    if ($value) {
    Remove-Item -Path C:\temp -Force
    }
    New-Item -Path C:\temp -ItemType Directory

  • name: Retrieve the input based on stdin
    win_shell: '$string = [Console]::In.ReadToEnd(); Write-Output $string.Trim()'
    args:
    stdin: Input message

创建文件或者文件夹,与linux不同的是 touch 创建文件 , directory创建文件夹

- name: Touch a file (creates if not present, updates modification time if present)
win_file:
path: C:\Temp\foo.conf
state: touch

  • name: Remove a file, if present
    win_file:
    path: C:\Temp\foo.conf
    state: absent

  • name: Create directory structure
    win_file:
    path: C:\Temp\folder\subfolder
    state: directory

  • name: Remove directory structure
    win_file:
    path: C:\Temp
    state: absent

# 将linux端的文件拷贝到win机器上,并修改文件名

  • name: Copy a single file
    win_copy:
    src: /srv/myfiles/foo.conf
    dest: C:\Temp\renamed-foo.conf

拷贝文件到指定位置并修改名称和备份

  • name: Copy a single file, but keep a backup
    win_copy:
    src: /srv/myfiles/foo.conf
    dest: C:\Temp\renamed-foo.conf
    backup: yes

force=yes 文件重名是使用,参数表示为强制覆盖文件

设置远程主机文件的内容

  • name: Set the contents of a file
    win_copy:
    content: abc123
    dest: C:\Temp\foo.txt

将单个文件复制给另一个用户

  • name: Copy a single file as another user
    win_copy:
    src: NuGet.config
    dest: '%AppData%\NuGet\NuGet.config'
    vars:
    ansible_become_user: user
    ansible_become_password: pass
    # The tmp dir must be set when using win_copy as another user
    # This ensures the become user will have permissions for the operation
    # Make sure to specify a folder both the ansible_user and the become_user have access to (i.e not %TEMP% which is user specific and requires Admin)
    ansible_remote_tmp: 'c:\tmp'

product_id 产品id   arguments:安装用到的命令 例:/s 静默安装   state="present" :安装   state="absent" 卸载

# 安装 VC

安装远程桌面 msi文件到远程主机

卸载时只需要产品ID

  • name: Uninstall Remote Desktop Connection Manager
    win_package:
    product_id: '{0240359E-6A4C-4884-9E94-B397A02D893C}'
    state: absent

从本地MSI卸载远程桌面连接管理器,省略product_id

  • name: Uninstall Remote Desktop Connection Manager from local MSI omitting the product_id
    win_package:
    path: C:\temp\rdcman.msi
    state: absent

7-Zip exe doesn't use a guid for the Product ID

  • name: Install 7zip from a network share specifying the credentials
    win_package:
    path: \\domain\programs\7z.exe
    product_id: 7-Zip
    arguments: /S
    state: present
    user_name: DOMAIN\User
    user_password: Password

安装Python,参数说明https://docs.python.org/3/using/windows.html

InstallAllUsers:执行系统范围的安装 PrependPath:添加到环境变量 Include_pip:安装pip

  • name: 安装Python3.9
    win_package:
    path: "python-3.9.2-amd64.exe"
    state: present
    product_id: python-3.9.2
    arguments: /quiet InstallAllUsers=1 PrependPath=1 Include_test=0 Include_pip=1

- name: Enable firewall for Domain, Public and Private profiles
win_firewall:
state: enabled
profiles:
- Domain
- Private
- Public
tags: enable_firewall

  • name: Disable Domain firewall win_firewall: state: disabled profiles:
    • Domain
      tags: disable_firewall

- name: Change the hostname to sample-hostname
win_hostname:
name: sample-hostname
register: res

修改主机名后需要重启windows才能生效

  • name: Reboot
    win_reboot:
    when: res.reboot_required

name 必填项 字符串
path (必填项) 通往ExecAction的可执行文件的路径
description 任务的描述
triggers 触发条件

restart_count 任务调度器尝试重新启动任务的次数

如果已设置,则还必须设置 `restart_count`,最长允许时间为31天,最短允许时间为1分钟。

这是在ISO 8601持续时间格式 `P[n]Y[n]M[n]DT[n]H[n]M[n]S`

run_only_if_idle 是否只有在计算机处于空闲状态时才会运行任务

- name: Create a task that will be repeated every minute forever
win_scheduled_task:
name: keepalive
description: keep alive the windows.exe
actions:
- path: C:\crontab\crontab.ps1
triggers:
- type: registration
repetition:
interval: PT2M # 每两分钟执行一次
duration: PT5M # 持续五分钟
stop_at_duration_end: no # 任务的运行实例是否在重复模式结束时停止
username: "administrator" # 给指定用户创建定时任务

win_reg_stat 获取机器的key

- name: Obtain information about a registry key using short form
ansible.windows.win_reg_stat:
path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion
register: current_version

  • name: Obtain information about a registry key property
    ansible.windows.win_reg_stat:
    path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion
    name: CommonFilesDir
    register: common_files_dir

  • name: Obtain the registry key's (Default) property
    ansible.windows.win_reg_stat:
    path: HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion
    name: ''
    register: current_version_default

# LimitBlankPasswordUse

#   0 = enable empty passwords on network

#   1 = disable empty passwords on network

- name: Modify the registry so that the specified user can log in with an empty password
  win_regedit:
    path: HKLM:\SYSTEM\CurrentControlSet\Control\Lsa
    name: LimitBlankPasswordUse
    data: 0
    type: dword

- name: 创建指定用户
win_user:
name: zhoujt
password: B0bP4ssw0rd # 设置密码,不加此项的话默认为没有密码
password_never_expires: yes # 密码用不过期
state: present # 创建用户
groups: # 用户归属组
- Users # 默认组
- Administrators # 添加为管理员

# 创建Jinja2模板,并传输到服务器

  • name: Create a file from a Jinja2 template
    win_template:
    src: /mytemplates/file.conf.j2 # src去template找对应jinja2文件
    dest: C:\Temp\file.conf # 推送到服务器后,变更文件名和后缀,方可达到传送配置文件的效果

注意:完成之后需要重启,环境变量的配置才可以生效。或者进入环境变量点击确定

- name: Set an environment variable for all users
win_environment:
state: present
name: TestVariable
value: Test value
level: machine

  • name: Remove an environment variable for the current user
    win_environment:
    state: absent
    name: TestVariable
    level: user

添加环境变量到系统用户 Path路径下

  • raw: echo $ENV:PATH
    register: path_out

  • name: 为所有用户设置需要添加应用的环境变量
    win_environment:
    state: present
    name: Path

    value:将path的全部拿下来,替换后再添加需要添加的程序路径

    value: "{{ path_out.stdout | regex_replace('[\r\n]*', '')}} + ;C:\\windows\\win64"
    level: machine # 系统级别

  • name: Set several variables at once
    win_environment:
    level: machine
    variables:
    TestVariable: Test value
    CUSTOM_APP_VAR: 'Very important value'
    ANOTHER_VAR: '{{ my_ansible_var }}'

  • name: Set and remove multiple variables at once
    win_environment:
    level: user
    variables:
    TestVariable: Test value
    CUSTOM_APP_VAR: 'Very important value'
    ANOTHER_VAR: '{{ my_ansible_var }}'
    UNWANTED_VAR: '' # < this will be removed

- name: Install the foo service
community.windows.win_nssm:
name: foo
application: C:\windows\foo.exe

This will yield the following command: C:\windows\foo.exe bar "true"

  • name: Install the Consul service with a list of parameters community.windows.win_nssm: name: Consul application: C:\consul\consul.exe arguments:
    • agent
    • -config-dir=C:\consul\config

This is strictly equivalent to the previous example

  • name: Install the Consul service with an arbitrary string of parameters
    community.windows.win_nssm:
    name: Consul
    application: C:\consul\consul.exe
    arguments: agent -config-dir=C:\consul\config

Install the foo service, and then configure and start it with win_service

  • name: Install the foo service, redirecting stdout and stderr to the same file
    community.windows.win_nssm:
    name: foo
    application: C:\windows\foo.exe
    stdout_file: C:\windows\foo.log
    stderr_file: C:\windows\foo.log

  • name: Configure and start the foo service using win_service
    ansible.windows.win_service:
    name: foo
    dependencies: [ adf, tcpip ]
    username: foouser
    password: secret
    start_mode: manual
    state: started

  • name: Install a script based service and define custom environment variables
    community.windows.win_nssm:
    name:
    application: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
    arguments: