Author Posts

January 1, 2012 at 12:00 am

by the_ratzenator at 2013-04-30 23:51:01

I would like to have a script that uninstalls all software on a computer and offers a wait state during each uninstall and moves onto the next program to uninstall. How would I go about doing this? Thanks

by poshoholic at 2013-05-01 12:25:12

Initial thoughts that come to mind:
1. Enumerate installed programs by querying the Windows Registry.
2. For each installed program, identify the uninstall command (also from the Registry).
3. Invoke the uninstall command for each program, one at a time, using Start-Process with the -Wait parameter. Be careful to invoke the uninstall with whatever switches are required to make it silent. An alternative to using -Wait on Start-Process (which will wait forever), you could invoke Start-Process without wait, grab the process object it returns, and then go into a while loop while counting a timer, sleeping for 1 second every iteration, and make sure that you only wait a maximum of X seconds before you determine that the uninstall failed, reporting an error message to the user in this case.
4. Wrap it up in a script block and invoke it on a remote system using Invoke-Command.

Something like that should do the trick.

by the_ratzenator at 2013-05-02 00:28:35

Thanks Kirk

Here is some code I am trying to tweak that I got from powershellcommunity.com. I am stuck and need some help. Thanks

Function Get-UninstallString
{
< #
.SYNOPSYS
Get-Uninstall string provides the DisplayName, Publisher and UninstallString for all software listed in the registry

.DESCRIPTION
Get-Uninstall will query the x64 and x86 registry nodes in order to list out all installed software and there associated uninstall stings. By default information is displayed as a table in a custom PSObject.

.PARAMETER ComputerName

.EXAMPLE
Get-UninstallString

Product : VMware Tools
Company : VMware, Inc.
Computer : LABTOOLS
Uninstall : MsiExec.exe /X{44D55920-B223-4702-81D9-4C07108A3C27}
Version : 9.2.2.18018

Product : Microsoft Visual C++ 2008 Redistributable – x64 9.0.30729.6161
Company : Microsoft Corporation
Computer : LABTOOLS
Uninstall : MsiExec.exe /X{5FCE6D76-F5DC-37AB-B2B8-22AB8CEDB1D4}
Version : 9.0.30729.6161

Product : Microsoft Visual C++ 2008 Redistributable – x86 9.0.30729.4148
Company : Microsoft Corporation
Computer : LABTOOLS
Uninstall : MsiExec.exe /X{1F1C2DFC-2D24-3E06-BCB8-725134ADF989}
Version : 9.0.30729.4148

.EXAMPLE
Get-UninstallString | Format-Table

Product Company Computer Uninstall Version
——- ——- ——– ——— ——-
VMware Tools VMware, Inc. LABTOOLS MsiExec.exe /X{44D55920-... 9.2.2.18018
Microsoft Visual C++ 2008... Microsoft Corporation LABTOOLS MsiExec.exe /X{5FCE6D76-... 9.0.30729.6161
Microsoft Visual C++ 2008... Microsoft Corporation LABTOOLS MsiExec.exe /X{1F1C2DFC-... 9.0.30729.4148

.EXAMPLE
Get-content c:\servers.txt | Get-UninstallString

Gets the uninstallstring information for a list of computers specified in the file servers.txt

#>
[CmdletBinding()]
Param
(
[parameter(
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True
)][String[]]$ComputerName = $env:COMPUTERNAME
)
Begin
{
$param = @{ScriptBlock = {`
if ((Get-WmiObject win32_operatingsystem -ComputerName $ComputerName).OSArchitecture -notlike '64-bit') {$keys= (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*')}
else {$keys = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*','HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*')}
$Keys |
Where-Object {$_.Publisher -or $_.UninstallString -or $_.displayversion -or $_.DisplayName} |
ForEach-Object {
New-Object -TypeName PSObject -Property @{
Computer = $env:COMPUTERNAME
Company = $_.Publisher
Uninstall = $_.UninstallString
Version = $_.displayversion
Product = $_.DisplayName
}
}
}
}
}
Process
{
If (Test-Connection $ComputerName -Quiet -Count 2) {
If ($ComputerName -ne $env:COMPUTERNAME) {$param.Add("ComputerName",$ComputerName)}
Invoke-Command @param
}
Else { "The Computer, $ComputerName, is not online" }
}
End {}
}

#This is where I am stuck

$UninstallStr= (Get-UninstallString).Uninstall | Select-String "msiexec.exe /X"

Foreach ($Str in $UninstallStr)
{
Start-Process
}

by poshoholic at 2013-05-02 05:55:31

You should take an approach something like this instead:

foreach ($uninstallString in Get-UninstallString | Select-Object -ExpandProperty Uninstall) {
Write-Verbose $uninstallString # This line is optional, just added in case you want to troubleshoot with verbose messages. You could use Write-Debug instead since it's really more of a debugging thing.
# Now call start-process with the uninstall string information
}

by the_ratzenator at 2013-05-02 14:14:22

I will try that and get back with you Kirk. Thanks.

I can always ask if we can contract out, but I work in a large healthcare environment with one particular PowerShell guru located in another state and I would ask him, but he has a tendency of really pissing me off with his arrogant smartass mouth, so that is why I am here inquiring.