PowerShell: Uninstall programs on a remote PC

Today I wanted to roll out Microsoft Office 2010 to a few clients but I needed to get rid of old Office installations on these systems because those could lead to problems while installing the new version. Instead of uninstalling them manually I wrote the following short PowerShell script UninstallOffice.ps1 for the task, which takes a computer name as its only parameter.

Param($pc = ""); if ($pc -eq "") { write-host ("Usage: UninstallOffice.ps1 PC") -foregroundcolor "red"; exit; } $programsToUninstall = @( "Microsoft Office Word Viewer 2003", "Microsoft Office Excel Viewer 2003", "Microsoft Office PowerPoint Viewer 2003", "Microsoft Office Visio Viewer 2003 (Deutsch)", "Microsoft Office XP Professional", "Microsoft Office Standard Edition 2003", "Microsoft Office Professional Edition 2003", "Microsoft Office Professional Plus 2007" ); $products = get-wmiobject -class "Win32_Product" -namespace "root\CIMV2" -ComputerName $pc; if ($products.length -gt 0) { $products | % { if ($programsToUninstall -contains $_.caption) { write-host ("Uninstalling " + $_.caption + " on " + $pc) -foregroundcolor "red"; $_.uninstall(); } }; }

You could replace the array $programsToUninstall with a list of the programs you would like to uninstall. The following snippet gives you a list of the installed programs’ names you could use in the array.
get-wmiobject -class "Win32_Product" -namespace "root\CIMV2" -ComputerName $pc | select caption

Update: If you get an error message when trying to uninstall the software, you may want to install this hotfix from Microsoft: Error message when you query Win32_Product class after you install applications by using Microsoft Windows Installer (MSI) 4.5 with “Per-User” option in Windows XP: “0x80041001 – Generic failure”.

Über Stefan

Polyglot Clean Code Developer

4 Kommentare

  1. Ich bin in einer ähnlichen Situation und hoffe du hast evtl. die korrekte Syntax bzw. ein funktionierendes Skript.

    Ich möchte alle Softwareprodukte, die den Namen soft123 enthalten von allen PCs deinstallieren, die pc im Computernamen haben (soft123 v.1.0, soft123 2 deinstallieren von pc01, pc02 usw.).

    Würde mich freuen wenn du mir weiterhelfen kannst. Habe es schon in div. Foren versucht aber bislang ohne Erfolg.

  2. Hallo Thomas. Das sollte kein großes Problem darstellen. Die PCs kannst du z.B. mit diesem Script ermitteln: Active Directory mit der PowerShell auslesen. Die Einschränkung auf pc im Namen sollte recht einfach sein. Dann musst du nur noch das obige Script leicht anpassen, z.B. aus Zeile 24 das hier machen:
    if ($_.caption -match “soft123”)

  3. $pcNameMustMatch = "pc145";
    $programNameMustMatch = "soft123";
    
    function GetComputersFromLDAP()
    {
    	trap
    	{
    		write-host ("Error while retrieving computers from LDAP: " + $_.exception.message) -foregroundcolor "red";
    		return $false;
    	}
    	$pcs = @();
    	$ldapSearcher = new-object directoryservices.directorysearcher;
    	$ldapSearcher.filter = "(objectclass=computer)";
    	$computers = $ldapSearcher.findall();
    	foreach ($computer in $computers)
    	{
    		$pc = "" | select-object Name;
    		$pc.Name = $computer.properties["name"];
    		$pcs += $pc;
    	}
    	return ($pcs | sort-object Name);
    }
    
    $pcs = GetComputersFromLDAP;
    foreach ($pc in $pcs)
    {
    	write-host "found computer" $pc.Name;
    	if ($pc.Name -notmatch $pcNameMustMatch)
    	{
    		write-host ("  -> name does not match " + $pcNameMustMatch) -foregroundcolor "red";
    		continue;
    	}
    
    	write-host ("  -> name matches " + $pcNameMustMatch) -foregroundcolor "green";
    	write-host ("  -> searching for installed software");
    	
    	$products = get-wmiobject -class "Win32_Product" -namespace "root\CIMV2" -ComputerName $pc.Name;
    	if ($products.length -gt 0)
    	{
    		$products | % {
    			if ($_.caption -match $programNameMustMatch)
    			{
    				write-host ("  -> uninstalling " + $_.caption + " on " + $pc.Name) -foregroundcolor "yellow";
    				#$_.uninstall(); # uncomment this line if you really want to uninstall the software!
    			}
    		};
    	}
    	else
    	{
    		write-host ("  -> no software found on" + $pc.Name) -foregroundcolor "red";
    	}
    
    }
  4. Hey Stefan,

    danke für die guten Skripte. Mitlerweile bin ich auch bei Powershell angelangt und bin durch eine Suche (mal wieder) auf deinen Blog gestoßen 😉

    Gruß

    Markus

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax