erik121
erik121

Reputation: 341

stop or start a service on remote machine

I created a script that will start or stop a service based on it's display name. My script works on the local machine but I would like to make sure that it can be done on a remote machine and the local machine. I am not sure how to get it working on a remote machine.

any help would be appreciated.

    $serviceName = Read-Host -Prompt 'Please enter service name: '

# Check that service name exists
If (Get-Service $serviceName -ErrorAction SilentlyContinue) 
{

# Check that service name is not empty
if([string]::IsNullOrEmpty($serviceName)) 
{            
    Write-Host "Service name is NULL or EMPTY"            
} 
else 
{            


$Choice =  Read-Host -Prompt 'Would you like to start or stop the service'

#Start service
If ($Choice -eq 'start') {

Start-Service -displayname $serviceName

Write-Host $serviceName "Starting..." -ForegroundColor Green 
}

#Stop service
If ($Choice -eq 'stop') {

  Stop-Service -displayname $serviceName

  Write-Host $serviceName "Stopping..." -ForegroundColor Green
}
 }
  }
else {            
    Write-Host "Service name does not exist"            
}

Upvotes: 2

Views: 22423

Answers (3)

henrycarteruk
henrycarteruk

Reputation: 13227

You can't use Start-Service/Stop-Service for a remote computer, you can however pass a service object from Get-Service (using the ComputerName parameter) to Set-Service which can perform the same start/stop actions for a remote computer:

Get-Service $ServiceName -ComputerName $ComputerName | Set-Service -Status Running

I find this to be much easier than using PowerShell Remoting or WMI commands.

You can easily update your code with minimal code changes:

$serviceName = Read-Host -Prompt 'Please enter service name: '

#get computername or use localhost for local computer
if(($ComputerName = Read-Host 'Enter Computer Name, leave blank for local computer') -eq ''){$ComputerName = 'localhost'}

$Service = Get-Service -DisplayName $serviceName -ComputerName $ComputerName -ErrorAction SilentlyContinue

# Check that service name exists
if ($Service) {
    # Check that service name is not empty
    if([string]::IsNullOrEmpty($serviceName)){Write-Host 'Service name is NULL or EMPTY'}
    else {    
        $Choice =  Read-Host -Prompt 'Would you like to start or stop the service'

        #Start service
        If ($Choice -eq 'start') {
            $Service | Set-Service -Status Running
            Write-Host $serviceName 'Starting...' -ForegroundColor Green
        }

        #Stop service
        If ($Choice -eq 'stop') {
          $Service | Set-Service -Status Stopped
          Write-Host $serviceName 'Stopping...' -ForegroundColor Green
        }
    }
}
else {            
    Write-Host 'Service name does not exist'            
}

Upvotes: 4

Jeff Zeitlin
Jeff Zeitlin

Reputation: 10799

Start-Service and Stop-Service do not work against remote computers. You will either need to do PowerShell remoting, or use WMI. In my environment, PowerShell remoting is blocked by default, but we use WMI instead; service objects retrieved through Get-WMIObject have a method called Start-Service() which can be called on the retrieved service object:

(Get-WmiObject -ComputerName $ComputerName -Class Win32_Service -Filter "Name='$ServiceName'").StartService()

Stopping a service on a remote computer using WMI works the same way; you would call the service object's StopService() method instead.

I recommend that you read the information in Get-Help Get-WMIObject and the MSDN reference on the Win32_Service class.

ETA: It should be noted that by omitting the -ComputerName parameter, WMI will work on the local computer as well.

Upvotes: 1

TheMadTechnician
TheMadTechnician

Reputation: 36297

Assuming that you have not disabled PowerShell remoting, the easiest way to do it is to wrap it in a function with ComputerName as an optional parameter, and then use Invoke-Command and splat PSBoundParameters.

Function Toggle-Service{
[cmdletbinding()]
Param([string[]]$ComputerName)
$serviceName = Read-Host -Prompt 'Please enter service name: '

# Check that service name exists
If (Invoke-Command -ScriptBlock {Get-Service $serviceName -ErrorAction SilentlyContinue} @PSBoundParameters) 
{

# Check that service name is not empty
if([string]::IsNullOrEmpty($serviceName)) 
{            
    Write-Host "Service name is NULL or EMPTY"            
} 
else 
{            


$Choice =  Read-Host -Prompt 'Would you like to start or stop the service'

#Start service
If ($Choice -eq 'start') {

Invoke-Command -ScriptBlock {Start-Service -displayname $serviceName} @PSBoundParameters

Write-Host $serviceName "Starting..." -ForegroundColor Green 
}

#Stop service
If ($Choice -eq 'stop') {

  Invoke-Command -ScriptBlock {Stop-Service -displayname $serviceName} @PSBoundParameters

  Write-Host $serviceName "Stopping..." -ForegroundColor Green
}
 }
  }
else {            
    Write-Host "Service name does not exist"            
}
}

Then you can call Toggle-Service without a parameter to perform it locally, or include the name of a remote server to perform the actions on that server.

Upvotes: 1

Related Questions