As part of a build pipeline I'm working on the octopus deploy process needs to talk to the database using roundhouse as a different user from the one running the deployment. This is done because the database uses integrated AD authentication, which I quite like. If this build were running on Linux then it would be as simple as editing the sudoers file and calling the command using sudo. Unfortunately this is Windows and the command line has long been a secondary concern.
I started by asking on the western devs slack channel to see if anybody else had done this and how. Dave Paquette suggested using psexec. This is a tool designed for running commands on a remote computer but if you leave the computer name off it will run on the local machine. This sounded perfect.
However I had a great deal of trouble getting psexec to work in the way I wanted. The command I wanted to run seemed to fail all the time giving an confusing error code -1073741502. The fix provided didn't seem to work for me so after an afternoon of bashing my head against psexec I went looking for another solution. Running remote processes gave me an idea: what about powershell remoting?
Some investigation suggested that the command I wanted to run would look like
1 | Invoke-command localhost -scriptblock { rh.exe --some-parameters } |
This would remote to localhost and run the roundhouse command as the current user. To get it to work using a different user then the command needed credentials passed into it. I had the credentials stored as sensitive variables in Octopus which set them up as variables in powershell. To turn these into credentials you need to do
1 |
|
Now these can be passed into invoke command as
1 | Invoke-command localhost -authentication credssp -Credential $cred -scriptblock { |
You might notice that authentication flag, this tells powershell the sort of authentication and cor credssp you also need to enable Credential Security Service Provider. To do this we run
1 | Enable-WSManCredSSP -Role server |
From an admin powershell session on the machine. Normally you would run these on different machines but we're remoting to local host so it is both the client and the server. I've enabled client for all machines but you might want to lock this down a bit more.
Finally I needed to pass some parameters to roundhouse proper. This can be done by passing them into the script block and then receiving them as parameters inside the block
1 | Invoke-command localhost -authentication credssp -Credential $cred -scriptblock { |
The whole process is pretty convoluted but that's Windows command line for you. What would this look like in bash on Linux?
1 | sudo $roundHouseExe --s=$databaseServer --d="$targetDb" --f=$fName /ni |
So yeah.