A common task that a System Administrator might face in their day is restarting a service on a remote system. While this can be accomplish using the Services.MSC or another various GUI, you have to load the GUI, then connect to the remote system, locate the service and finally perform the action on the service.

There are a few ways that this can be done using WMI (Win32_Services) and using Get-Service along with Stop/Start/Restart-Service cmdlets.

Using WMI

The first method of managing a service that I will go into is using WMI to accomplish this task. First I will connect to the specific service that I want to manipulate, in this case, the windows update client service: wuauserv.

We now have our WMI service object for wuauserv. Lets take a look at all of the available methods for this object.

$Service | Get-Member -Type Method

The methods that we are most concerned with for this article are StartService() and StopService().

With this knowledge of what methods we can use to start and stop the remote service, lets go ahead and stop the service.

$service.stopservice()

Note the ReturnValue property that is returned here after calling the Stop() method. A 0 means that the stop method was successful. For more information on other return values, please check out this msdn page.

Unfortunately, the WMI object is not dynamic nor does it have a way to let you refresh the object to see if the Stop worked or not. With that, we have to perform the query again.

Notice that the return object when using Invoke-WMIMethod is exactly the same as the method we used earlier.

Using existing cmdlets: Get-Service,Stop/Start/Restart-Service

One of the nice things that PowerShell can do both locally and remotely is query a service using the Get-Service cmdlet.

$service = get-service -ComputerName dc1 -Name wuauserv
$service

This works just as well as the WMI method but returns a different object: System.ServiceProcess.ServiceController

Lets look at some of the methods that are available from this object:

$service | Get-Member -Type Method

Much like the WMI object, we have a Start() and Stop() method that we can use to manage the service object. But if you take a closer look, we also see a Refresh() object as well. While we have the same issue where the object doesn’t automatically update itself when the state changes, it does allow us to refresh the object and show us the new state without having to perform another query.

$service.Start()
$service.Refresh()
$service

As you can tell, this works rather nicely even though we do not get a return code of any type to let us know if this worked or not.

Ok, so I mentioned that you can also use Start/Stop/Restart-Service to accomplish the same type of service actions? But if you look at the parameters, you will not see a –Computername parameter that is so common in cmdlets that allow remote connections, such as Get-Service.

So how can we use those cmdlets to manipulate the state of a remote service if there is no –Computername parameter? Fortunately, the cmdlets have an –InputObject parameter that allows us to supply the service object, even if it is a remote object to manipulate the state of the service.

Now for something we haven’t been able to do at all with the WMI or the System.ServiceProcess.ServiceController object is perform a restart of the service easily without having to call a Stop and then Start method. We can now use the Restart-Service cmdlet to accomplish this task.

In conclusion

So as you see, there are a number of ways that you can manipulate the state of a remote service with little to no effort at all. That is the beauty of PowerShell in that there are multiple paths to accomplishing the same goal and all can be done very easily!

I had the same problem in that I couldn’t pipe the Get-Service into Restart-Service to restart a remote service. ie this command “Get-Service -ComputerName dc1 -Name wuauserv | Restart-Service -Verbose”, did not work for me.

I think you’ll find that if executed from a computer named dc2, this example;
“Get-Service -ComputerName dc1 -Name wuauserv | Restart-Service -Verbose”
would actually get the service name from the dc1, but then restart the wuauserv service locally on dc2.

What OS are you running this against? I cannot reproduce the same type of action that you are showing with the local system having its service restarted instead of the remote system that you are piping into the *-Service cmdlet via the services object. I’ve ran this against several systems and each time the remote service is stopped, started or restarted.