Im using ansible 2.7.5 and a windows 10 host over winRM.
If I execute:
ansible win -I hosts -m win_command -a "PowerShell.exe ipconfig"
I get an output and it works fine.
But I want to write it inside a playbook and not as an ansible command but I won't get any output so I tried to use stdout but it wont work:
- hosts: win
gather_facts: no
tasks:
- name: PowerShell Command
win_command: powershell.exe
register: shell_result
args:
stdin: ipconfig
-debug:
var: shell_result.stdout_lines
Any suggestions how to get the first command working as a playbook?
Your - debug task isn't indented properly and doesn't have the right spacing. I'm not sure if that's just from posting here or if it's in your original file.
Your call to powershell.exe left out the - parameter which is what tells it to accept input on stdin. So it should be win_command: powershell.exe -.
That said, ipconfig is actually ipconfig.exe so instead of trying to run a shell with win_command just run ipconfig.exe directly:
- hosts: win
gather_facts: no
tasks:
- name: ipconfig
win_command: ipconfig.exe
register: shell_result
- debug:
var: shell_result.stdout_lines
Related
I am looking to start a Go web server (a single .exe) on Windows Server via Ansible.
The equivalent in Linux that works great looks like:
- name: Start web server
become: true
become_user: root
shell:
cmd: nohup /home/centos/webserver </dev/null >/dev/null 2>&1 &
I can do it in PowerShell using Start-Process -FilePath -NoNewWindow .\webserver.exe but it terminates when I close the PowerShell window.
I have also looked into doing it with Start-Job { & C:\Path\to\webserver.exe } and Get-Job shows it completed, but not sure what that means since it's a web server and should just keep running until it's killed.
I need something that will star the webserver but not be tied to the shell so Ansible can do it via the win_shell module. I would have hoped this would work, but no luck:
- name: Start the webserver processes
win_shell: Start-Process -FilePath .\webserver.exe
args:
chdir: C:\Users\Administrator
Any and all suggestions much appreciated!
Looks like I was trying to find a more complicated way to do it with PowerShell when Ansible had built in functionality all along. This achieves exactly what I want:
- name: Start webserver
win_shell: .\webserver.exe
args:
chdir: C:\Users\Administrator
async: 180
poll: 0
I'm learning Ansible and am running into something I haven't seen a good reference for anywhere -
I have a .ps1 on my target machine that I want to run via Ansible, while passing it a variable as well. My playbook for it is pretty simple:
---
- name: run stuff
hosts: all
gather_facts: no
vars:
force_all_hosts: false
tasks:
- name: run mounter script
win_shell: C:\folder\file.ps1 -password (ConvertTo-SecureString "{{vault_pw}}" -AsPlainText -Force)
The contents of the .ps1 work when I run them manually local to the Windows machine, so I know the actual commands work. When I run the playbook it works as well - the Powershell script runs succesfully and the changes are made - but the actual task never completes so the playbook can't finish.
I added a "< NUL" to the end of the win_shell line to force a message that said the return code wasn't 0 - the RC was 1 - but then I updated Ansible to 2.8 and now the "<" character is reserved so I can't recreate the return code failure anymore.
Is there a way to force the return code, and filter if it's <= 2 or something? Or better yet, is there another way to ensure the job ends other than using async/poll since that causes the play to report that it failed?
Can you try the async option in ansible?
https://docs.ansible.com/ansible/latest/user_guide/playbooks_async.html
I'm using ansible to manage several windows hosts on the cloud, I need to create a log file and link it to another file, so I use the follow playbook
- name: init the directory structure of windows
hosts: '{{windows_hosts}}'
tasks:
- name: create log file and link it to log directory
win_command: mklink log D:\prod\log
args:
chdir: D:\prod\project
when running this playbook, the hosts can be found successfully, but I got the following error report
> TASK [Gathering Facts]
> ********* ok: [111.111.2.40]
>
> TASK [create log file and link it to log directory]
> ********* fatal: [111.231.76.40]: FAILED! => {"changed": false, "cmd": "mklink log
> D:\\prod\\log", "msg": "Exception calling \"SearchPath\" with \"1\"
> argument(s): \"Could not locate the following executable
> mklink.exe\"", "rc": 2}
and I tryed this command on the remote host in the same directory, it can be execute successfully. I don't know what to do......
win_command is for running executables directly. Hence the user's environment isn't applied and you aren't running inside a dos box or powershell window
so 'mklink' isn't actually an executable - its a built-in feature of the cmd.exe program. So to run mklink via win_command, you'd have to run the cmd.exe program and pass it an argument to tell it do what 'mklink' does, like this:
win_command: cmd.exe /k mklink log D:\prod\log
Do the following way:
---
- name: Run Windows Command
hosts: windows
gather_facts: False
tasks:
- name: win command
win_shell: cmd /k mklink log D:\prod\log
args:
chdir: D:\prod\project
In codeship - I am trying to use the env variables. My setup looks like this:
codeship-services.yml
environment:
- ENV=my-var
codeship-steps.yml
type: parallel
steps:
- command: echo $ENV
I does not work, it just prints $ENV.
Environment variables are only available when you the command is invoked in the context of a shell. By default that's not the case (similar to how docker run operates as well).
To get access to environment variables, either extract the command to a shell script and call the script instead, or explicitly invoke a shell
- service: app
command: sh -c "echo $ENV"
For the life of me, I cannot seem to get my provisioning script to execute when I run my container. Down the road, I will need to pass in arguments to the docker run command to replace 'hiiii' and '123' for multiple container deployments.
This is my docker file
FROM microsoft/aspnet:3.5-windowsservercore-10.0.14393.1198
SHELL [“powershell”, “-Command”, “$ErrorActionPreference = ‘Stop’; $ProgressPreference = ‘SilentlyContinue’;”]
COPY *.ps1 /Container/
COPY [“wwwroot”, “/inetpub/wwwroot”]
COPY [“Admin”, “/Program Files (x86)Admin”]
COPY [“Admin/web.config”, “/Program Files (x86)/Admin/web_default.config”]
#ENTRYPOINT [“powershell”]
CMD [“powershell.exe”, -NoProfile, -File, C:\Container\Start-Admin.Docker.Cmd.ps1 -Parm1 ‘Hiiii’ -parm2 ‘123’]
I have also tried the shell version of CMD as follows
CMD powershell -NoProfile -File C:\Container\Start-Admin.Docker.Cmd.ps1 -Parm1 ‘Hiiii’ -Parm2 ‘123’
This is the command I am using.
docker image build -t image:v1:v1 .
docker run --name container -p 8001:80 -d image:v1
After I create and run the container I see that the script did not run, or failed. However, I can exec into powershell on the container and run the script manually and it works fine and I see all the changes that I need.
docker exec --interactive --tty container powershell
C:\Container\Start-Admin.Docker.Cmd.ps1 -Parm1 ‘Hiiii’ -Parm2 ‘123’
I am just at a loss as to what I am missing regarding CMD.
Thanks!
I was able to get it working the way I had hoped. Though I am still working out some details in the provisioning script, this is how I ended up getting the result I wanted from the docker side of things.
FROM microsoft/aspnet:3.5-windowsservercore-10.0.14393.1198
#The shell line needs to be removed and any RUN commands need to be immediately proceeded by 'powershell' eg RUN powershell ping google.com
#SHELL [“powershell”, “-Command”, “$ErrorActionPreference = ‘Stop’; $ProgressPreference = ‘SilentlyContinue’;”]
COPY *.ps1 /Container/
COPY [“wwwroot”, “/inetpub/wwwroot”]
COPY [“Admin”, “/Program Files (x86)Admin”]
COPY [“Admin/web.config”, “/Program Files (x86)/Admin/web_default.config”]
ENV myParm1 Hiiii
ENV myParm2 123
ENTRYPOINT ["powershell", "-NoProfile", "-Command", "C:\\Container\\Start-Admin.Docker.Cmd.ps1"]
CMD ["-parm1 $Env:myParm1 -parm2 $Env:myParm2"]
The docker run command looks like this
docker run -d -p 8001:80 -e "myParm1=byeeeee" --name=container image:v1
I hope this helps someone else that is in my boat. Thanks for all the answers!
You can give this a try. ARG passes the variable to shell accessible via PS $env: variable.
ARG parmOne=Hiiii
ARG parmTwo=123
# Run a native PowerShell session and pass the script as a command.
RUN ["powershell", "-NoProfile", "-Command", "C:\\Container\\Start-Admin.Docker.Cmd.ps1 -Parm1 $env:parmOne -parm2 $env:parmTwo"]