Existe-t-il un moyen simple de se connecter à la fonctionnalité standard « Ajouter ou supprimer des programmes » à l'aide de PowerShell pour désinstaller une application existante ? Ou pour vérifier si l'application est installée?
Existe-t-il un moyen simple de se connecter à la fonctionnalité standard « Ajouter ou supprimer des programmes » à l'aide de PowerShell pour désinstaller une application existante ? Ou pour vérifier si l'application est installée?
Réponses:
$app = Get-WmiObject -Class Win32_Product | Where-Object {
$_.Name -match "Software Name"
}
$app.Uninstall()
Edit: Rob a trouvé un autre moyen de le faire avec le paramètre Filter:
$app = Get-WmiObject -Class Win32_Product `
-Filter "Name = 'Software Name'"
(gwmi Win32_Product | ? Name -eq "Software").uninstall()
Un peu de golf codé.
EDIT: Au fil des ans, cette réponse a reçu un certain nombre de votes positifs. Je voudrais ajouter quelques commentaires. Je n'ai pas utilisé PowerShell depuis, mais je me souviens avoir observé quelques problèmes:
-First 1
mais je ne suis pas sûr. N'hésitez pas à modifier.L'utilisation de l'objet WMI prend une éternité. C'est très rapide si vous connaissez simplement le nom du programme que vous souhaitez désinstaller.
$uninstall32 = gci "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match "SOFTWARE NAME" } | select UninstallString
$uninstall64 = gci "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match "SOFTWARE NAME" } | select UninstallString
if ($uninstall64) {
$uninstall64 = $uninstall64.UninstallString -Replace "msiexec.exe","" -Replace "/I","" -Replace "/X",""
$uninstall64 = $uninstall64.Trim()
Write "Uninstalling..."
start-process "msiexec.exe" -arg "/X $uninstall64 /qb" -Wait}
if ($uninstall32) {
$uninstall32 = $uninstall32.UninstallString -Replace "msiexec.exe","" -Replace "/I","" -Replace "/X",""
$uninstall32 = $uninstall32.Trim()
Write "Uninstalling..."
start-process "msiexec.exe" -arg "/X $uninstall32 /qb" -Wait}
-like "appNam*"
puisque la version est dans le nom et qu'elle change, mais il ne semble pas trouver le programme. Des idées?
Pour corriger la deuxième méthode dans l'article de Jeff Hillman, vous pouvez soit faire un:
$app = Get-WmiObject
-Query "SELECT * FROM Win32_Product WHERE Name = 'Software Name'"
Ou
$app = Get-WmiObject -Class Win32_Product `
-Filter "Name = 'Software Name'"
J'ai découvert que la classe Win32_Product n'est pas recommandée car elle déclenche des réparations et n'est pas optimisée pour la requête. La source
J'ai trouvé ce post de Sitaram Pamarthi avec un script à désinstaller si vous connaissez l'application guid. Il fournit également un autre script pour rechercher des applications très rapidement ici .
Utilisez comme ceci:. \ Uninstall.ps1 -GUID {C9E7751E-88ED-36CF-B610-71A1D262E906}
[cmdletbinding()]
param (
[parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[string]$ComputerName = $env:computername,
[parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Mandatory=$true)]
[string]$AppGUID
)
try {
$returnval = ([WMICLASS]"\\$computerName\ROOT\CIMV2:win32_process").Create("msiexec `/x$AppGUID `/norestart `/qn")
} catch {
write-error "Failed to trigger the uninstallation. Review the error message"
$_
exit
}
switch ($($returnval.returnvalue)){
0 { "Uninstallation command triggered successfully" }
2 { "You don't have sufficient permissions to trigger the command on $Computer" }
3 { "You don't have sufficient permissions to trigger the command on $Computer" }
8 { "An unknown error has occurred" }
9 { "Path Not Found" }
9 { "Invalid Parameter"}
}
Pour ajouter un peu à cet article, je devais être capable de supprimer des logiciels de plusieurs serveurs. J'ai utilisé la réponse de Jeff pour m'amener à ceci:
J'ai d'abord eu une liste de serveurs, j'ai utilisé une requête AD , mais vous pouvez fournir le tableau de noms d'ordinateurs comme vous le souhaitez:
$computers = @("computer1", "computer2", "computer3")
Ensuite, je les ai parcourus, en ajoutant le paramètre -computer à la requête gwmi:
foreach($server in $computers){
$app = Get-WmiObject -Class Win32_Product -computer $server | Where-Object {
$_.IdentifyingNumber -match "5A5F312145AE-0252130-432C34-9D89-1"
}
$app.Uninstall()
}
J'ai utilisé la propriété IdentifyingNumber pour faire correspondre au lieu du nom, juste pour être sûr de désinstaller la bonne application.
function Uninstall-App {
Write-Output "Uninstalling $($args[0])"
foreach($obj in Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall") {
$dname = $obj.GetValue("DisplayName")
if ($dname -contains $args[0]) {
$uninstString = $obj.GetValue("UninstallString")
foreach ($line in $uninstString) {
$found = $line -match '(\{.+\}).*'
If ($found) {
$appid = $matches[1]
Write-Output $appid
start-process "msiexec.exe" -arg "/X $appid /qb" -Wait
}
}
}
}
}
Appelez-le ainsi:
Uninstall-App "Autodesk Revit DB Link 2019"
Une ligne de code:
get-package *notepad* |% { & $_.Meta.Attributes["UninstallString"]}
Je ferai ma propre petite contribution. J'avais besoin de supprimer une liste de paquets du même ordinateur. C'est le script que j'ai imaginé.
$packages = @("package1", "package2", "package3")
foreach($package in $packages){
$app = Get-WmiObject -Class Win32_Product | Where-Object {
$_.Name -match "$package"
}
$app.Uninstall()
}
J'espère que cela se révélera utile.
Notez que je dois à David Stetler le mérite de ce script car il est basé sur le sien.
Voici le script PowerShell utilisant msiexec:
echo "Getting product code"
$ProductCode = Get-WmiObject win32_product -Filter "Name='Name of my Software in Add Remove Program Window'" | Select-Object -Expand IdentifyingNumber
echo "removing Product"
# Out-Null argument is just for keeping the power shell command window waiting for msiexec command to finish else it moves to execute the next echo command
& msiexec /x $ProductCode | Out-Null
echo "uninstallation finished"
Basé sur la réponse de Jeff Hillman:
Voici une fonction que vous pouvez simplement ajouter à votre profile.ps1
ou définir dans la session PowerShell actuelle:
# Uninstall a Windows program
function uninstall($programName)
{
$app = Get-WmiObject -Class Win32_Product -Filter ("Name = '" + $programName + "'")
if($app -ne $null)
{
$app.Uninstall()
}
else {
echo ("Could not find program '" + $programName + "'")
}
}
Disons que vous vouliez désinstaller Notepad ++ . Tapez simplement ceci dans PowerShell:
> uninstall("notepad++")
Sachez simplement que cela Get-WmiObject
peut prendre du temps, alors soyez patient!
Utilisation:
function remove-HSsoftware{
[cmdletbinding()]
param(
[parameter(Mandatory=$true,
ValuefromPipeline = $true,
HelpMessage="IdentifyingNumber can be retrieved with `"get-wmiobject -class win32_product`"")]
[ValidatePattern('{[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}}')]
[string[]]$ids,
[parameter(Mandatory=$false,
ValuefromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
HelpMessage="Computer name or IP adress to query via WMI")]
[Alias('hostname,CN,computername')]
[string[]]$computers
)
begin {}
process{
if($computers -eq $null){
$computers = Get-ADComputer -Filter * | Select dnshostname |%{$_.dnshostname}
}
foreach($computer in $computers){
foreach($id in $ids){
write-host "Trying to uninstall sofware with ID ", "$id", "from computer ", "$computer"
$app = Get-WmiObject -class Win32_Product -Computername "$computer" -Filter "IdentifyingNumber = '$id'"
$app | Remove-WmiObject
}
}
}
end{}}
remove-hssoftware -ids "{8C299CF3-E529-414E-AKD8-68C23BA4CBE8}","{5A9C53A5-FF48-497D-AB86-1F6418B569B9}","{62092246-CFA2-4452-BEDB-62AC4BCE6C26}"
Il n'est pas entièrement testé, mais il a fonctionné sous PowerShell 4.
J'ai exécuté le fichier PS1 tel qu'il est vu ici. Laisser récupérer tous les systèmes de l' AD et essayer de désinstaller plusieurs applications sur tous les systèmes.
J'ai utilisé le IdentifyingNumber pour rechercher la cause logicielle de l'entrée de David Stetlers.
Pas testé:
Ce qu'il ne fait pas:
Je n'ai pas pu utiliser uninstall (). Essayer que j'ai eu une erreur me disant que l'appel d'une méthode pour une expression qui a une valeur NULL n'est pas possible. Au lieu de cela, j'ai utilisé Remove-WmiObject, qui semble accomplir la même chose.
PRÉCAUTION : Sans nom d'ordinateur donné, il supprime le logiciel de TOUS les systèmes dans Active Directory.
Pour la plupart de mes programmes, les scripts de cet article ont fait le travail. Mais j'ai dû faire face à un programme hérité que je ne pouvais pas supprimer en utilisant la classe msiexec.exe ou Win32_Product. (pour une raison quelconque, j'ai obtenu la sortie 0 mais le programme était toujours là)
Ma solution était d'utiliser la classe Win32_Process:
avec l'aide de nickdnk, cette commande consiste à obtenir le chemin du fichier de désinstallation exe:
64 bits:
[array]$unInstallPathReg= gci "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match $programName } | select UninstallString
32 bits:
[array]$unInstallPathReg= gci "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match $programName } | select UninstallString
vous devrez nettoyer la chaîne de résultat:
$uninstallPath = $unInstallPathReg[0].UninstallString
$uninstallPath = $uninstallPath -Replace "msiexec.exe","" -Replace "/I","" -Replace "/X",""
$uninstallPath = $uninstallPath .Trim()
maintenant, lorsque vous avez le chemin du fichier exe de désinstallation du programme approprié , vous pouvez utiliser cette commande:
$uninstallResult = (Get-WMIObject -List -Verbose | Where-Object {$_.Name -eq "Win32_Process"}).InvokeMethod("Create","$unInstallPath")
$ uninstallResult - aura le code de sortie. 0 est le succès
les commandes ci-dessus peuvent également s'exécuter à distance - je l'ai fait en utilisant la commande invoke mais je crois que l'ajout de l'argument -computername peut fonctionner