win_updates rewrite

Hi all,

Awhile back, I was trying to help a customer use the win_updates module- they reported that it chugged for a long time, claimed to install updates, but ultimately did nothing. I started doing some debugging, and realized that the module could likely never have worked as-written. The Windows Update scripting client is not allowed to run under a remote token, and I’m not aware of any way to get a non-remote token under WinRM. I started to write a fix that would just run the existing module code under a Powershell Scheduled-Job, but kept getting stymied by PSWindowsUpdate’s lack of error handling- also the reason the original module silently completed without actually installing any updates. Ultimately, I ended up just rewriting the entire module to drive the Windows Update client directly, instead of using PSWindowsUpdate. I’ve done quite a bit of testing on 2008R2 and 2012R2, and I’m finally comfortable that it seems to work pretty well. The Scheduled-Job stuff is a lot jankier than the docs would have you believe, so there’s a ton of code to try and recover from the numerous ways that it can fail, but it seems to be pretty stable now (I might rewrite it using ephemeral services down the line if the Scheduled-Job stuff turns out to be problematic). Please give it a shot, though, and +1 if it works for you- would like to get this included in the initial 2.0 drop if possible.

I initially wrote and tested under 1.9.2, so this module should be copyable to a local module library and runnable under 1.9, if you don’t want to test in 2.0.

Feedback welcome! The PR is at: https://github.com/ansible/ansible-modules-extras/pull/854

Thanks,

-Matt

Thanks for tackling this.

Wondering out loud if the scheduled job stuff would be worth pulling out into either a separate module, at some point? I’d say into the common powershell code but probably wouldn’t want to include it into every module.

Added to my list to test, can’t make any promises when at the moment though.

Jon

​Matt,

I’d love to see this as part of 2.0 – however, i’m just super stoked that I have something that seems to work.

I’ll keep kicking the tires on this one and let you know if i run into any issues. Thanks a ton.

_Dann​

I ran into the same issue with a different use case (using dism image manipulation utilities) – and made an ansible module for running powershell snippets inside a scheduled job that works on ansible 1.9 … https://github.com/ansible/ansible-modules-extras/pull/1007#issuecomment-145115161

Part of me thinks that it might be nice for ansible to bake the ability to invoke ansible modules from within a scheduled job into the winrm execution logic. Could also be a nice way to add windows support for the moral equivalent of sudo_user/become …?

Ben

It would be great to have a function in powershell.ps1 which would enable execution thru a scheduled task. No doubt we’re gonna run into stuff which requires it in the future as well. I’ll do some pondering on it over the weekend.

An equivalent of async for python, it should be made compatible with
current 'async options'

Brian, is there any documentation on what a module needs to look like in order to support async?

Group, I have outlined a rough alpha here: https://gist.github.com/trondhindenes/6ecb829057e01a6da568
The script is supposed to be the combination of powershell.ps1 and module code which gets copied onto the target node.

Whenever “RunAsScheduledTask” is invoked inside a module, the script will:

  1. Copy itself to a new file and add some metadata so that the script knows if its running as a scheduled task or not
  2. Any code inside the “$IsScheduledTask -eq $true” block will execute as a scheduled task. Ouput will be redirected to scheduledtaskoutput.json
  3. Any code in the else block afterwards will be executed after the scheduled task has been execited. At a minimum this code will parse the scheduledtaskoutput.json and return that down to Ansible using exit-json.

I think I’m on to something here, but very keen on feedback. As far as I can see this approach would let us control the scheduled task itself (credentials etc) using ansible variables(options) which I think is key.

1. So I was thinking this could work like the current async for
python, ansible would copy both the wrapper (scheduler) and the module
and execute the wrapper giving it the module as a parameter.

2. Instead of modifying modules to support this, just do this when
the async option is selected in the task, that way modules themselves
don't have to know about schedule or not and should work transparently
on all

3. this can again mirror the current async behavior

Gotcha. I guess there are a couple of use cases for this: async operations like you describe and operations which are problematic when invoked directly from ansible like the win_updates module (because of the way the updates api is implemented in windows). I’ll have a look at the async stuff and see if we can accomodate both.

Given how generally iffy the PS ScheduledJob stuff is, and how significant the execution delays are, I’d be nervous about adopting it for async. I got up close and personal with its many warts doing win_updates, and after that experience, I’d be happy if we never had to touch it again. I think there are lighter-weight ways to accomplish what async needs to do that are easier to clean up after and that will perform much better.

I’ve been thinking about how to implement async for awhile now- I figured something a lot closer to the *nix/Python impl with just backgrounded processes and file-based output in a jid directory would be a lot less messy. Consider the case of “fire-and-forget” async tasks (both intentional and async tasks whose output was dropped due to an abort). If you’re using the task scheduler, there’s no easy way to have the output automatically cleaned up, as we don’t have a way to signal that we truly don’t care about the task output (so that the task could nuke itself as its final act). The directory-based stuff is pretty easy to clean up, and the mess is localized to the user’s Ansible directory, as opposed to polluting and slowing down a system-critical service like the task scheduler. There are also logging considerations- since Task Scheduler logging is kinda all-or-nothing, you don’t really get any benefit there unless task logging is enabled globally, which again, is probably not such a hot idea for servers that can run thousands of them a day.

Just my $0.02…

-Matt