Check if a Windows service exists and delete in PowerShell

I am currently writing a deployment script that installs a number of Windows services.

The services names are versioned, so I want to delete the prior Windows service version as part of the installs of the new service.

How can I best do this in PowerShell?

15 Answers

You can use WMI or other tools for this since there is no Remove-Service cmdlet until Powershell 6.0 (See Remove-Service doc)

For example:

$service = Get-WmiObject -Class Win32_Service -Filter "Name='servicename'"
$service.delete()

Or with the sc.exe tool:

sc.exe delete ServiceName

Finally, if you do have access to PowerShell 6.0:

Remove-Service -Name ServiceName
6

There's no harm in using the right tool for the job, I find usign sc.exe (via PowerShell) to be the most reliable method with few dependencies.

Local:

sc.exe delete "MyService"

Remote server:

sc.exe \\server delete "MyService"
6

If you just want to check service existence:

if (Get-Service "My Service" -ErrorAction SilentlyContinue)
{ "service exists"
}

I used the "-ErrorAction SilentlyContinue" solution but then later ran into the problem that it leaves an ErrorRecord behind. So here's another solution to just checking if the Service exists using "Get-Service".

# Determines if a Service exists with a name as defined in $ServiceName.
# Returns a boolean $True or $False.
Function ServiceExists([string] $ServiceName) { [bool] $Return = $False # If you use just "Get-Service $ServiceName", it will return an error if # the service didn't exist. Trick Get-Service to return an array of # Services, but only if the name exactly matches the $ServiceName. # This way you can test if the array is emply. if ( Get-Service "$ServiceName*" -Include $ServiceName ) { $Return = $True } Return $Return
}
[bool] $thisServiceExists = ServiceExists "A Service Name"
$thisServiceExists 

But ravikanth has the best solution since the Get-WmiObject will not throw an error if the Service didn't exist. So I settled on using:

Function ServiceExists([string] $ServiceName) { [bool] $Return = $False if ( Get-WmiObject -Class Win32_Service -Filter "Name='$ServiceName'" ) { $Return = $True } Return $Return
}

So to offer a more complete solution:

# Deletes a Service with a name as defined in $ServiceName.
# Returns a boolean $True or $False. $True if the Service didn't exist or was
# successfully deleted after execution.
Function DeleteService([string] $ServiceName) { [bool] $Return = $False $Service = Get-WmiObject -Class Win32_Service -Filter "Name='$ServiceName'" if ( $Service ) { $Service.Delete() if ( -Not ( ServiceExists $ServiceName ) ) { $Return = $True } } else { $Return = $True } Return $Return
}
1

More recent versions of PS have Remove-WmiObject. Beware of silent fails for $service.delete() ...

PS D:\> $s3=Get-WmiObject -Class Win32_Service -Filter "Name='TSATSvrSvc03'"
PS D:\> $s3.delete()
...
ReturnValue : 2
...
PS D:\> $?
True
PS D:\> $LASTEXITCODE
0
PS D:\> $result=$s3.delete()
PS D:\> $result.ReturnValue
2
PS D:\> Remove-WmiObject -InputObject $s3
Remove-WmiObject : Access denied
At line:1 char:1
+ Remove-WmiObject -InputObject $s3
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [Remove-WmiObject], ManagementException + FullyQualifiedErrorId : RemoveWMIManagementException,Microsoft.PowerShell.Commands.RemoveWmiObject
PS D:\> 

For my situation I needed to be running 'As Administrator'

To delete multiple services in Powershell 5.0, since remove service does not exist in this version

Run the below command

Get-Service -Displayname "*ServiceName*" | ForEach-object{ cmd /c sc delete $_.Name}

One could use Where-Object

if ((Get-Service | Where-Object {$_.Name -eq $serviceName}).length -eq 1) { "Service Exists" }

Combining Dmitri & dcx's answers I made this:

function Confirm-WindowsServiceExists($name)
{ if (Get-Service $name -ErrorAction SilentlyContinue) { return $true } return $false
}
function Remove-WindowsServiceIfItExists($name)
{ $exists = Confirm-WindowsServiceExists $name if ($exists) { sc.exe \\server delete $name }
}

For single PC:

if (Get-Service "service_name" -ErrorAction 'SilentlyContinue'){(Get-WmiObject -Class Win32_Service -filter "Name='service_name'").delete()}
else{write-host "No service found."}

Macro for list of PCs:

$name = "service_name"
$list = get-content list.txt
foreach ($server in $list) {
if (Get-Service "service_name" -computername $server -ErrorAction 'SilentlyContinue'){
(Get-WmiObject -Class Win32_Service -filter "Name='service_name'" -ComputerName $server).delete()}
else{write-host "No service $name found on $server."}
}

To check if a Windows service named MySuperServiceVersion1 exists, even when you might not be sure of its exact name, you could employ a wildcard, using a substring like so:

 if (Get-Service -Name "*SuperService*" -ErrorAction SilentlyContinue)
{ # do something
}

PowerShell Core (v6+) now has a Remove-Service cmdlet.

I don't know about plans to back-port it to Windows PowerShell, where it is not available as of v5.1.

Example:

# PowerShell *Core* only (v6+)
Remove-Service someservice

Note that invocation fails if the service doesn't exist, so to only remove it if it currently exists, you could do:

# PowerShell *Core* only (v6+)
$name = 'someservice'
if (Get-Service $name -ErrorAction Ignore) { Remove-Service $name
}
2

Adapted this to take an input list of servers, specify a hostname and give some helpful output

 $name = "<ServiceName>" $servers = Get-content servers.txt function Confirm-WindowsServiceExists($name) { if (Get-Service -Name $name -Computername $server -ErrorAction Continue) { Write-Host "$name Exists on $server" return $true } Write-Host "$name does not exist on $server" return $false } function Remove-WindowsServiceIfItExists($name) { $exists = Confirm-WindowsServiceExists $name if ($exists) { Write-host "Removing Service $name from $server" sc.exe \\$server delete $name } } ForEach ($server in $servers) {Remove-WindowsServiceIfItExists($name)}
  • For PowerShell versions prior to v6, you can do this:

    Stop-Service 'YourServiceName'; Get-CimInstance -ClassName Win32_Service -Filter "Name='YourServiceName'" | Remove-CimInstance
  • For v6+, you can use the Remove-Service cmdlet.

Observe that starting in Windows PowerShell 3.0, the cmdlet Get-WmiObject has been superseded by Get-CimInstance.

Windows Powershell 6 will have Remove-Service cmdlet. As of now the Github release shows PS v6 beta-9

Source:

I know it's an old question but if someone is looking for one-liner:

On PS Version > 7.2

Wildcard search on the Name property

Get-Service *name* | Select-Object -First 1 | Remove-Service

Search the Display Name property

Get-Service -DisplayName "My Service Description" | Remove-Service

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like