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?
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
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.
Si vous voulez juste vérifier l'existence du service:
if (Get-Service "My Service" -ErrorAction SilentlyContinue)
{
"service exists"
}
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
}
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"
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}
On pourrait utiliser Where-Object
if ((Get-Service | Where-Object {$_.Name -eq $serviceName}).length -eq 1) { "Service Exists" }
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
}
}
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."}
}
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
}
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
}
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)}
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.
Windows Powershell 6 aura la cmdlet Remove-Service . A partir de maintenant, la version Github montre PS v6 beta-9