File copy/Create folder on Windows server based upon json output from Powershell

Firstly - sorry for the noob question.

I’ve written a Powershell script that is run from a play that returns in json the name of a zip file.

Output from Powershell

{
“Name”: “latest-ansible v0.1.zip”
}

playbook

The issue you are seeing is that you are using the stdout_lines return value which is the stdout of the script that was run but split into a list on each newline. You want to use the stdout return value from the script which would be the full stdout of your json. The task’s would look something like this

`

  • name: Run Powershell script and return json including zip file name
    script: files/script.ps1
    register: script_result

this uses the filter from_json to convert the raw json string to a

dictionary in Ansible so you can access the variables a lot easier

  • name: convert the script result to a dict in Ansible
    set_fact:
    script_filename: ‘{{ script_result.stdout|from_json }}’

  • name: copy files
    win_copy:
    src: C:\Temp{{ script_filename.Name }} # if Name in the JSON is ‘latest-ansible v0.1.zip’, then src sent to win_copy is ‘C:\Temp\latest-ansible v0.1.zip’
    dest: C:\Inetpub
    remote_src: yes # you need to set this so the copy happens remote to remote, by default src is based on the local Ansible controller

`

I haven’t tested this, but see how you go, it should bring you onto the right track. A few more notes;

  • You are getting warnings saying ansible_winrm_cert_validation is unsupported, the variable should actually be ansible_winrm_server_cert_validation, if you remove the definition of ansible_winrm_cert_validation then those warnings will go away
  • In your win_copy task, you quoted the jinja2 block, you only need to quote it when the value starts with a block like so
    `

doesn’t need quoting as the value itself doesn’t start with {

key: value/{{ variable }}

needs to be quoted as the value does start with {

key: “{{ variable }}”
`

Thanks

Jordan

Thanks Jordan! That code worked a treat - really appreciate your assistance and detailed explanations below.

Jordan do you know how to strip the “.zip” off the file name? I’ve been looking at http://jinja.pocoo.org/docs/2.10/templates/#truncate but haven’t cracked it yet.

Hey

There are a few ways to do this, they usually revolve around using filters to “filter” the value into something else. Ansible has a few filters available outside of the standard Jinja2 functions which can be found here https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html. In your case you want to use the splitext to split the path between the path/filename and the extension like so;

`
src: C:\Temp{{ (script_filename.Name|splitext)[0] }}

`

What we do here is pass the value of script_filename.Name to the filter splitext and that ultimately returns a value, in this case returns a tuple of (path without extension, extension). We don’t want the extension so we only get the first element from the return value and because it is a 0 based index, 0 is the first element.

Thanks

Jordan

Nice - thanks Jordan. That’s easier than what I’ve just done…

win_file:
path: C:\inetpub{{ script_filename.Name | regex_replace(‘.zip$’,‘’) }}

Thanks again!

Sorry - I’ve got another question(s) related to this. I’ve modified the PS script to return 2 x json outputs, each assigned to a different PS variable. Each output contains a different file name.

Is it possible to return two outputs to the playbook ran off the task that runs the PS script? Can 2 x variables in the play be registered for this task? Not just script_result?

Another option would be to create a separate script - each script returns a different string that is parsed to playbook… or create a hashtable… @ { file1 = string1; file2 = string 2} - then convert this to json?

Assuming the hashtable is the recommended approach - the returns json could then be searched for the relevant key name?

Updated - changed script to now add the two variables into a hashtable that is converted to json - assume this is the correct approach. This can be returned to the script_output registered in the play.

Yep, I would create a hashtable, convert that to JSON and output that. That way you can parse that into Ansible easily and select whatever key you want. This is how the PowerShell modules work as well.

Thanks

Jordan

Cool. Thanks Jordan. Works a treat.