web-dev-qa-db-fra.com

Vérifier si un service Windows existe et supprimer dans PowerShell

J'écris actuellement un script de déploiement qui installe un certain nombre de services Windows.

Les noms de services sont versionnés, je souhaite donc supprimer la version précédente du service Windows dans le cadre des installations du nouveau service.

Comment puis-je le faire au mieux dans PowerShell?

136
Adrian Russell

Vous pouvez utiliser WMI ou d'autres outils à cet effet car il n'y a pas d'applet de commande Remove-Service jusqu'à Powershell 6.0 ( voir la documentation Remove-Service)

Par exemple:

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

Ou avec l'outil sc.exe:

sc.exe delete ServiceName

Enfin, si vous avez accès à PowerShell 6.0:

Remove-Service -Name ServiceName
204
ravikanth

Il n'y a pas de mal à utiliser le bon outil pour le travail que je trouve en cours d'exécution (de Powershell)

sc.exe \\server delete "MyService" 

la méthode la plus fiable qui n’a pas beaucoup de dépendances.

120
dcx

Si vous voulez juste vérifier l'existence du service:

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

J'ai utilisé la solution "-ErrorAction SilentlyContinue", mais j'ai ensuite rencontré le problème suivant: il y a un ErrorRecord. Alors, voici une autre solution pour simplement vérifier si le service existe en utilisant "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 

Mais ravikanth a la meilleure solution puisque Get-WmiObject ne génère pas d'erreur si le service n'existait pas. J'ai donc choisi d'utiliser:

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

Donc, pour offrir une solution plus complète:

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

Les versions les plus récentes de PS ont Remove-WmiObject. Attention, le silence échoue pour $ 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:\> 

Pour ma situation, je devais exécuter "en tant qu'administrateur"

12
Straff

Pour supprimer plusieurs services dans Powershell 5.0, car le service de suppression n'existe pas dans cette version

Exécuter la commande ci-dessous

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

On pourrait utiliser Where-Object

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

4
ShaneH

En combinant les réponses de Dmitri et dcx, j'ai formulé ceci:

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
Richard

Pour un seul 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 pour la liste des PC:

$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
Ivan Temchenko

Pour vérifier si un service Windows nommé MySuperServiceVersion1 existe, même si vous n'êtes pas sûr de son nom exact, vous pouvez utiliser un caractère générique, en utilisant une sous-chaîne comme ceci:

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

PowerShell Core ( v6 + ) a maintenant un Remove-Service cmdlet .

Je ne sais pas s'il est prévu de le transférer sur Windows PowerShell, où il est pas disponible à partir de la v5.1 .

Exemple:

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

Notez que l’appel échoue si le service n’existe pas. Vous ne pouvez donc le supprimer que s’il existe déjà:

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

Adapté pour prendre une liste d'entrées de serveurs, spécifier un nom d'hôte et donner une sortie utile

            $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)}
2
Gerald
  • Pour les versions de PowerShell antérieures à la v6, vous pouvez procéder comme suit:

    Stop-Service 'YourServiceName'; Get-CimInstance -ClassName Win32_Service -Filter "Name='YourServiceName'" | Remove-CimInstance
    
  • Pour la version 6 +, vous pouvez utiliser la cmdlet Remove-Service .

Notez que depuis Windows PowerShell 3.0, la cmdlet Get-WmiObject a été remplacée par Get-CimInstance.

2
Rosberg Linhares

Windows Powershell 6 aura la cmdlet Remove-Service . A partir de maintenant, la version Github montre PS v6 beta-9

Source: https://docs.Microsoft.com/en-us/powershell/module/Microsoft.powershell.management/remove- service? view = powershell-6

1
Gagan