检查Windows服务是否存在并在PowerShell中删除

我目前正在编写一个安装许多Windows服务的部署脚本。

服务名称是版本化的,所以我想删除以前的Windows服务版本作为新服务安装的一部分。

我怎样才能最好在PowerShell中做到这一点?

因为没有Remove-Service cmdlet,所以您需要使用WMI

例如,

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

使用正确的工具没有任何坏处,我发现运行(从Powershell)

 sc.exe \\server delete "MyService" 

最可靠的方法,没有太多的依赖关系。

如果你只是想检查服务的存在:

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

我使用了“-ErrorAction SilentlyContinue”解决scheme,但后来遇到了一个错误logging后面的问题。 所以这里有另一个解决scheme来检查服务是否存在使用“获取服务”。

 # 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 

但是ravikanth具有最好的解决scheme,因为如果服务不存在,Get-WmiObject不会抛出错误。 所以我决定使用:

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

所以要提供更完整的解决scheme:

 # 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 } 

更新版本的PS有Remove-WmiObject。 小心$沉默失败$ 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:\> 

对于我的情况,我需要运行“以pipe理员身份”

结合Dmitri&dcx的答案,我做了这个:

 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 } } 

要检查名为MySuperServiceVersion1的Windows服务是否存在,即使您不确定它的确切名称,也可以使用通配符,使用如下所示的子string:

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

对于单个PC:

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

个人电脑列表macros:

 $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."} } 

修改此选项以获取服务器的input列表,指定主机名并提供一些有用的输出

  $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)} 

可以使用Where-Object

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

在我的情况下,问题是服务已经停留在开始状态,Windows将不会删除该服务,直到它终止。 在这种情况下,您必须手动终止服务。 我遵循这些步骤:

  1. 以pipe理员身份打开cmd
  2. 执行sc queryex {{servicename}}其中service name是服务的短名称(不是显示名称)。 注意PID。
  3. 执行taskkill /f /pid {{PID}}

该服务即时终止并删除。

Windows Powershell 6将具有Remove-Service cmdlet。 截至目前,Github发布了PS v6 beta-9

来源: https //docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/remove-service?view = powershell-6