How can I restart a service on a member server in a local domain from another domain joined computer using an account that is not an admin?

Ricky Herndon 21 Reputation points
2023-07-14T01:28:24.9366667+00:00

One of our clients has requested a "button" to be able to restart a publishing service that is running on a server on the network, from his desktop. I actually have a large chunk of this question figured out, I think. I understand that standard users don't have permission to restart services by default, but I have found how to modify the permissions of the service in question by using the sysinternals Process Explorer application. The standard user has permissions to restart the service and I have confirmed that this works when logged into the computer as that user and ran the "restart-service" PowerShell cmdlet. Specifically, the user has the permission to start the service, stop the service, and query the service's status. The trouble I am having is being able to restart the service on the member server REMOTELY from a desktop on the domain. It gives me an error (which I don't have a screenshot of currently; I will get this). Importantly, I have been able to restart the service remotely by running the same command while logged in as the domain admin on the DC. The command I used was "Get-Service -ComputerName <name of the the server> -Name <service name> | restart-service -Force". This doesn't work for a standard user, but I am able to run just the first part of that command before the pipe and get the status of the service just fine. There is some sort of permission I am missing to be able to do this, and I don't know what it is and can't find the answer on my own. Can someone help me?

Windows 10
Windows 10
A Microsoft operating system that runs on personal computers and tablets.
12,062 questions
Windows Server
Windows Server
A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.
13,701 questions
Active Directory
Active Directory
A set of directory-based technologies included in Windows Server.
6,885 questions
PowerShell
PowerShell
A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
2,809 questions
{count} votes

2 answers

Sort by: Most helpful
  1. MotoX80 35,506 Reputation points
    2023-07-14T16:43:53.09+00:00

    See if you can use a straight WMI call.

    Get-CimInstance -ComputerName TheOtherPCname -ClassName win32_service -Filter "Name = 'TheServiceName"
    (Get-CimInstance -ComputerName TheOtherPCname -ClassName win32_service -Filter "Name = 'TheServiceName").stop
    (Get-CimInstance -ComputerName TheOtherPCname -ClassName win32_service -Filter "Name = 'TheServiceName").start
    
    
    

  2. MotoX80 35,506 Reputation points
    2023-07-21T15:49:53.6033333+00:00

    How about doing this a different way?

    I had a similar issue where I had application developers who needed to restart their home grown services on test/dev servers. I didn't want to give them admin access, and the biggest problem that I had was that sometimes their code was in a hung state. So they not only needed to stop the service, we needed to kill the hung process too.

    My solution was to build a .Net web site to allow users to manage their own "stuff". This is not a trivial task, so I'm just sharing this as "food for thought". The web site ran as the system account, so it had full access to the server. I authenticated the user and displayed options based on what their account was allowed to do. Once I got the first site working it was fairly easy to modify it to do other things.

    For your requirements, a simple solution would be to use a file share where the user drops a flag file into. This indicates a stop or start request. It gets processed by a scheduled task that executes a Powershell script. The task runs as the system account, so there is no "access denied" or remote call issues.

    You need to create a folder on the target machine and share it out. Grant the user access so that they can create a start.flag or stop.flag file. It should be easy to build them a .bat file to use as their "button" to create the appropriate flag file. If you put the log file in the same folder, they can review it to see the current status.

    Create a scheduled task that executes this Powershell script. Add a trigger to run at system startup, and set the account as the system account. The task will always show as running, and that's ok.

    $folder = "C:\temp\ZZZZ\"                          # the folder to watch
    $logfile = "C:\temp\ZZZZ\Log.txt"                  # our log file,  
    $ServiceName = "w3svc"                             # the service to start/stop 
    
    function LogIt($msg){
       	Write-Host $msg                                   # seems to only work in ISE            
        $msg | Out-File $logfile -Append
    
    }
    try {                                                 # clear out watcher when testing with ISE   
        $FileSystemWatcher.EnableRaisingEvents = $false
        $FileSystemWatcher.Dispose()
    } catch {}
    
    $FileSystemWatcher = New-Object System.IO.FileSystemWatcher
    $FileSystemWatcher.Path = $folder
    $FileSystemWatcher.EnableRaisingEvents = $True
    $FileSystemWatcher.Filter = '*.flag'
    
    $action = {
    	$msg  = '{0} was  {1} at {2}' -f $Event.SourceEventArgs.FullPath,$Event.SourceEventArgs.ChangeType,	$Event.TimeGenerated
    	LogIt $msg
        if ($Event.SourceEventArgs.ChangeType -eq "Created") { 
            if ($Event.SourceEventArgs.FullPath -match 'start.flag') {
                Logit "We have a start request." 
                try {
                    start-service -Name $ServiceName -ErrorAction Stop
                    logit "The service was started."
                } catch {
                    logit $_
                } 
    	    }
            if ($Event.SourceEventArgs.FullPath -match 'stop.flag') {
                Logit "We have a stop request." 
                try {
                    stop-service -Name $ServiceName -ErrorAction Stop
                    logit "The service was stopped."
                    # If the service won't stop, or some other error occurs, kill the application process here. 
                } catch {
                    logit $_
                    # or kill it here. 
                } 
    	    }
            Logit "Service status is: $((get-service -Name $ServiceName).status)"
            Remove-Item -Path $folder -Filter *.flag  -force -recurse        # clean out all flag files 
        }
    }
    
    Register-ObjectEvent -InputObject $FileSystemWatcher  -EventName Created  -Action $action
    LogIt "Running."
    while($True){
        Start-Sleep -Seconds 1    #keep powershell.exe running
    } 
    
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.