Проверьте, существует ли служба Windows, и удалите ее в PowerShell
в настоящее время я пишу сценарий развертывания, который устанавливает ряд служб Windows.
имена служб являются версионными, поэтому я хочу удалить предыдущую версию службы Windows в рамках установки новой службы.
Как я могу лучше всего сделать это в PowerShell?
14 ответов:
вы можете использовать WMI или другие инструменты для этого, так как нет
Remove-Serviceкомандлет до Powershell 6.0 ( см. Remove-Service doc)например:
$service = Get-WmiObject -Class Win32_Service -Filter "Name='servicename'" $service.delete()или :
sc.exe delete ServiceNameнаконец, если у вас есть доступ к PowerShell 6.0:
Remove-Service -Name ServiceName
нет никакого вреда в использовании правильного инструмента для работы, я нахожу запуск (из Powershell)
sc.exe \server delete "MyService"самый надежный метод, который не имеет много зависимостей.
Если вы просто хотите проверить сервис наличие:
if (Get-Service "My Service" -ErrorAction SilentlyContinue) { "service exists" }
я использовал" - ErrorAction SilentlyContinue " решение, но затем позже столкнулся с проблемой, что он оставляет ErrorRecord позади. Итак, вот еще одно решение, чтобы просто проверить, существует ли служба с помощью "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но ravikanth имеет лучшее решение, так как Get-WmiObject не будет выдавать ошибку, если служба не существует. Поэтому я остановился на использовании:
Function ServiceExists([string] $ServiceName) { [bool] $Return = $False if ( Get-WmiObject -Class Win32_Service -Filter "Name='$ServiceName'" ) { $Return = $True } Return $Return }так, чтобы предложить более полное решение:
# 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. Остерегайтесь молчаливых не за $обслуживание.исключать. )(..
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:\>для моей ситуации мне нужно было работать "как администратор"
комбинируя ответы Дмитрия и 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 } }
можно использовать Where-Object
if ((Get-Service | Where-Object {$_.Name -eq $serviceName}).length -eq 1) { "Service Exists" }
чтобы проверить, есть ли служба Windows с именем
MySuperServiceVersion1существует, даже если вы не уверены в его точном имени, вы можете использовать подстановочный знак, используя подстроку следующим образом:if (Get-Service -Name "*SuperService*" -ErrorAction SilentlyContinue) { # do something }
для одного ПК:
if (Get-Service "service_name" -ErrorAction 'SilentlyContinue'){(Get-WmiObject -Class Win32_Service -filter "Name='service_name'").delete()} else{write-host "No service found."}макрос для списка компьютеров:
$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."} }
для удаления нескольких служб в Powershell 5.0, так как удалить службу не существует в этой версии
выполните следующую команду
Get-Service -Displayname "*ServiceName*" | ForEach-object{ cmd /c sc delete $_.Name}
адаптировал это, чтобы взять входной список серверов, указать имя хоста и дать некоторые полезные выходные данные
$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)}
PowerShell базовый ( v6+) в настоящее время имеет
Windows Powershell 6 будет иметь Remove-Service. На данный момент релиз Github показывает PS V6 beta-9
для версий PowerShell до v6, вы можете сделать это:
Stop-Service 'YourServiceName'; Get-CimInstance -ClassName Win32_Service -Filter "Name='YourServiceName'" | Remove-CimInstanceдля V6+, вы можете использовать командлет Remove-Service.
обратите внимание, что начиная с Windows PowerShell 3.0,командлет Get-WmiObject был заменен Get-CimInstance.
Comments