PowerShell'de bir Windows hizmetinin olup olmadığını kontrol edin ve silin


151

Şu anda bir dizi Windows hizmetini yükleyen bir dağıtım komut dosyası yazıyorum.

Hizmet adlarının sürümü belirlendi, bu nedenle yeni hizmetin yüklemelerinin bir parçası olarak önceki Windows hizmet sürümünü silmek istiyorum.

Bunu PowerShell'de en iyi nasıl yapabilirim?

Yanıtlar:


238

Remove-ServicePowershell 6.0'a kadar cmdlet olmadığı için bunun için WMI veya diğer araçları kullanabilirsiniz ( Bkz. Kaldırma-Servis belgesi)

Örneğin:

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

Veya sc.exearaçla:

sc.exe delete ServiceName

Son olarak, PowerShell 6.0'a erişiminiz varsa:

Remove-Service -Name ServiceName

2
Bu örneğin ilgili kısmını powershell'e de taşıyabilirsiniz (TransactedInstaller sınıfını kullanın): eggheadcafe.com/articles/20060104.asp Ancak ravikanth'ın yöntemi muhtemelen daha basittir.
JohnL

7
PS'nin daha yeni sürümleri Remove-WmiObject'e sahiptir ve $ service.delete () için sessiz başarısızlıklara dikkat edin - biçimlendirilmiş örneklerle başka bir yanıt ekledik.
Straff

1
Kısacası, en güncel sürüm Powershell'i Yönetici olarak çalıştırmak ve aşağıdakileri çalıştırmaktır: $service = Get-WmiObject -Class Win32_Service -Filter "Name='servicename'" $service | Remove-WmiObject
BamboOS

Herkesin bilgi için straff cevabı diyor "sessiz dikkat başarısız $service.delete()"
sirdank

Windows PowerShell 3.0'dan başlayarak, cmdlet Get-WmiObject, Get-CimInstance tarafından değiştirilmiştir. Yani bugünlerde bunu yapabilirsiniz:Stop-Service 'servicename'; Get-CimInstance -ClassName Win32_Service -Filter "Name='servicename'" | Remove-CimInstance
Rosberg Linhares

123

İş için doğru aracı kullanmanın bir zararı yok, koşarken buluyorum (Powershell'den)

sc.exe \\server delete "MyService" 

çok fazla bağımlılığı olmayan en güvenilir yöntem.


56
.Exe kısmı çok önemlidir çünkü sc başlı başına Set-Content için bir takma addır.
Tom Robinson

@tjrobinson Bunun için teşekkürler .exe, yorumunuzu görene kadar ihmal ettim. Şimdi benim için çalışıyor.
gwin003

Bu, yalnızca uzak bilgisayar üzerinde haklarınız varsa kullanışlıdır. Değilse (en güvenli ortamlarda benzeri) bu işe yaramaz ve destekleri kimlik geçen o şey gerekir
DaveStephens

\\serverServis yerel ise sunucu adı ( ) atlanır.
jpmc26

1
bu daha iyi çünkü %ve ile daha kolay $_
senaryo

86

Sadece hizmetin varlığını kontrol etmek istiyorsanız:

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

21

"-ErrorAction SilentlyContinue" çözümünü kullandım, ancak daha sonra arkasında bir Hata Kaydı bırakan sorunla karşılaştım. İşte "Get-Service" kullanarak Hizmetin var olup olmadığını kontrol etmenin başka bir çözümü.

# 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 

Ancak ravikanth en iyi çözüme sahiptir çünkü Get-WmiObject, Servis yoksa bir hata vermeyecektir. Bu yüzden kullanmaya karar verdim:

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

Yani daha eksiksiz bir çözüm sunmak için:

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

7
Tamlık için Get-WmiObject -Class Win32_Service -Filter "Name='$serviceName'"ve Get-Service $serviceName -ErrorAction Ignore(hizmet yoksa hatayı tamamen gizleyen) arasında bir hız karşılaştırması yapmaya karar verdim . Get-WmiObject'in daha hızlı olmasını bekliyordum çünkü hata vermiyor. Çok yanılmışım Her birini bir döngüde 100 kez çalıştıran Get-Service 0.16 saniye, Get-WmiObject ise 9.66 saniye sürdü. Dolayısıyla Get-Service, Get-WmiObject'ten 60 kat daha hızlıdır.
Simon Tewsi

13

PS'nin daha yeni sürümlerinde Remove-WmiObject bulunur. $ Service.delete () için sessiz başarısızlıklara dikkat edin ...

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:\> 

Durumum için 'Yönetici olarak' koşmam gerekiyordu


7

Powershell 5.0'da birden fazla hizmeti silmek için, çünkü bu sürümde kaldırma hizmeti yoktur

Aşağıdaki komutu çalıştırın

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

5

Dmitri ve dcx'in cevaplarını birleştirerek şunu yaptım:

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

4

Where-Object kullanılabilir

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


3

Adlandırılmış bir Windows hizmetinin MySuperServiceVersion1var olup olmadığını kontrol etmek için , tam adından emin olmasanız bile, aşağıdaki gibi bir alt dize kullanarak bir joker karakter kullanabilirsiniz:

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

3

Tek PC için:

if (Get-Service "service_name" -ErrorAction 'SilentlyContinue'){(Get-WmiObject -Class Win32_Service -filter "Name='service_name'").delete()}

else{write-host "No service found."}

PC listesi için makro:

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

}

3

PowerShell Core ( v6 + ) artık bir Remove-Servicecmdlet'e sahip .

Onu v5.1'den itibaren mevcut olmadığı Windows PowerShell'e yedekleme planlarını bilmiyorum .

Misal:

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

Hizmet mevcut değilse çağırmanın başarısız olacağını unutmayın, bu nedenle yalnızca şu anda mevcutsa kaldırmak için şunları yapabilirsiniz:

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


2

Sunucuların bir giriş listesini almak, bir ana bilgisayar adı belirtmek ve bazı yararlı çıktılar vermek için bunu uyarladı

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.