ansible win_updates output

Hi guys,

I’m trying to return the following message; i basically want to display the following message and only list the ‘title’ field for the available update. The message should read;

" host1 has 12 updates available. The following updates are available for install:

  • KB11222
  • KB112232
    etc
    "

I’ve tried a bunch of permutations, with the latest shown below (which doesn’t work by the way).

Here’s the raw output; each item in the ‘updates’ list is defined by the value of the ‘id’ field. Normally this would be a key like ‘item’ where i could then specify, updates.item.title, right?

How can i get around this?

Cheers

ok: [host1] => {
“available_updates”: {
“changed”: true,
“failed”: false,
“found_update_count”: 2,
“installed_update_count”: 0,
“reboot_required”: false,
“updates”: {
“749e3c7a-4779-4c14-bccd-2b608c39ddc9”: {
“id”: “749e3c7a-4779-4c14-bccd-2b608c39ddc9”,
“installed”: false,
“kb”: [
“3084905”
],
“title”: “Update for Windows Server 2012 R2 (KB3084905)”
},
“8832eabb-68ee-4ef9-b45e-b8fee94581b8”: {
“id”: “8832eabb-68ee-4ef9-b45e-b8fee94581b8”,
“installed”: false,
“kb”: [
“890830”
],
“title”: “Windows Malicious Software Removal Tool for Windows 8, 8.1, 10 and Windows Server 2012, 2012 R2, 2016 x64 Edition - November 2017 (KB890830)”
},
},
}

Here's the raw output; each item in the 'updates' list is defined by the
value of the 'id' field. Normally this would be a key like 'item' where i
could then specify, updates.item.title, right?

I'm not sure what you mean, but it sound wrong.

How can i get around this?

Cheers

ok: [host1] => {
    "available_updates": {
        "changed": true,
        "failed": false,
        "found_update_count": 2,
        "installed_update_count": 0,
        "reboot_required": false,
        "updates": {
            "749e3c7a-4779-4c14-bccd-2b608c39ddc9": {
                "id": "749e3c7a-4779-4c14-bccd-2b608c39ddc9",
                "installed": false,
                "kb": [
                    "3084905"
                ],
                "title": "Update for Windows Server 2012 R2 (KB3084905)"
            },
            "8832eabb-68ee-4ef9-b45e-b8fee94581b8": {
                "id": "8832eabb-68ee-4ef9-b45e-b8fee94581b8",
                "installed": false,
                "kb": [
                    "890830"
                ],
                "title": "Windows Malicious Software Removal Tool for
Windows 8, 8.1, 10 and Windows Server 2012, 2012 R2, 2016 x64 Edition -
November 2017 (KB890830)"
            },
},
}

Something like this will give you what you're looking for.

  - debug:
      msg: |
        {{ inventory_hostname }} has {{ available_updates.found_update_count }} updates available. The following updates are available for install:
        {% for key, value in available_updates.updates.iteritems() %}
        - {{ value.kb | join(',') }}
        {% endfor %}

Perfect, thank you sir!

Much appreciated

Hi Kai,

Any way we can format the output of the debug message as below i.e. have a KB per line?

" host1 has 12 updates available. The following updates are available for install:

  • KB11222
  • KB112232
    etc"

Thank you

It should based on your output of the available_updates.
What are you seen and do you have the output of the variable that does not give you that output?

If the "kb": field contains more than one element, my code will put them in a comma separated sting.
If that is what you see, and just want all to be in one list this should fix it.

   - debug:
       msg: |
         {{ inventory_hostname }} has {{ available_updates.found_update_count }} updates available. The following updates are available for install:
         {% for key, value in available_updates.updates.iteritems() %}
         {% for i in value.kb %}
         - {{ i }}
         {% endfor %}

Thanks Kai. The output is working fine, it’s more about the formatting. For example, with the following debug code, i receive the following;

  • debug:
    msg: "{{ inventory_hostname }} has {{ available_updates.found_update_count }} updates available.
    {% for key, value in available_updates.updates.iteritems() %}
  • KB: {{ value.title }}
    {% endfor %}"

ok: [host1] => {
“msg”: "host1 has 6 updates available. - KB: Update for Windows Server 2012 R2 (KB3013769) - KB: Update for Windows Server 2012 R2 (KB3102429) - KB: Update for Windows Server 2012 R2 (KB3013816) - KB: Update for Windows Server 2012 R2 (KB3084905) - KB: 2017-11 Preview of Monthly Quality Rollup for Windows Server 2012 R2 for x64-based Systems (KB4050946) - KB: Windows Malicious Software Removal Tool for Windows 8, 8.1, 10 and Windows Server 2012, 2012 R2, 2016 x64 Edition - November 2017 (KB890830) "
}

What i’d like, is for the output to be formatted as below;

ok: [host1] => {
“msg”: "host1 has 6 updates available.

  • KB: Update for Windows Server 2012 R2 (KB3013769)
  • KB: Update for Windows Server 2012 R2 (KB3102429)
  • KB: Update for Windows Server 2012 R2 (KB3013816)
  • KB: Update for Windows Server 2012 R2 (KB3084905)
  • KB: 2017-11 Preview of Monthly Quality Rollup for Windows Server 2012 R2 for x64-based Systems (KB4050946)
  • KB: Windows Malicious Software Removal Tool for Windows 8, 8.1, 10 and Windows Server 2012, 2012 R2, 2016 x64 Edition - November 2017 (KB890830) "
    }

Is this possible?

Thank you

Thanks Kai. The output is working fine, it's more about the formatting. For
example, with the following debug code, i receive the following;

Ansible is not a reporting tool so it has limit supported for nice output on the screen.
You can put it in a file with the template module.

        - debug:
             msg: "{{ inventory_hostname }} has {{
available_updates.found_update_count }} updates available.
                  {% for key, value in
available_updates.updates.iteritems() %}
                - KB: {{ value.title }}
                  {% endfor %}"

The first ting to do is losing the quotes and add a pipe, the pipe is essential.

   - debug:
       msg: |
         {{ inventory_hostname }} has {{ available_updates.found_update_count }} updates available.
         {% for key, value in available_updates.updates.iteritems() %}
         - KB: {{ value.title }}
         {% endfor %}"

ok: [host1] => {
    "msg": "host1 has 6 updates available. - KB: Update for Windows Server
2012 R2 (KB3013769) - KB: Update for Windows Server 2012 R2 (KB3102429) -
KB: Update for Windows Server 2012 R2 (KB3013816) - KB: Update for Windows
Server 2012 R2 (KB3084905) - KB: 2017-11 Preview of Monthly Quality Rollup
for Windows Server 2012 R2 for x64-based Systems (KB4050946) - KB: Windows
Malicious Software Removal Tool for Windows 8, 8.1, 10 and Windows Server
2012, 2012 R2, 2016 x64 Edition - November 2017 (KB890830) "
}

What i'd like, is for the output to be formatted as below;

ok: [host1] => {
    "msg": "host1 has 6 updates available.
     - KB: Update for Windows Server 2012 R2 (KB3013769)
     - KB: Update for Windows Server 2012 R2 (KB3102429)
     - KB: Update for Windows Server 2012 R2 (KB3013816)
     - KB: Update for Windows Server 2012 R2 (KB3084905)
     - KB: 2017-11 Preview of Monthly Quality Rollup for Windows Server
2012 R2 for x64-based Systems (KB4050946)
     - KB: Windows Malicious Software Removal Tool for Windows 8, 8.1, 10
and Windows Server 2012, 2012 R2, 2016 x64 Edition - November 2017
(KB890830) "
}

Is this possible?

To get an other output than the default one, you'll need to change the stdout callback plugin[1].

If you use the debug, it output nice human readable text that you are looking for, but it will be more verbose.
You could check out and test the other to see if them give you the output you want or you could write your own.

[1] https://docs.ansible.com/ansible/devel/plugins/callback.html#plugin-list

Thanks Kai - i managed to get exactly what i wanted by using the following environment variable;

ANSIBLE_STDOUT_CALLBACK=debug

Here’s the final debug/msg configuration of the playbook;

  • debug:
    msg: |
    {{ inventory_hostname }} has {{ available_updates.found_update_count }} updates available.
    {% for key, value in available_updates.updates.iteritems() %}
  • KB: {{ value.title }}
    {% endfor %}

Now when i run the playbook, i get the following output;

ok: [host1] => {}

MSG:

host1 has 6 updates available.

  • KB: Update for Windows Server 2012 R2 (KB3013769)
  • KB: Update for Windows Server 2012 R2 (KB3102429)
  • KB: Update for Windows Server 2012 R2 (KB3013816)
  • KB: Update for Windows Server 2012 R2 (KB3084905)
  • KB: 2017-11 Preview of Monthly Quality Rollup for Windows Server 2012 R2 for x64-based Systems (KB4050946)
  • KB: Windows Malicious Software Removal Tool for Windows 8, 8.1, 10 and Windows Server 2012, 2012 R2, 2016 x64 Edition - November 2017 (KB890830)

Thanks for all your help

Hi,

One last request; what’s the best way to get the users confirmation before continuing further with the playbook? I’d like to be able to say, "host1 has 6 updates available.

  • KB: Update for Windows Server 2012 R2 (KB3013769)
  • KB: Update for Windows Server 2012 R2 (KB3102429)
  • KB: Update for Windows Server 2012 R2 (KB3013816)
  • KB: Update for Windows Server 2012 R2 (KB3084905)
  • KB: 2017-11 Preview of Monthly Quality Rollup for Windows Server 2012 R2 for x64-based Systems (KB4050946)
  • KB: Windows Malicious Software Removal Tool for Windows 8, 8.1, 10 and Windows Server 2012, 2012 R2, 2016 x64 Edition - November 2017 (KB890830)

“Do you wish to install all updates(y/n)?”. If the user presses y, the playbook will continue and complete the install + reboot. If the user presses n, the playbook will exit.

I’ve tried prompts, var_prompts etc; none of which achieve what i’m looking for.

Any advice?

Thank you

I think the only option is the pause module.