Windows testing & new module 'winreg'

Hi there,

I've just started getting into ansible on the Linux side (great software!), and
have spent a little time playing with Windows & Cygwin.

I can report that shell actions are quite reliable - I've been able to
string together policy that execs reg adds conditionally based on a
reg query (using 'register:' & only_if) as well as manipulate
firewalls using netsh. Let me know if you want some examples.

I've put together my first subsantial module named 'winreg' which
manipulates registry entries. Here's some examples:

  # before any reg changes are made
  $ ssh Administrator@192.168.1.245 \
      "reg query \"HKLM\Software\Policies\Microsoft\Windows NT\Terminal Services\" /v fDenyTSConnections"
  ERROR: The system was unable to find the specified registry key or value.

  # set fDenyTSConnections to 1
  $ ansible winsvr -m winreg -a
      "keyname='HKLM\Software\Policies\Microsoft\Windows NT\Terminal Services'
       valname=fDenyTSConnections
       datatype=REG_DWORD
       data=0x1
       state=present"
  winsvr | success >> {
      "changed": true
  }
  $ ssh Administrator@192.168.1.245 \
    "reg query \"HKLM\Software\Policies\Microsoft\Windows NT\Terminal Services\" /v fDenyTSConnections"
  HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services
    fDenyTSConnections REG_DWORD 0x1

  # on repeat, changed is false
  $ ansible winsvr -m winreg -a
      "keyname='HKLM\Software\Policies\Microsoft\Windows NT\Terminal Services'
       valname=fDenyTSConnections
       datatype=REG_DWORD
       data=0x1
       state=present"
  winsvr | success >> {
      "changed": false
  }

  # set fDenyTSConnections to 0
  $ ansible winsvr -m winreg -a
      "keyname='HKLM\Software\Policies\Microsoft\Windows NT\Terminal Services'
       valname=fDenyTSConnections
       datatype=REG_DWORD
       data=0x1
       state=present"
  winsvr | success >> {
      "changed": true
  }
  $ ssh Administrator@192.168.1.245 \
    "reg query \"HKLM\Software\Policies\Microsoft\Windows NT\Terminal Services\" /v fDenyTSConnections"
  HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Terminal Services
    fDenyTSConnections REG_DWORD 0x0

  # absent works too
  $ ansible winsvr -m winreg -a
    "keyname='HKLM\Software\Policies\Microsoft\Windows NT\Terminal Services'
     valname=fDenyTSConnections
     state=absent"
  winsvr | success >> {
      "changed": true
  }
  $ ssh Administrator@192.168.1.245 \
    "reg query \"HKLM\Software\Policies\Microsoft\Windows NT\Terminal Services\" /v fDenyTSConnections"
  ERROR: The system was unable to find the specified registry key or value.

I've placed the module on github and would appreciate any feedback.

  https://github.com/cgb/ansible_modules/blob/master/windows/winreg

The one strange thing I've seen is the following:
  winsvr | FAILED >> {
      "cmd": "reg query \"HKLM\\Software\\Policies\\Microsoft\\Windows NT\\Terminal Services\" /v \"fDenyTSConnections\"",
      "failed": true,
      "msg": "[Errno 11] Resource temporarily unavailable",
      "rc": 11
  }

It's not clear to me why this is happening - I can run 'reg query'
many times (infinite loop) over one SSH connection, and I can also run
it many times, spawning a new SSH connection each time. But via
ansible, it occasionally spits the resouce temp unavailable message.

Thanks!

Chris Bennett

Neat!

So my long standing windows theory (undeveloped) is it would be really
great is if we could have a "Windows" connection type and could
remotely execute scripts implemented in native powershell.

This way you don't have to install sshd or python, and the windows
machine can be managed in a native way.

I've still yet to explore what it takes to make that possible but
would welcome experimentation.

--Michael

is't there a posix interface in Windows "Windows Services for Unix"
http://en.wikipedia.org/wiki/Windows_Services_for_UNIX that you might
ride in instead of CYGWIN

Yeah, cygwin is definitely not something we're going to keep in core.

I really want to be able to manage a windows machine (if/when we
tackle this) with minimal OS config changes, and hold true to
ansible's "no bootstrapping" plans.

That being said, if it turns out this is not viable, we can look down
other paths.

--Michael

I personally like the idea of cygwin on all Windows machines I have to
deal with as I can then manage them just as easily as Linux boxes
(I deal with 700ms round trip sometimes, so CLI works a hell of a lot
better than a RDP session).

But I agree - if there was native support for 'winrm' or 'winexe' (or
whatever), it's one less step to having ansible take over.

I'd be happy to do some testing when the Windows support is underway.

I will probably continue writing some other modules - they can just be
ported to the native access method when that happens :slight_smile:

Chris

Chris - ran across this while doing a Google search. I’m also working with a Windows machine in a similar way - using openssh from cygwin to do remote database restores as part of a system configuration/provision. Works pretty well but while changing the way I’m doing some of the remote commands on the Windows box I ended up with what you’re seeing here - and intermittently only. Sometimes it works, sometimes it doesn’t. It always fails when I’m running a native Windows binary or a batch file that runs that same binary. In my case I’m running sqlcmd.exe to import the SQL Server database.

Did you ever figure out why this is happening? Oddly enough this only started today - I’ll have to potentially roll-back my changes prior to today’s changes and see if I can reproduce, that might give me an idea of what’s actually causing the problem, unless you figured something out in the last month?

Just as a reminder, there’s no Windows support at this time.

So this is a question about why your winreg module doesn’t work or what?

Hard to tell what “it” was, sorry :slight_smile:

On my side - I know there’s no windows support but the limited amount of work that I’m doing on Windows right now was a risk worth taking. Just a single command. HOLD IT TOGETHER FOR A SINGLE COMMAND! :slight_smile: So far it’s doing pretty well.

Chris - I did find this little gem and after following the instructions and running about 10 back-to-back playbooks with the database restore command, I didn’t have a single failure. That said, I did have a rogue bash.exe process running on my Windows endpoint, so that might have been the bulk of my issue, but even after killing that it was still throwing errors. I followed the rest of these steps and so far it’s been running perfectly. Try this out and see if it helps:

http://stackoverflow.com/questions/9300722/cygwin-error-bash-fork-retry-resource-temporarily-unavailable

Copy/pasted answer in case it disappears:

rkosegi’s Answer seems to be working for everyone (myself included). But, just so you don’t have to follow the daisy chain of links:

(assuming Cygwin is installed at C:\cygwin):

  1. Open Task Manager and close any processes that look to be Cygwin related.
  2. Open C:\Cygwin\bin in Windows Explorer
  3. Verify that dash.exe, ash.exe, rebase.exe, and rebaseall exist in this folder
    • If any of them are missing, re-run Cygwin setup and select the dash, ash, and rebase packages
  4. right-click your C:\Cygwin folder, uncheck Read-only (if its checked), and press OK.
    • When an error about not being able to switch some files comes up, select “Ignore All”. Wait for this process to complete.
  5. Browse to C:\Cygwin\bin in Windows Explorer
  6. Right click dash.exe and click “Run as Administrator”. A command Prompt should appear with nothing but a $
  7. Type /usr/bin/rebaseall -v, hit enter, and wait for the process to complete.
    • If you get errors about Cygwin processes running, try Step 1 again. If that still doesn’t work, Restart your computer into safe mode and try these steps again.
  8. Try opening Cygwin again.

This process worked for me. I hope it works for you guys too.

Source: http://cygwin.wikia.com/wiki/Rebaseall

Ok, so when you say “it is (still) throwing errors” on this list there is a small rule :slight_smile:

(A) you must define “it”

(B) you must show what the errors actually are.

Otherwise, it just leaves folks confused as to whether there’s an Ansible bug or a user error bug or a configuration problem or … etc.

The “it” there was the action in the playbook executing on the windows server restoring the database - the sqlcmd.exe call. That’s the only action causing issues. And it’s the same “resource is unavailable” return code that Chris was seeing in his original post. That’s the only issue I’ve made reference to here related to ansible unless that wasn’t clear.

Additionally that’s the only “command” action in the playbook for the windows server - and the only one that’s failed in this way.

Does that info satisfy the rule? :slight_smile:

ok, so windows cmd fails under cygwin with custom developed module, no ansible changes required, sounds like?

Thanks!

In my case I wasn’t using a custom module - so slightly different than Chris. My action was the command module in ansible calling a windows executable via Cygwin ssh and the error and result was very similar to his.

I don’t think my issue is an ansible issue per se - probably an issue with Cygwin bash or ssh implementation on the windows side, given the possible Cygwin-based solution I posted.

But since ansible doesn’t support windows at this point, that’s still moot. I figured a possible solution might be appreciated given the recent date of the post. :slight_smile:

Ok, thanks.

Yeah, I am very inclined to see if we can get this going via a different transport in the Windows case.

That being said, Windows SSH being intermittent seems strange, though if you are getting some occasional output at login or something, I can see that causing issues.

I’d love a different transport, something native. Installing ssh on my production windows boxes doesn’t thrill me but it thrills me more than having to manage half of the deployment by hand.

I think the connection to the windows machine is solid. My guess is that it had more to do with that errant bash process running and possible changes to the binaries (after package updates) in Cygwin that other people on the net (per my posted solution) were also seeing in some cases. Regardless it raises a yellow flag (not full red) for me as a solid solution until a native solution becomes available.

TL;DR steer clear of cygwin, and have a clear business reason why
you're not able to use Active Directory + Group Policies for managing
stuff.

I've spent many years managing very large multi-platform outsourced
infrastructures, which are thankfully over. (yay cloud).

Cygwin should not be your end solution for managing infrastructure.
Its a fantastic tool to allow users to run unixy stuff on their
windows boxes, but it's not IMO suited for a management layer.

# Technical

Every time you add additional packages under cygwin you'll need to do
the rebaseall dance to avoid issues like those you've seen. Every
time. And you'll be trying to rebase cygwin while accessing it over a
running cygwin-based ssh session.

# People / Skillset

For integrating ansible into a windows environment, expect confusion
from windows admins who are expecting windows tools, file ending &
formats, and are not comfortable with a unix toolchain stashed in the
middle.

# Alternatives

## SSH

For ssh-based non-cygwin solutions, http://www.bitvise.com/ works very
nicely although pricing is a steep start but it's quite reasonable in
subsequent years due to maintenance contract. I'm sure there are
others that are equally suited.

## Remote execution

Something like http://winexe.sourceforge.net/ might also be an option,
but IMO a robust commercially supported ansible plugin is the way to
go here. Even if it means needing to distribute a package initially
before boxes can be managed.

Generally I'd pose the question -- what are you trying to do with
ansible that is not already possible with Active Directory and Group
Policies? While these are not linux friendly tools they are well
tested, most software integrates with them, and they are understood by
competent windows admins.

I went down the "let's do it all in the command line" back when moving
from NetWare to Windows NT 3.51, and at the end of the day you will
waste non-trivial time trying to re-invent what MS and its ecosystem
have spent decades engineering themselves, for better or for worse.
Obviously this is all about your environment & infrastructure, your
business requirements, but it boils down to how much is your time
worth & can you do it better/cheaper/simpler than native Windows
tools?

A+
Dave

All good points, Dave. However, I’m using Ansible in this sense to run a very specific set of commands on Windows - the only reason being that I have to use SQL Server and run import commands for databases on those systems. I have a very limited number of them, and doing a very limited set of things. I knew there were risks going this direction and figured it was worth some time spent trying to see if I could get past them. Not perfect, but for now pretty good until there is a better solution.

I don’t think AD and policies help me run on-demand SQL Server restore scripts on non-domain and cloud-based servers - setting up AD just for that purpose seems too heavy for me. I do, however, like your winexe suggestion - I’ll have to give that a look if Cygwin continues to cause me problems. I just needed a way to reach into a Windows machine and run commands that weren’t too extensive, and Cygwin was a good solution for that.

If I was managing 20+ of these Windows servers, that’s one thing. But I’m managing three now, I bet I’m maybe up to 5-6 in a couple of years. MAYBE. This set of commands has to work in-tandem with the rest of the Linux set up that’s going on with Ansible, so it’s worth my trying to solve this at the same time as part of the same problem, and with a single toolset.

Thanks!

– mitch