Note
This module is part of the ansible.windows collection (version 2.8.0).
You might already have this collection installed if you are using the ansible
package.
It is not included in ansible-core
.
To check whether it is installed, run ansible-galaxy collection list
.
To install it, use: ansible-galaxy collection install ansible.windows
.
To use it in a playbook, specify: ansible.windows.win_copy
.
Synopsis
-
The
win_copy
module copies a file on the local box to remote windows locations. -
For non-Windows targets, use the ansible.builtin.copy module instead.
Parameters
Parameter |
Comments |
---|---|
backup boolean |
Determine whether a backup should be created. When set to No backup is taken when Choices:
|
content string |
When used instead of This is for simple values, for anything complex or with formatting please switch to the ansible.windows.win_template module. |
decrypt boolean |
This option controls the autodecryption of source files using vault. Choices:
|
dest path / required |
Remote absolute path where the file should be copied to. If Use \ for path separators or \\ when in “double quotes”. If If If |
force boolean |
If set to If set to If set to Choices:
|
local_follow boolean |
This flag indicates that filesystem links in the source tree, if they exist, should be followed. Choices:
|
remote_src boolean |
If If Choices:
|
src path |
Local path to a file to copy to the remote server; can be absolute or relative. If path is a directory, it is copied (including the source folder name) recursively to If path is a directory and ends with “/”, only the inside contents of that directory are copied to the destination. Otherwise, if it does not end with “/”, the directory itself with all contents is copied. If path is a file and dest ends with “\”, the file is copied to the folder with the same filename. Required unless using |
Notes
Note
-
Currently win_copy does not support copying symbolic links from both local to remote and remote to remote.
-
It is recommended that backslashes
\
are used instead of/
when dealing with remote paths. -
Because win_copy runs over WinRM, it is not a very efficient transfer mechanism. If sending large files consider hosting them on a web service and using ansible.windows.win_get_url instead.
-
When using become with a user that is not an Administrator, the remote temp directory must be set to one that is accessible to both the become and connection user with
ansible_remote_tmp
. See the examples for more information.
See Also
Examples
- name: Copy a single file ansible.windows.win_copy: src: /srv/myfiles/foo.conf dest: C:\Temp\renamed-foo.conf - name: Copy a single file, but keep a backup ansible.windows.win_copy: src: /srv/myfiles/foo.conf dest: C:\Temp\renamed-foo.conf backup: true - name: Copy a single file keeping the filename ansible.windows.win_copy: src: /src/myfiles/foo.conf dest: C:\Temp\ - name: Copy folder to C:\Temp (results in C:\Temp\temp_files) ansible.windows.win_copy: src: files/temp_files dest: C:\Temp - name: Copy folder contents recursively ansible.windows.win_copy: src: files/temp_files/ dest: C:\Temp - name: Copy a single file where the source is on the remote host ansible.windows.win_copy: src: C:\Temp\foo.txt dest: C:\ansible\foo.txt remote_src: true - name: Copy a folder recursively where the source is on the remote host ansible.windows.win_copy: src: C:\Temp dest: C:\ansible remote_src: true - name: Set the contents of a file ansible.windows.win_copy: content: abc123 dest: C:\Temp\foo.txt - name: Copy a single file as another user ansible.windows.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'
Return Values
Common return values are documented here, the following are the fields unique to this module:
Key |
Description |
---|---|
backup_file string |
Name of the backup file that was created. Returned: if backup=yes Sample: |
checksum string |
SHA1 checksum of the file after running copy. Returned: success, src is a file Sample: |
dest string |
Destination file/path. Returned: changed Sample: |
operation string |
Whether a single file copy took place or a folder copy. Returned: success Sample: |
original_basename string |
Basename of the copied file. Returned: changed, src is a file Sample: |
size integer |
Size of the target, after execution. Returned: changed, src is a file Sample: |
src string |
Source file used for the copy on the target machine. Returned: changed Sample: |
Collection links
- Issue Tracker
- Repository (Sources)
2025-04-26
What it does
- Remote destinations
You can specify the exact location on the target Windows machine where you want the file to be copied. - Copies files
This module is specifically designed to transfer files from your Ansible control machine to remote Windows targets.
Key Features
- Retries and Delays
- You can configure retries and delays for the copy operation in case of temporary network issues.
- Conditions
- You can define conditions to control when the copy operation should occur. For example, only copy the file if it doesn’t already exist on the target.
- File Attributes
- You can control file permissions (read, write, execute) on the target machine.
- You can set file ownership and group ownership.
- You can modify file timestamps (creation, modification, access).
- File Sources
- Local Files
You can directly copy files from your local filesystem. - Remote Files
You can copy files from another remote machine. - URLs
You can fetch files from web servers or other URL sources.
- Local Files
- hosts: windows_servers
tasks:
- name: Copy a file from local to remote
win_copy:
src: my_script.ps1
dest: "C:\Program Files\MyScripts"
mode: '0755'
- name: Copy a file from a URL
win_copy:
src: "http://example.com/install.exe"
dest: "C:\Temp"
- name: Copy a file from another remote host
win_copy:
src: "{{ remote_host }}:/path/to/file.txt"
dest: "C:\Data"
- mode
This option sets the file permissions (in octal notation). - dest
This option specifies the destination path on the target Windows machine. - src
This option defines the source of the file to be copied. - win_copy
This specifies that the task will use thewin_copy
module. - tasks
This section contains a list of tasks to be executed on the target hosts. - hosts: windows_servers
This line defines the target group of Windows machines.
Common Errors and Troubleshooting for Ansible’s win_copy Module
File Path Issues
-
Incorrect Destination Path
- Error
«Failed to create directory» or «Access denied» - Troubleshooting
- Permissions
Ensure the target directory exists and the Ansible user has write permissions to the destination path. - Drive Letters
If using drive letters (e.g., «C:»), ensure they are correctly specified and accessible to the remote host. - Special Characters
Avoid using special characters in the destination path.
- Permissions
- Error
-
- Error
«src file does not exist» - Troubleshooting
- Double-check
Verify the absolute or relative path to the source file on your control machine or remote host (if applicable). - Permissions
Ensure the Ansible user or process has read access to the source file. - Variables
If using variables for the source path, confirm they are correctly defined and resolved.
- Double-check
- Error
Permission and Access Issues
- Insufficient Privileges
- Error
«Access is denied» - Troubleshooting
- Run as Administrator
Run the Ansible playbook with elevated privileges (e.g., usingsudo
or equivalent). - User Context
Ensure the Ansible user account on the target machine has the necessary permissions to copy files to the specified location. - UAC (User Account Control)
If UAC is enabled on the target machines, you might need to adjust UAC settings or use a different approach to elevate privileges.
- Run as Administrator
- Error
Network Connectivity Issues
- Connection Refused
- Error
«Connection refused» or «Cannot connect to host» - Troubleshooting
- Firewall Rules
Verify that firewalls (Windows Firewall, host-based firewalls) on both the control machine and target machines are not blocking the necessary ports for communication (typically WinRM ports). - Network Connectivity
Check network connectivity between the control machine and the target Windows hosts using tools likeping
ortelnet
. - WinRM Configuration
Ensure WinRM is properly configured and enabled on the target Windows machines.
- Firewall Rules
- Error
Module-Specific Issues
-
Checksum Mismatch
- Error
«Checksum mismatch» - Troubleshooting
- File Integrity
Verify that the source file has not been modified or corrupted. - Network Glitches
In rare cases, network issues might cause data corruption during transfer.
- File Integrity
- Error
-
Incorrect Mode
- Error
«Invalid mode specified» - Troubleshooting
- Valid Modes
Ensure themode
parameter is specified correctly (e.g., octal notation like ‘0755’).
- Valid Modes
- Error
General Troubleshooting Tips
- Consult the Documentation
Refer to the official Ansible documentation for thewin_copy
module for the most up-to-date information and examples. - Check Ansible Logs
Review the Ansible logs for any error messages or warnings. - Test on a Single Host
If the issue affects multiple hosts, test the playbook on a single target host first to isolate and troubleshoot the problem more easily. - Debugging
Use thedebug
module to inspect the values of variables and intermediate results within your playbook. - Verbose Output
Run Ansible with the-vvv
flag for increased verbosity. This provides more detailed output, including the exact commands executed on the remote hosts, which can help pinpoint the issue.
Basic File Copy
- hosts: windows_servers
tasks:
- name: Copy a single file
win_copy:
src: /path/to/local/file.txt
dest: C:\Users\Administrator\Desktop\file.txt
Copy with File Mode
- hosts: windows_servers
tasks:
- name: Copy a file with specific permissions
win_copy:
src: /path/to/local/script.exe
dest: C:\Program Files\MyScripts\script.exe
mode: '0755'
Copy from a URL
- hosts: windows_servers
tasks:
- name: Copy a file from a URL
win_copy:
src: http://example.com/install.exe
dest: C:\Temp\
Copy from Another Remote Host
- hosts: windows_servers
tasks:
- name: Copy a file from another remote host
win_copy:
src: "{{ remote_host }}:/path/to/remote/file.txt"
dest: C:\Data
Copy a Directory
- hosts: windows_servers
tasks:
- name: Copy a directory recursively
win_copy:
src: /path/to/local/directory/
dest: C:\Temp\
Set File Contents
- hosts: windows_servers
tasks:
- name: Set the contents of a file
win_copy:
content: "This is the content of the file."
dest: C:\Temp\my_file.txt
- Testing
Always test your playbooks thoroughly on a non-production environment before deploying them to production systems. - Variables
Utilize variables to make your playbooks more dynamic and reusable. - Windows Paths
Use the correct Windows path format (e.g.,C:\
, backslashes). - Permissions
Ensure the Ansible user or the user running the playbook has the necessary permissions to create files and directories in the destination path.
Using win_get_url for Downloads
- Example
- Benefits
- Can directly download files from remote URLs.
- Useful for downloading installers, updates, or other files from external sources.
- Scenario
When the source file is located on a web server (HTTP, HTTPS, FTP).
- hosts: windows_servers
tasks:
- name: Download file from URL
win_get_url:
url: "http://example.com/install.exe"
dest: "C:\Temp\install.exe"
Leveraging win_robocopy for Advanced Synchronization
- Example
- Benefits
- Provides more robust and flexible file synchronization capabilities.
- Scenario
When you require more advanced file synchronization features, such as:- Mirroring directories
Copying files and subdirectories, including deletions. - Resuming interrupted transfers
Continuing a copy operation after an interruption. - File filtering
Specifying inclusion/exclusion criteria for files.
- Mirroring directories
- hosts: windows_servers
tasks:
- name: Synchronize directories using robocopy
win_robocopy:
src: "C:\Source"
dest: "D:\Destination"
options: "/MIR /R:2 /W:5"
# /MIR: Mirrors directories
# /R:2: Retry 2 times on failure
# /W:5: Wait 5 seconds between retries
Utilizing DSC (Desired State Configuration)
- Example
- Benefits
- Provides a powerful framework for managing the entire configuration of a Windows system.
- Offers a higher level of abstraction for managing resources.
- Scenario
When you require a more declarative and state-based approach to managing files and configurations.
- hosts: windows_servers
tasks:
- name: Manage file with DSC
win_dsc:
Name: 'MyFile'
Properties:
DestinationPath: 'C:\Temp\my_file.txt'
Contents: 'This is the content of the file.'
Employing PowerShell Scripts
- Example
- Benefits
- Provides maximum flexibility and control over file operations.
- Can leverage the full power of PowerShell for advanced scripting.
- Scenario
When you need to perform complex file operations or integrate with other PowerShell cmdlets.
- hosts: windows_servers
tasks:
- name: Copy file using PowerShell
win_shell: |
Copy-Item -Path "C:\Source\file.txt" -Destination "C:\Destination"
Choosing the Right Method
- PowerShell
Provides maximum flexibility for custom file operations. - DSC
Recommended for complex configurations and state management. - win_robocopy
Best for advanced synchronization scenarios. - win_get_url
Ideal for downloading files from web servers. - win_copy
Suitable for basic file copying tasks.
Select the method that best suits your specific requirements and complexity of the file transfer or synchronization task.
How to copy files to Windows remote hosts?
I’m going to show you a live Playbook with some simple Ansible code.
I’m Luca Berton and welcome to today’s episode of Ansible Pilot
Ansible copy files to Windows remote hosts
Today we’re talking about Ansible module win_copy
.
The full name is ansible.windows.win_copy
which means is part of the collection of modules “ansible.windows
” targeted windows remote hosts.
This module is pretty stable and out for years.
The purpose is to copy files from the local machine to remote locations.
Because win_copy runs over WinRM, it is not a very efficient transfer mechanism. If you plan to send large files consider hosting them on a web service and using ansible.windows.win_get_url
instead.
Please note that the opposite is done by module win_fetch.
On Linux target use the module ansible.builtin.copy
.
Please note that the opposite is done by module win_fetch
.
On Linux target use the Ansible copy module..
Parameters
dest
path — remote pathsrc
string — local pathbackup
boolean — no / yesforce
string — yes / no
I’m going to summarize the most useful parameters.
The only required parameter is “dest” which specifies the remote absolute path destination. It’s better with “», the Windows way, instead of “/”, the Unix way. Please also verify that the remote user has the right to write in this path.
The “src” specifies the source file in the controller host. It could be a relative or absolute path. I recommend absolutely. If the source is a directory all the content is copied.
Please be more careful with the “/” at the end. If present only the content of the directory is copied, if you want the directory and the content you need to omit the “/” character.
The “backup” boolean parameter allows you to create a backup if the utility overwrites any file.
The default behavior is to transfer the file only if not present or differ in the target host, the file is also verified by Ansible with a checksum on the source and target host automatically. If you want to transfer the all the time the file you need to toggle the “force” parameter to “no”. Please note that setting to “no” also disables the checksum that could speed up the process but also corrupt the file.
Demo
Let’s jump in a real-life playbook to copy files to Windows remote hosts with Ansible.
- copy.yml
---
- name: win_copy module Playbook
hosts: all
become: false
gather_facts: false
vars:
source: "report.txt"
destination: "Desktop/report.txt"
tasks:
- name: copy report.txt
ansible.windows.win_copy:
src: "{{ source }}"
dest: "{{ destination }}"
- report.txt
code with ❤️ in GitHub
Conclusion
Now you know how to copy files to remote Windows hosts with Ansible.
Subscribe to the YouTube channel, Medium, and Website, X (formerly Twitter) to not miss the next episode of the Ansible Pilot.
Academy
Learn the Ansible automation technology with some real-life examples in my
Udemy 300+ Lessons Video Course.
My book Ansible By Examples: 200+ Automation Examples For Linux and Windows System Administrator and DevOps
Donate
Want to keep this project going? Please donate
Patreon
Buy me a Pizza
I will show you several operations which an administrator can perform on a remote windows system using ansible-playbook.
Ansible is one of the most used DevOps tools in the market today. It provides a bunch of windows modules that are used to configure and manage the Windows server. I assume you already have Ansible installed on Windows from where you want to manage the Windows servers.
The following are some of the commonly used tasks performed by Windows administrators on a daily basis. You will be amazed to see how easy it is administered Windows using Ansible.
My Ansible Windows controller machine’s IP address is 192.168.0.106, and my remote Windows system’s IP address is 192.168.0.102. Before you get started, make sure you run a win_ping
module to check whether you are able to connect to windows remote server or not.
Geekflare@MSEDGEWIN10 ~
$ ansible win -m win_ping
192.168.0.102 | SUCCESS => {
"changed": false,
"ping": "pong"
}
My connection to a remote host is successful.
So, let’s get started with Ansible Playbooks…
Copying Files
win_copy is an ansible module that copies a file from the local server to a remote Windows host. I will use this module to copy a single PDF.
Use the below YAML code, give the source and destination paths.
Geekflare@MSEDGEWIN10 ~
$ vi copy.yml
---
- hosts: win
tasks:
- name: Copy File
win_copy:
src: C:\output.pdf
dest: C:\ansible_examples\
remote_src: yes
Run the ansible-playbook for win_copy.
Geekflare@MSEDGEWIN10 ~
$ ansible-playbook copy.yml
PLAY [win] ***********************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************
ok: [192.168.0.102]
TASK [Copy File] *****************************************************************************************************************************
changed: [192.168.0.102]
PLAY RECAP ***********************************************************************************************************************************
192.168.0.102
: ok=2 changed=1 unreachable=0 failed=0
skipped=0 rescued=0 ignored=0
The file has been copied successfully at the destination location on a remote windows system.
Install/UnInstall MSI
To install an application using the MSI file, you need to use win_get_url to mention the path of the MSI file to download and then use the win_package module to install it. The state present means the MSI will be installed on the machine, and the application is in the present state.
Here, I am installing Apache.
YAML code to be used:
Geekflare@MSEDGEWIN10 ~
$ vi msi.yml
---
- name: Installing Apache MSI
hosts: win
tasks:
- name: Download the Apache installer
win_get_url:
url: https://archive.apache.org/dist/httpd/binaries/win32/httpd-2.2.25-win32-x86-no_ssl.msi
dest: C:\ansible_examples\httpd-2.2.25-win32-x86-no_ssl.msi
- name: Install MSI
win_package:
path: C:\ansible_examples\httpd-2.2.25-win32-x86-no_ssl.msi
state: present
Run the ansible-playbook to install using MSI.
Geekflare@MSEDGEWIN10 ~
$ ansible-playbook msi.yml
PLAY [Installing Apache MSI] *****************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************
ok: [192.168.0.102]
TASK [Download the Apache installer] *********************************************************************************************************
changed: [192.168.0.102]
TASK [Install MSI] ***************************************************************************************************************************
changed: [192.168.0.102]
PLAY RECAP ***********************************************************************************************************************************
192.168.0.102
: ok=3 changed=2 unreachable=0 failed=0
skipped=0 rescued=0 ignored=0
Now, go to the windows system and check if the apache application got installed successfully.
C:\Users\geekflare>cd C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin
C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin>httpd -v
Server version: Apache/2.2.25 (Win32)
Server built: Jul 10 2013 01:52:12
You can also install applications using MSI with arguments. Below is the same example as above, but instead of a state, we are using an install argument to install apache.
YAML code to be used:
---
- name: Installing Apache MSI
hosts: win
tasks:
- name: Download the Apache installer
win_get_url:
url: https://archive.apache.org/dist/httpd/binaries/win32/httpd-2.2.25-win32-x86-no_ssl.msi
dest: C:\ansible_examples\httpd-2.2.25-win32-x86-no_ssl.msi
- name: Install MSI
win_package:
path: C:\ansible_examples\httpd-2.2.25-win32-x86-no_ssl.msi
arguments:
- /install
- /passive
- /norestart
To uninstall an application using the MSI file, you need to use the win_package module. The state absent means the application will be uninstalled using the MSI file.
Here, I am uninstalling Apache.
Geekflare@MSEDGEWIN10 ~
$ vi uninstall_msi.yml
---
- name: UnInstalling Apache MSI
hosts: win
tasks:
- name: UnInstall MSI
win_package:
path: C:\ansible_examples\httpd-2.2.25-win32-x86-no_ssl.msi
state: absent
Run the ansible-playbook to uninstall using MSI.
Geekflare@MSEDGEWIN10 ~
$ ansible-playbook uninstall_msi.yml
PLAY [UnInstalling Apache MSI] *****************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************
ok: [192.168.0.102]
TASK [UnInstall MSI] *************************************************************************************************************************
changed: [192.168.0.102]
PLAY RECAP ***********************************************************************************************************************************
192.168.0.102
: ok=2 changed=1 unreachable=0 failed=0
skipped=0 rescued=0 ignored=0
Now, if I check the apache version, I will get the below output as the application got uninstalled.
C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin>httpd -v 'httpd' is not recognized as an internal or external command,
operable program or batch file.
Uninstall Software (.EXE)
You can also uninstall software with .exe file using the product id of that software.
Geekflare@MSEDGEWIN10 ~
$ vi uninstall.yml
---
- hosts: win
tasks:
- name: Uninstall 7-Zip from the exe
win_package:
path: C:\Program Files\7-Zip\Uninstall.exe
product_id: 7-Zip
arguments: /S
state: absent
Run the ansible-playbook to uninstall 7-Zip.
Geekflare@MSEDGEWIN10 ~
$ ansible-playbook uninstall.yml
PLAY [win] *************************************************************************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************************************************************
ok: [192.168.0.102]
TASK [Uninstall 7-Zip from the exe] ***********************************************************************************************************************************************************
changed: [192.168.0.102]
PLAY RECAP *************************************************************************************************************************************************************************************
192.168.0.102 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Stop/Start/Restart Windows Services
win_service ansible module is used to start, stop, or restart a service. Here, I will show you how to stop the tomcat service.
You need to mention the service name in the YAML file and set the state to stop.
Geekflare@MSEDGEWIN10 ~
$ vi service.yml
---
- hosts: win
tasks:
- name: Stop service Tomcat
win_service:
name: Tomcat8
state: stopped
Run the ansible-playbook to stop the tomcat service.
Geekflare@MSEDGEWIN10 ~
$ ansible-playbook service.yml
PLAY [win] ***********************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************
ok: [192.168.0.102]
TASK [Stop service Tomcat] ****************************************************************************************************************
changed: [192.168.0.102]
PLAY RECAP ***********************************************************************************************************************************
192.168.0.102
: ok=2 changed=1 unreachable=0 failed=0
skipped=0 rescued=0 ignored=0
If you check the tomcat service on the windows system, it is now in stopped status.
You can define state to started or restarted or paused to change the status of the service.
Gathering Facts
Using win_disk_facts ansible module, you can retrieve all the disk information of the target host.
Geekflare@MSEDGEWIN10 ~
$ vi disk.yml
---
- hosts: win
tasks:
- name: Get disk facts
win_disk_facts:
- name: Output first disk size
debug:
var: ansible_facts.disks[0].size
- name: Convert first system disk into various formats
debug:
msg: '{{ disksize_gib }} vs {{ disksize_gib_human }}'
vars:
# Get first system disk
disk: '{{ ansible_facts.disks|selectattr("system_disk")|first }}'
# Show disk size in Gibibytes
disksize_gib_human: '{{ disk.size|filesizeformat(true) }}'
disksize_gib: '{{ (disk.size/1024|pow(3))|round|int }} GiB'
Run the ansible-playbook to get the disk information.
Geekflare@MSEDGEWIN10 ~
$ ansible-playbook disk.yml
PLAY [win] ***********************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************
ok: [192.168.0.102]
TASK [Get disk facts] ************************************************************************************************************************
ok: [192.168.0.102]
TASK [Output first disk size] ****************************************************************************************************************
ok: [192.168.0.102] => {
"ansible_facts.disks[0].size": "1000204886016"
}
TASK [Convert first system disk into various formats] ****************************************************************************************
ok: [192.168.0.102] => {
"msg": "932 GiB vs 931.5 GiB"
}
PLAY RECAP ***********************************************************************************************************************************
192.168.0.102
: ok=4 changed=0 unreachable=0 failed=0
skipped=0 rescued=0 ignored=0
Using win_command ansible module, you can execute commands on the remote host and get CPU information, device details, and much more.
Geekflare@MSEDGEWIN10 ~
$ vi check.yml
---
- hosts: win
tasks:
- name: Get disk facts
win_command: wmic cpu get caption, deviceid, name, numberofcores, maxclockspeed, status
register: usage
- debug: msg="{{ usage.stdout }}"
Run the ansible-playbook to get remote system information.
Geekflare@MSEDGEWIN10 ~
$ ansible-playbook check.yml
PLAY [win] ***********************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************
ok: [192.168.0.102]
TASK [Get facts] ************************************************************************************************************************
changed: [192.168.0.102]
TASK [debug] *********************************************************************************************************************************
ok: [192.168.0.102] => {
"msg": "Caption DeviceID MaxClockSpeed
Name
NumberOfCores Status \r\r\nIntel64 Family 6 Model 142 Stepping 9 CPU0 2712 Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz 2 OK \r\r\n\r\r\n"
}
PLAY RECAP ***********************************************************************************************************************************
192.168.0.102
: ok=3 changed=1 unreachable=0 failed=0
skipped=0 rescued=0
ignored=0
Running Commands
Whatever commands you run on a window, they can be run through the ansible win_command module. You just need to specify the command in your YAML file. Here, I am just creating a directory.
Geekflare@MSEDGEWIN10 ~
$ vi commands.yml
---
- hosts: win
tasks:
- name: run an executable using win_command
win_command: whoami.exe
- name: run a cmd command
win_command: cmd.exe /c mkdir C:\test
Run the ansible-playbook to perform win_command operation.
Geekflare@MSEDGEWIN10 ~
$ ansible-playbook commands.yml
PLAY [win] ***********************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************
ok: [192.168.0.102]
TASK [run an executable using win_command] ***************************************************************************************************
changed: [192.168.0.102]
TASK [run a cmd command] *********************************************************************************************************************
changed: [192.168.0.102]
PLAY RECAP ***********************************************************************************************************************************
192.168.0.102
: ok=3 changed=2 unreachable=0 failed=0
skipped=0 rescued=0 ignored=0
Environment Variables
A windows system has multiple environment variables, for example, JAVA_HOME. Using the win_environment ansible module, you can add or modify environment variables on a windows system. In this example, I am adding a new variable to the windows environment variables list.
Geekflare@MSEDGEWIN10 ~
$ vi env.yml
---
- hosts: win
tasks:
- name: Set an environment variable for all users
win_environment:
state: present
name: NewVariable
value: New Value
level: machine
Run the ansible-playbook to add the environment variable on a remote windows machine.
Geekflare@MSEDGEWIN10 ~
$ ansible-playbook env.yml
PLAY [win] ***********************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************
ok: [192.168.0.102]
TASK [Set an environment variable for all users] *********************************************************************************************
changed: [192.168.0.102]
PLAY RECAP ***********************************************************************************************************************************
192.168.0.102
: ok=2 changed=1 unreachable=0 failed=0
skipped=0 rescued=0 ignored=0
Go to the environment variables window; you will see the new variable you just added is present here.
Add/Edit Registry
win_regedit ansible module is used to add or edit registry details on a remote windows machine. You need to give the path of the registry and content to be added/updated. Here I am creating a new registry entry GeekFlare inside HKLM:\SOFTWARE path and then adding name and data to this registry.
Geekflare@MSEDGEWIN10 ~
$ vi registry.yml
---
- hosts: win
tasks:
- name: Creating a registry
win_regedit:
path: HKLM:\SOFTWARE\GeekFlare
- name: Modifying a registry, adding name and data
win_regedit:
path: HKLM:\SOFTWARE\GeekFlare
name: Geek
data: Flare
Run the ansible-playbook to add the registry.
Geekflare@MSEDGEWIN10 ~
$ ansible-playbook registry.yml
PLAY [win] ***********************************************************************************************************************************
TASK [Gathering Facts] ***********************************************************************************************************************
ok: [192.168.0.102]
TASK [Creating a registry] *******************************************************************************************************************
changed: [192.168.0.102]
TASK [Modifying a registry, adding name and data] ********************************************************************************************
changed: [192.168.0.102]
PLAY RECAP ***********************************************************************************************************************************
192.168.0.102
: ok=3 changed=2 unreachable=0 failed=0
skipped=0 rescued=0 ignored=0
If you go to Registry Editor on the remote system, you can see this registry has been added successfully with Name and Data parameters.
Delete Log
win_eventlog ansible module is used to add, clear, or remove windows event logs from the windows system.
Go to Windows Powershell, and list the EventLogs present on the remote windows machine.
PS C:\Users\Geekflare> Get-EventLog -List
Max(K) Retain OverflowAction Entries Log
------ ------ -------------- ------- ---
20,480 0 OverwriteAsNeeded 33,549 Application
20,480 0 OverwriteAsNeeded 0 HardwareEvents
512 7 OverwriteOlder 20 Internet Explorer
20,480 0 OverwriteAsNeeded 0 Key Management Service
128 0 OverwriteAsNeeded 190 OAlerts
Security
20,480 0 OverwriteAsNeeded 44,828 System
15,360 0 OverwriteAsNeeded 3,662 Windows PowerShell
Now, I will show how to remove logs from all sources for Internet Explorer.
Geekflare@MSEDGEWIN10 ~
$ vi log.yml
---
- hosts: win
tasks:
- name: Remove Internet Explorer Logs
win_eventlog:
name: Internet Explorer
state: absent
Run the ansible-playbook to remove the Internet Explorer form the remote windows machine.
Geekflare@MSEDGEWIN10 ~
$ ansible-playbook log.yml
PLAY [win] *************************************************************************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************************************************************
ok: [192.168.0.102]
TASK [Remove Internet Explorer Logs] **********************************************************************************************************************************************
changed: [192.168.0.102]
PLAY RECAP *************************************************************************************************************************************************************************************
192.168.0.102 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Now, if you list the EventLogs again, you will see Internet Explorer logs have been removed.
PS C:\Users\Geekflare> Get-EventLog -List
Max(K) Retain OverflowAction Entries Log
------ ------ -------------- ------- ---
20,480 0 OverwriteAsNeeded 33,549 Application
20,480 0 OverwriteAsNeeded 0 HardwareEvents
20,480 0 OverwriteAsNeeded 0 Key Management Service
128 0 OverwriteAsNeeded 190 OAlerts
Security
20,480 0 OverwriteAsNeeded 44,835 System
15,360 0 OverwriteAsNeeded 56 Windows PowerShell
So, that was all about Ansible playbooks, which can be used for remote windows administration. Go ahead and try out these playbooks. You can also try other Ansible Windows modules available.
Ansible is one of the most popular open-source automation and configuration management tools, allowing infrastructure teams to efficiently manage systems at scale through simple yet powerful playbooks. A standout capability of Ansible is its support for not only Linux/Unix systems but also Windows environments.
One module that demonstrates Ansible‘s cross-platform prowess is the win_copy
module. As the name suggests, win_copy
facilitates seamless file transfers between Ansible controller and Windows hosts. In this comprehensive guide, we‘ll explore common and advanced usage of win_copy
for streamlining file operations across heterogeneous infrastructure.
Overview of win_copy Module
The win_copy
module is part of the ansible.windows
collection. As mentioned earlier, it allows copying files from Ansible control node to remote Windows machines.
Key highlights of the module:
- Supports copying single files, multiple files or entire directories recursively.
- Can create backup copies before overwriting existing files.
- Has check mode to preview file changes.
- Handles large files efficiently without taxing controller resources.
Now let‘s see this powerful module in action through some practical examples.
Installing the Ansible Windows Collection
The win_copy
module resides in the Ansible-developed windows collection, so we need to install it first:
$ ansible-galaxy collection install ansible.windows
This fetches the latest version of the collection containing 100+ Windows-centric modules.
Copying a Single File
Let‘s start with a simple playbook to copy a file from Ansible control node to Windows host:
- hosts: windows
tasks:
- name: Copy config.txt to C:\temp
ansible.windows.win_copy:
src: /ansible/files/config.txt
dest: C:\temp
Here src
points to file location on the Ansible controller while dest
defines the target path on Windows. By default, win_copy
overwrites existing destination files.
We can also inline file content instead of external file through content
parameter:
- name: Create foo.txt with inline content
ansible.windows.win_copy:
content: |
Hello world!
This is foo file content
dest: C:\temp\foo.txt
This creates foo.txt
at given location with provided content.
Copying Multiple Files
To copy multiple files in one go, set src
to a folder path containing those files:
- name: Copy scripts folder recursively
ansible.windows.win_copy:
src: /ansible/files/scripts/
dest: C:\temp\scripts
The trailing slash indicates that scripts
folder should be copied recurisvely. All files within scripts
directory on controller will be copied maintaining same structure.
Preserving Filenames While Copying
If you just want to dump a file inside destination folder without explicitly specifying filename, provide folder path instead of full file path in dest
:
- name: Copy file preserving filename
ansible.windows.win_copy:
src: /ansible/files/config.txt
dest: C:\temp
So config.txt
will be copied as C:\temp\config.txt
. This comes handy when iterating over a folder containing multiple files.
Creating Backup Copies
To safely copy over existing destination files, we can enable backup creation through backup
parameter:
- name: Copy foo.txt creating backup
ansible.windows.win_copy:
src: /ansible/files/foo.txt
dest: C:\temp\foo.txt
backup: true
If foo.txt
already exists at target location, it will be renamed to foo.txt.~before_ansible_backup~
before copying updated file.
The backup name contains timestamp, so running the task multiple times will maintain separate versions.
Copying Files Conditionally
We can control file copy operation based on certain conditions using when
clause:
- name: Copy if source file exists
ansible.windows.win_copy:
src: /ansible/files/foo.txt
dest: C:\temp\foo.txt
when: ansible_local.file_foo_txt.stat.exists
Here foo.txt
will be copied only if it‘s present in controller‘s file system.
We can use any arbitrary condition here leveraging facts like – file timestamps, sizes, etc.
Using Check Mode for Dry Run
It‘s considered a best practice to test playbook changes through Ansible‘s check mode before actual execution.
Check mode shows what changes would occur without applying them:
$ ansible-playbook copy-playbook.yml --check
This test run allows spotting any potential issues upfront without impacting existing systems.
Copying Directories Recursively
We already saw how win_copy
can recursively copy folders maintaining full hierarchy. One special case is selectively copying subdirectories and files rather than entire tree.
This can be achieved through remote_src
parameter like below:
- name: Selective copy from Windows
ansible.windows.win_copy:
remote_src: yes
src: C:\source\scripts\utils
dest: /ansible/backups/scripts
Setting remote_src: true
denotes that source is on remote Windows machine instead of controller. So only utils
subfolder from the given path will be copied.
Handling Large File Transfers Efficiently
Copying large files through Ansible controller is inefficient as it consumes controller disk space and network bandwidth between controller and managed node.
win_get_url
provides a better approach – it directly downloads file on Windows host from a remote URL without routing it via controller:
- name: Download tensorflow binaries
ansible.windows.win_get_url:
url: https://xyz.com/tensorflow.zip
dest: C:\temp
For ultra large binaries, this method is highly recommended.
Understanding Win_copy Limitations
While win_copy makes Windows file transfers easier, it comes with a few limitations:
- Maximum file size limited to available controller disk space
- No native support for advanced protocols like SFTP/SCP
- Limited error handling capabilities
So for advanced use cases, native Windows PowerShell resources may provide better flexibility.
Conclusion
Ansible‘s win_copy module takes away complexity of managing Windows file transfers through automated, idempotent playbooks. We explored it‘s versatile options for copying files/folders, creating backups, conditional tasks, check mode and more.
For large binaries, win_get_url is the way to go as it directly downloads onto Windows host.
Overall, win_copy dramatically cuts down tedious manual file operations – helping engineers focus on writing business logic rather than spend time on filesystem grunt work!