We want to deploy an application on a Windows Server 2012 with Ansible 1.8.2.
I have searched and found a list of modules for Windows. Is there a module to execute a .exe?
Did someone already launch a .exe on Windows with Ansible?
The raw module can work, as others have suggested. One challenge is that it won't "know" if the executable has already been run before. In combination with the win_stat module and the when conditional, you can build a script that detects if something has been installed and runs if not installed. For example, I wanted to install the MSBuild development tools:
- name: Check to see if MSBuild is installed
win_stat: path='C:\Program Files (x86)\MSBuild\12.0\Bin\MSBuild.exe'
register: msbuild_installed
- name: Download MS Build Tools 2013
win_get_url:
url: 'http://download.microsoft.com/download/9/B/B/9BB1309E-1A8F-4A47-72A3B3/BuildTools_Full.exe'
dest: 'c:\temp\BuildTools_Full.exe'
when: not msbuild_installed.stat.exists
- name: Install MS Build Tools 2013
raw: 'c:\temp\BuildTools_Full.exe /Quiet /NoRestart /Full'
when: not msbuild_installed.stat.exists
Note that I found the command line arguments for BuildTools_Full.exe by manually running
.\BuildTools_Full.exe /h
The documentation says 'Note there are a few other Ansible modules that don’t start with “win” that also function, including “slurp”, “raw”, and “setup” (which is how fact gathering works).' (http://docs.ansible.com/intro_windows.html), so I would assume that the 'raw' module (http://docs.ansible.com/raw_module.html) should work (I have no Windows VM currently available to play around):
So please try a playbook with:
- raw: <your .exe>
or an Ansible adhoc command:
ansible <your server> -m raw -a '<your .exe>'
There´s another way (and modules) which is not so obvious in the first place: the win_service module combined with the win_nssm module.
As sfuqua already mentioned, most of the time you want to know the "state" of your application - e.g. if it was already installed, is currently running, stopped and so on. Therefore the concept of a Windows service is a very good solution. And it´s very easy to get such a service through the usage of the Non-Sucking Service Manager (nssm).
With the Ansible win_nssm module that´s a cakewalk:
- name: Install & start application as Windows service (via nssm)
win_nssm:
name: "your_app_name"
application: "{{path_to_your_apps_exe}}"
state: restarted
Now we have a real Windows service and can manipulate the state with the help of the win_service module, just as we are used to from applications running on Linux:
- name: Control app Windows service
win_service:
name: "your_app_name"
state: stopped
This approach frees us of the need to use the raw module (which has some disadvantages, like disabling change handler support) and the troubles to write and maintain scripts for this simple task.
As mentioned here, you can use win_command. But if you need to run an interactive .exe, you may need to run it through PsExec. An example Playbook can then look like this:
- name: Test PsExec
hosts: windows
tasks:
- name: Copy PsExec
win_copy:
src: <WORKING_FOLDER>/PsExec.exe
dest: "{{ ansible_user_dir }}/Desktop/PsExec.exe"
force: no
- name: Run Windows Calculator
win_command: "{{ ansible_user_dir }}/Desktop/psexec.exe -accepteula -nobanner -i 1 -s calc.exe"
register: output
- debug: var=output
I have resolved the issue with psexec
In the Playbook
- name: test raw module
hosts: Windows
gather_facts: false
tasks:
- name: Stop process 01
script: startProcess.ps1
And startProcess.ps1
#Creating the credential for the invoke-command.
$strScriptUser = "COMPUTERNAME\USer"
$strPass = "PASSWORD"
$PSS = ConvertTo-SecureString $strPass -AsPlainText -Force
$cred = new-object system.management.automation.PSCredential $strScriptUser,$PSS
#Invoke-Command to call the psexec to start the application.
invoke-command -Computer "." -Scriptblock {
c:\AnsibleTest\ps\psexec.exe -accepteula -d -h -i 1 -u COMPUTERNAME\USER -p PASSWORD PATH_TO_THE_EXE\PROGRAM.EXE
} -Credential $cred
You need to install the psexec in the remote PC. Switches for the psexec
Related
I am working on a simple playbook that will ultimately be able to start/stop/restart windows services and I ran into an issue:
fatal: [mspdbwn1w01]: FAILED! => {
"msg": "The powershell shell family is incompatible with the sudo become plugin"
}
Below is the playbook:
- name: Add Host
hosts: localhost
connection: local
strategy: linear
tasks:
- name: Add Temp Host
add_host:
name: "{{ win_client }}"
group: temp
- name: Target Server
connection: winrm
hosts: temp
tasks:
- name: Stop a service
win_service:
name: "{{ service }}"
state: stopped
Google hasn't been much help, and I've tried everything I could find, every variation of become*.
I don't know if it matters, but due to the nature of the environment I work in, I have 2 separate users to log into *nix hosts vs. windows hosts.
Any assistance or guideance would be greatly appreciated.
Your system seems to use sudo as the default become method, which is not compatible with PowerShell. For Windows (and PowerShell), you can use runas as the become method. Add:
become_method: runas
to your playbook or task. You can get a list of all available become methods with:
ansible-doc -t become -l
Example:
doas Do As user
dzdo Centrify's Direct Authorize
enable Switch to elevated permissions on a network device
ksu Kerberos substitute user
machinectl Systemd's machinectl privilege escalation
pbrun PowerBroker run
pfexec profile based execution
pmrun Privilege Manager run
runas Run As user
sesu CA Privileged Access Manager
su Substitute User
sudo Substitute User DO
You can view the documentation for a particular become method with:
ansible-doc -t become runas
If you still get erros, pay attention to the error message, as it most probably is a different one. Using privilege escalation requires the definition of a username and a password for this purpose, for example.
i need to install Symantec endpoint security on my linux system and im trying to write a playbook to do so
when i want to install the program i use ./install.sh -i
but after the installation when i run the installation again i get this msg:
root#TestKubuntu:/usr/SEP# ./install.sh -i
Starting to install Symantec Endpoint Protection for Linux
Downgrade is not supported. Please make sure the target version is newer than the original one.
this is how i install it in the playbook
- name: Install_SEP
command: bash /usr/SEP/install.sh -i
I would like if it's possible to maybe check if the service is up and if there is no service then install it or maybe there is a better way doing this.
Thank you very much for your time
Q: "I would like to check if the service is up and if there is no service then install it."
It's possible to use service_facts. For example to check a service is running
vars:
my_service: "<name-of-my-service>"
tasks:
- name: Collect service facts
service_facts:
- name: Install service when not running
command: "<install-service>"
when: "my_service not in ansible_facts.services|
dict2items|
json_query('[?value.state == `running`].key')"
To check a service installed use
json_query('[].key') }}"
(not tested)
Please try something like below.
- name: Check if service is up
command: <command to check if service is up>
register: output
- name: Install_SEP
command: bash /usr/SEP/install.sh -i
when: "'running' not in output.stdout"
Note: I have used running in when condition : If the service command returns something specific, include that instead of running.
I am trying to get an Ansible task to print the version used while running on Windows 10.
I am currently trying something like this:
---
# Source: https://serverfault.com/a/695798
- name: Get version
win_shell: ansible --version
register: ansibleVersion
# How I chose to expose the version collected
- name: Display version
win_msg:
msg: "Ansible Version: {{ ansibleVersion.stdout }}"
display_seconds: 30
However, I am getting this output:
"stderr": "ansible : The term 'ansible' is not recognized as the name of a cmdlet, function, script file, or operable program. \r\nCheck the spelling of the name, or if a path was included, verify that the path is correct and try again.\r\n
Full disclosure, I am new to Ansible. I have tried win_command, win_shell, and am not really sure what all to try next.
The Windows machines can be provisioned using ansible but not installed on Windows.
You can configure the Windows machine from a Linux machine as the controller host.
And you can run the ansible-playbook from this controller host which will run on the windows machine.
---
- hosts: all
tasks:
- name: Get Windows version
win_shell: "systeminfo /fo csv | ConvertFrom-Csv | select OS*, System*, Hotfix* | Format-List"
register: windows_version
- name: Print Windows host information
debug:
msg: "{{ windows_version }}"
Save this as main.yml
Add the Windows host IP in hosts file
[win]
172.16.*.*
[win:vars]
ansible_user=user
ansible_password=password
ansible_connection=winrm
ansible_winrm_server_cert_validation=ignore
Run the playbook using the following command
ansible-playbook -i hosts main.yml
If you want ansible on Windows, then there are other installation methods to run it on Windows.
Also mentioned in the comments.
I have attached some links to setup ansible on Windows 10 subsytem for Linux,
Ansible - Windows Frequently asked questions
Using Ansible through Windows 10's Subsystem for Linux
Hope it solves your issue.
Thank you to all those who answered and commented. The articles were very informative, and I learned a much more about Ansible. The answers put me on the scent of the actual task I made.
To restate my comment on the original question, I had a misunderstanding. Because on my Windows machine I had to add a user ansible, I thought it was being run locally somehow. However, it turns out, Ansible deploys are being run from a Linux VM.
Once I had this misunderstanding cleared up, I realized I needed to use delegate_to: 127.0.0.1 in my Ansible task. Here is my Check Ansible version task:
---
# SEE: https://serverfault.com/a/695798/514234
- name: Check Ansible version
command: ansible --version
register: ansibleVersion
delegate_to: 127.0.0.1
- name: Print version
debug:
msg: "Ansible Version: {{ ansibleVersion.stdout }}"
Ansible on mojave works A1. Winrm is enabled on the windows 10 home machine. I have setup a windows update play that reboots the machine. The problem is it reboots but then i have to login manually.
Maybe someone has an idea on how to automate that part ? is there a module that i could use ?
- name: Install windows updates
win_updates:
category_names:
- SecurityUpdates
- CriticalUpdates
- UpdateRollups
reboot: yes
look at :
https://learn.microsoft.com/en-us/sysinternals/downloads/autologon
Its a bit of a hack, but it does permit a user to autologon, in unattended mode.
I usually simply copy the autologon exec to 'Program Files' (ansible module win_copy), and then run it with CLI params (using ansible-vault of course; the password is hashed in the win registry... not super secure, but for my use-case, it is sufficient):
- name: Sync the contents of autologon directory
win_robocopy:
src: "E:\\install_packages\\Autologon"
dest: "C:\\Program Files\\Autologon"
- name: Configure autologon
win_command: "C:\\Program Files\\Autologon.exe <username> <domain> <password>"
I'm new to Ansible. The following is my requirement,
Transfer files(.tar.gz) from one host to many machines (38+ Nodes) under /tmp as user1
Log in to each machines as user2 and switch to root user using sudo su - (With Password)
extract it to another directory (/opt/monitor)
Change a configuration in the file (/opt/monitor/etc/config -> host= )
Start the process under /opt/monitor/init.d
For this, should I use playbooks or ad-hoc commands ?
I'll happy to use ad-hoc mode in ansible as I'm afraid of Playbooks.
Thanks in advance
You’d have to write several ad hoc commands to accomplish this. I don’t see any good reason to not use a playbook here. You will want to learn about playbooks, but it’s not much more to learn than the ad hoc commands. The sudo parts are taken care of for you by using the -b option to “become” the using sudo. Ansible takes care of the logging in for you via ssh.
The actions you’ll want to make use of are common for this type of setup where you’re installing something from source, commands like yum, get_url, unarchive, service. As an example, here’s a pretty similar process to what you need, demonstrating installing redis from source on a RedHat-family system:
- name: install yum dependencies for redis
yum: name=jemalloc-devel ... state=present
- name: get redis from file server
get_url: url={{s3uri}}/common/{{redis}}.tar.gz dest={{tmp}}
- name: extract redis
unarchive: copy=no src={{tmp}}/{{redis}}.tar.gz dest={{tmp}} creates={{tmp}}/{{redis}}
- name: build redis
command: chdir={{tmp}}/{{redis}} creates=/usr/local/bin/redis-server make install
- name: copy custom systemd redis.service
copy: src=myredis.service dest=/usr/lib/systemd/system/
# and logrotate, redis.conf, etc
- name: enable myredis service
service: name=myredis state=started enabled=yes
You could define custom variables like tmp and redis in a global_vars/all.yaml file. You’ll also want a site.yaml file to define your hosts and a role(s).
You’d invoke the playbook with something like:
ansible-playbook site.yaml -b --ask-become-pass -v
This can operate on your 38+ nodes as easily as on one.
You'll want a playbook to do this. At the simplest level, since you mention unpacking, it might look something like this:
- name: copy & unpack the file
unarchive: src=/path/to/file/on/local/host
dest=/path/to/target
copy=yes
- name: copy custom config
copy: src=/path/to/src/file
dest=/path/to/target
- name: Enable service
service: name=foo enabled=yes state=started