Restarting service remotely as non-admin?


We host (on Server 2019) a few server apps that someone else knows and configures the internal settings through a web interface or client application. Occasionally, the manager of the application needs the service to be stopped or restarted because it hung or they made a setting change that requires a restart. I'd like to give them a script to do that on their own time rather than wait for me. These users are not able to log into the server.

As a sysadmin from a workstation, these kinds of PoSh lines work:

invoke-command -ComputerName $server -ScriptBlock { stop-Service 'XYZservice' }   
Get-Service -ComputerName $Server -Name $Service | start-service

I've given the users "start/stop" permission on the services, and they (and not other users) can get the status of the service with:

Get-Service -ComputerName $Server -Name $Service

However, if my unprivileged user tries to actually start/stop the service, we get:

invoke-command -ComputerName $server -ScriptBlock { stop-Service 'XYZservice' }   
[] Connecting to remote server failed with the following error   
message : Access is denied. For more information, see the about_Remote_Troubleshooting Help topic.


Get-Service -ComputerName $Server -Name $Service | start-service   
start-service : Service 'XYZservice' cannot be started due to the following error: Cannot open XYZservice service on
computer ''.


(Get-WmiObject Win32_Service -filter "name='XYZservice'" -ComputerName $Server).StopService()   
Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

Is there some other PowerShell trick get this to work? What use is the 'start/stop' privilege if it only allows viewing the status?


asked on Stack Overflow Jul 6, 2020 by Teknowledgist

1 Answer


@Lee_Dailey directed me to the most excellent solution. Following these excellent instructions with a little more info from here I was able to do exactly what I needed.

Specifically, I included this line in the .psrc file:

VisibleCmdlets = @{ Name = 'Start-Service'; Parameters = @{ Name = 'Name'; ValidateSet = 'XYZservice' }},
                 @{ Name = 'Restart-Service'; Parameters = @{ Name = 'Name'; ValidateSet = 'XYZservice' }},
                 @{ Name = 'Stop-Service'; Parameters = @{ Name = 'Name'; ValidateSet = 'XYZservice' }}

and then my unprivileged user could do this:

$sesh = new-pssession -ComputerName $Server -ConfigurationName $ConfigName
$cmdString = "restart-service $service"
$scriptBlock = [Scriptblock]::Create($cmdString)
invoke-command -session $sesh -ScriptBlock $scriptblock
remove-pssession $sesh

and nothing else (except the related start/stop commands) on the server.

This JEA ability should be more widely documented.

answered on Stack Overflow Jul 8, 2020 by Teknowledgist

User contributions licensed under CC BY-SA 3.0