Saturday, January 3, 2015

Scope

Ever wanted to allow a non-admin to remotely restart a service? No? K.

.... well if sometime you feel like it, this article is for you. We'll walk
through enabling PowerShell
Remoting (part of WinRM),
allowing the non-administrators to connect, and allowing the specified user
or group to restart the service in question.

(Install and) Enable PowerShell Remoting

On Windows server 2012, this step is already completed by default. On
earlier versions of Windows you may need to install software and then enable
connection. That is an article in and of itself, but fortunately it has
already been published
by Ian Farr. Consult that article to determine what software, if any,
you need to install.

After installs:

Note: This may not be necessary on 2012 and up but will not
hurt none the less.

The Enable-PSRemoting cmdlet will run a few different sub cmdlets to
enable the proper services and setup initial permissions.

Set up Security Principals and Grant Permissions to use PowerShell
Remoting

Caution: This grants access to connect to
the PSRemote interface and attempt to issue commands. While this isn't
enough to stop services, etc. by itself it should be done with caution.

There are two levels of security you will need to address with this
operation: the ability to connect to the PSRemote interface/attempt to
issue commands, and the permissions on the service to be restarted. It is
important to consider that these two groups may not be the same; there is
a lot one can do with PSRemoting outside of restarting a specific service.
Thus it is likely you will want to create a larger (in scope and size)
group to access PSRemoting and a smaller group to restart this specific
service.

If you don't much care and just want to get going you can just make the
principals the same... even just a single user. With that said:

Determine what security principals you want to have access to
PSRemoting and create them if necessary. I use an Active Directory group
named appropriately and populated with the desired users, but you could
use anything down to a single user if you like.

Ensure you still have the PowerShell prompt open on your target
server; if not open it as in the section above.

Click "OK" to close the box and apply the permissions, then answer y +
<enter> to restart the service.

Note that on 64-bit systems where you have elected to use the 32-bit
version of PowerShell you will also need to execute steps 3-5 using the Set-PSSessionConfiguration
-ShowSecurityDescriptorUI -Name Microsoft.PowerShell32 command as
well.

Now you can hit the PSRemote interface with the specified accounts; if
you haven't figured it out yet this could be used for many things other
than just restarting a service... this is why PSRemoting is so great!

Grant Service Restart Access to the Appropriate Security Principal

In my example my service will be called "MyService". Normally this is an
operation that would be somewhat complex with the built-in Windows tools,
so I'm going to offer up a simpler way.

Per the install instructions, unblock the zip, extract, and import the
module after install with Import-Module Carbon or the
import-carbon.ps1 script. (Note: You may need to
set-executionpolicy
unrestricted to use Carbon; make sure you set-executionpolicy
Restricted when you're done)

Execute the Grant-ServiceControlPermission,
i.e. Grant-ServiceControlPermission -ServiceName MyService
-Identity MyDomain\MyGroup where MyService is the short name of
the target service and MyDomain\MyGroup is the target security
principal.

Aaron Jensen has done a great job
with the Carbon module and I highly recommend it to anyone operating in a
DevOps space on Windows Server. That one command in point #3 could have
been an article about SDDLs in and of itself.

Test and Provide Restart Commands to Target User(s)

Rather than having your target users learn the appropriate PowerShell
commands, it may be easier to provide them with a script. Here's a sample
one that can restart multiple services on multiple servers after executing
the steps above on each.

This script is really just a starting point; there are many different
directions you could take it based on your needs. For example, you could use
the get-credential cmdlet to allow the user to enter alternative
credentials. To use it as-is simply replace the server(s) and service(s)
names at the top of the script with those you are targeting.

... and that's it! Thanks to carbon and a couple simple commands this
operation is pretty easy to achieve. This has been a big help in lower
environments for letting users, developers, etc. restart services as needed
without having to interrupt their support personnel. Hopefully it helps you
as well.