检查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将不会删除该服务,直到它终止。 在这种情况下,您必须手动终止服务。 我遵循这些步骤:
- 以pipe理员身份打开cmd
- 执行
sc queryex {{servicename}}
其中service name是服务的短名称(不是显示名称)。 注意PID。 - 执行
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