Currently, drush uses ssh to execute drush commands on a remote server. If the remote server is running Windows, we would like to be able to use winrm to run the remote command so that additional components do not need to be installed on the server.

Comments

greg.1.anderson’s picture

Status: Active » Needs work
StatusFileSize
new5.64 KB

I'm having trouble configuring winrm, so I have not actually tested this myself yet. :P However, in simulate mode, this patch does appear to generate the correct winrs command to run a drush command remotely on a Windows server, so it just might work. To use, just add 'os' => 'windows', to the site alias for a site running Windows OS, and drush will then use winrs instead of ssh for drush @winserver status and the like.

Note that this patch does not affect sql-sync, which remains unsupported. That issue is being tracked in #1149886: sql dump does not work with windows sql server, which I will hopefully address shortly.

Still needs a bit of documentation (ideally including winrm setup :> ).

kulov’s picture

I managed to get it working! It is ok, but needs few fixes.
Note that alias needs to have port 80 or http:// prefix added for the remote-host address otherwise winrm tries to connect to default port 5985.
Winrm prompts for password, however the prompt is not displayed on screen and you have to type it, hit Enter, wait for the command to complete and after that you get something typed on screen. It may be buffer flush issue.
Somehow the command run remotely end up escaped twice and it doesn't work unless I remove escaping in drush_escapeshellarg($cmd, "LOCAL").
There are two print statements that need to be removed:

drush_print_r($site_record);
  drush_print('os is ' . $os);

At last - I did not define os for my alias, so $os end up empty. In drush_os function it says that default os will be Linux. However call to drush_is_windows() below detects client OS as Windows. It then assumes that client and server OS are the same and make remote call to Windows OS. I am not sure that it is correct to assume remote OS to be the same as client OS. Better it would be nice to leave default OS as Linux in case one did not set os parameter in alias.

greg.1.anderson’s picture

Great!

Is there any way to provide a password to winrs non-interactively? Is there any equivalent of ssh key pairs with winrs? Having to enter a password for all remote commands is a serious liability.

I'll look into the double-escaping.

I'm not sure whether the default for an unspecified OS should be the same as the client platform or "Linux". Originally it was always "Linux"; I changed it recently. I think assuming "Linux" is probably better, because then the same alias will work the same way on different machines; it would be inelegant for an alias to change from "Linux" to "Windows" just because you sent it to someone using a different OS than you.

moshe weitzman’s picture

Looks like --password is the way. See http://ss64.com/nt/winrs.html.

I agree that docs on how to install and configure winrs would be great. I have not tried to use it yet.

greg.1.anderson’s picture

Thanks, moshe.

Winrm comes pre-installed, and in theory is really easy to set up, but none of the config commands work for me -- I get 'permission denied'. I have identified that you need to run your shell as administrator, and the admin must have a non-empty password, but that is insufficient. Once I figure out how to configure it, I'll write up some docs.

greg.1.anderson’s picture

Further work on this issue is waiting on #1058874: drush_backend_invoke buffers output till end of command. Show progress., but here are some notes on configuring winrm / winrs.

Before you use winrs, you must configure winrm. On a new install of Windows 7:

  1. Log in as an account with administrator access rights.
  2. Insure that your account has a password. Assign one if necessary, then log out and log back in again.
  3. Right-click on Accessories -> Command Prompt and select run as administrator to open a DOS prompt in administration mode.
  4. Run winrm quickconfig and answer "yes" to all prompts.

The output I received from winrm quickconfig is shown below:

C:\Windows\system32>winrm quickconfig
WinRM is not set up to receive requests on this machine.
The following changes must be made:

Set the WinRM service type to delayed auto start.
Start the WinRM service.
Configure LocalAccountTokenFilterPolicy to grant administrative rights remotely
to local users.

Make these changes [y/n]? y

WinRM has been updated to receive requests.

WinRM service type changed successfully.
WinRM service started.
Configured LocalAccountTokenFilterPolicy to grant administrative rights remotely
 to local users.
WSManFault
    Message
        ProviderFault
            WSManFault
                Message = WinRM firewall exception will not work since one of th
e network connection types on this machine is set to Public. Change the network
connection type to either Domain or Private and try again.

Error number:  -2144108183 0x80338169
WinRM firewall exception will not work since one of the network connection types
 on this machine is set to Public. Change the network connection type to either
Domain or Private and try again.

The errors do not matter; the first two operations were successful, and only the last, "grant administrative rights remotely to local users" (which does not sound like a good idea anyway) failed.

After that, you can set the TrustedHosts config variable to allow your client to connect to your server:

C:\Windows\system32>WinRM set winrm/config/client @{TrustedHosts="*"}
Client
    NetworkDelayms = 5000
    URLPrefix = wsman
    AllowUnencrypted = false
    Auth
        Basic = true
        Digest = true
        Kerberos = true
        Negotiate = true
        Certificate = true
        CredSSP = false
    DefaultPorts
        HTTP = 5985
        HTTPS = 5986
    TrustedHosts = *

You can replace the "*" with the fqdn of a specific server if you do not want to open up your configuration to the whole world. (n.b. these instructions are for a dev machine setup on a local network; adequate security precautions are left as the responsibility of the reader.)

At one point, I got my Win7 box into a strange state and could not get any winrm commands to work; I would receive an "Access Denied" error regardless of what steps I tried. Running winrm quickconfig returned an error message that the system was already configured, followed by another "access denied" error. It was reported that winrm could be reset as follows:

winrm invoke restore winrm/config @{}

Unfortunately, this did not work for me; I received the same "access denied" error. Perhaps this command will help in some instances, though.

greg.1.anderson’s picture

It appears that installing msysgit is the thing that causes winrs to stop working.

greg.1.anderson’s picture

This time, the reset instructions from #6 worked.

greg.1.anderson’s picture

Status: Needs work » Needs review
StatusFileSize
new3.77 KB

This works. Adds capability to specify 'winrs-password' to your site alias. This is documented in examples.aliases.drushrc.inc; however, cmdkey is recommended:

cmdkey.exe /add:your-remotehost.domain.com /user:USERNAME /pass:PASSWORD

greg.1.anderson’s picture

StatusFileSize
new18.47 KB

Further refactoring backend invoke to make it more reusable (e.g. from sql-sync).

greg.1.anderson’s picture

Title: Remote commands to drush on Windows server » Remote commands to drush on Windows server + backend invoke / sql-sync refactor
StatusFileSize
new44.03 KB

Expanding the scope of the refactoring to include sql-sync, so that remote syncs also use winrs.

Contexts now forwarded via backend invoke per #1185142: drush_invoke_process_args() does not inherit contexts

greg.1.anderson’s picture

Priority: Normal » Major

Upping priority of Windows issues important for drush-5.0.

moshe weitzman’s picture

Read through this and I don't have much feedback. It looks fine to me. I'd like to see more doxygen for drush_sql_su() and drush_sitealias_get_db_spec().

Also, expanded test coverage would be swell. We are changing a lot of code.

Don't know that many folks are able to review this. Feel free to commit when it works for you.

greg.1.anderson’s picture

Status: Needs review » Fixed

I went ahead and committed this; it works well on Linux, and all test cases pass. Remote commands on Windows work, sql-sync on Windows may need further adjustment in a future issue, but we're a lot closer.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

moshe weitzman’s picture

I got wedged in the same way as Greg in #6 and the only way I could stop seeing access denied is to use the incantation at bottom of http://social.technet.microsoft.com/Forums/en-US/winserverManagement/thr....

Now my winrm looks normal (i think) but I am still seeing a hang when doing anything needing a backend call such as updatedb. An example is updatedb when it calls the sollowing (you have to actually have a pending update to see this. just update schema_version column in system table to quickly see it.)

php.exe "C:\\Users\\mweitzman\\drush\\drush.php" --php=php.exe --debug --root=C:/Users/mweitzman/temp/drupal-7.10 --uri=http://default updatedb-batch-process 4 4 --backend=2 2>&1