Monday 5 March 2018

PowerShell: Script to Uninstall MSI with Application Name.

We do face issues like multiple versions of same application got installed on the machine(e.g: Java,Visual C++). Created an Universal Uninstaller script, which is used to uninstall an MSI application with use of application name.

Script:
$Global:LogDir = $env:windir+"\logs"
$Global:gLogPath = $LogDir + "\" + "MSI Universal Uninstaller_Overview.log"
If (Test-Path -path $LogDir)
    {}
Else {
    #This system is not having logs folder. Hence creating it'
    New-Item -path $LogDir  -ItemType directory
    New-Item -path $LogPath -ItemType File
     }
Function Write-Log {
    Param(
        [string]$Message,
        [string]$Path,
        [string]$Level = "info"
    )

    if (-not $(Test-Path $path))
    {
        New-Item $path -Type File -ErrorAction SilentlyContinue >> $Log
    }
   
    if(Test-Path $path)
    {
        Switch -wildcard ($level) {
            'info'
            {
                Write-Output "[$level] : $(Get-Date) ----> $Message" | Format-Table -AutoSize | Out-File -FilePath $Path -Append
               
            }
            'warning'
            {
                Write-Output "[$level] : $(Get-Date) ----> $Message" | Format-Table -AutoSize | Out-File -FilePath $Path -Append
               
            }
            'error'
            {
                Write-Output "[$level] : $(Get-Date) ----> $Message" | Format-Table -AutoSize | Out-File -FilePath $Path -Append
               
            }
            default {}
        }
    }
}

$Log = $gLogPath
Write-Log -Path $Log -level "info" -message $("==============================================")

Function ReadMSI{
    Param($MSIName)
     
    If([string]::IsNullOrEmpty($MSIName))
    {
        Write-Log -Path $Log -level "info" -message $("Enter valid Application Name")
    }
    Else
    {
        uninst_MSI($MSIName)
    }
}

Function uninst_MSI($Ename)
{
Write-Log -Path $Log -level "info" -message $("Entered Application Name:$Ename")
$msi = Get-WmiObject -Class win32_product | ? {$_.Name -like "*$EName*"} | Select-Object Name,IdentifyingNumber,Version
$msi_search = $msi | Sort-Object Name | Out-GridView -Title "MSI Applications on $Env:COMPUTERNAME" -PassThru
If($msi)
{
    If($msi_search)
        {  
            Write-Log -Path $Log -level "info" -message $("Applications selected: ")
            $return = $msi_search | Select-Object Name,Version | Format-Table -HideTableHeaders -AutoSize | Out-String
            Write-Log -Path $Log -level "info" -message $("$return")
            $title = "Uninstall the following apps from $($ENV:computername)"
            $message = "You've selected the below apps for removal, do you wish to continue?:$return"
            $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Removes application(s) from $env:computername."
            $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Returns to application listing."
            $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
            $result = $host.ui.PromptForChoice($title, $message, $options, 0)

    If ($result -eq 0)
    {
    $msi_search|ForEach-Object{
    $Name=$_.Name
    $GUID=$_.IdentifyingNumber
    $Ver=$_.Version
    $Product1 = $Name+" "+$Ver
         
        $UNInstarguments = $LogDir + "\" + $Product1 + "_UNINST.log"
        $Global:arguments = " /x " + """$GUID""" + " /qb! REBOOT=ReallySuppress MSIRESTARTMANAGERCONTROL=Disable /L*V " + """$UNInstarguments"""
        Write-Log -Path $Log -level "info" -message $("Uninstalling the MSI..($Product1)..")
        $process = Start-Process -FilePath msiexec.exe -ArgumentList $arguments -Wait -PassThru
       
        if ($process.ExitCode -eq 0){
        Write-Log -Path $Log -level "info" -message $("($Product1)has been successfully uninstalled with ExitCode: $($process.ExitCode)")
        }
        elseif($process.ExitCode -eq 3010){
        Write-Log -Path $Log -level "info" -message $("($Product1)has been successfully uninstalled(REBOOT_REQUIRED) with ExitCode: $($process.ExitCode)")
        }
        else{
        Write-Log -Path $Log -level "info" -message $("($Product1)Uninstallation failed with ExitCode: $($process.ExitCode)")
        }
     }
     }
     Else{Write-Log -Path $Log -level "info" -message $("You have cancelled the uninstallation")}
     }
     Else
     {
     Write-Log -Path $Log -level "info" -message $("You have not selected any apps to unistall")
     }
     }
    Else
   {
   Write-Log -Path $Log -level "info" -message $("Application named like ($Ename)is not installed in the machine")
   }
}
  
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
$MSIName = [Microsoft.VisualBasic.Interaction]::InputBox("Enter Package Name", "MSI:Universal Remover", "")

ReadMSI $MSIName

Steps To DO:
1. Copy code and save the script as XXX.PS1
2. Set the execution policy to run the script.
3. Execute the script and you will get popup for application name. Enter the application name to uninstall and Click OK.

4. Will get list of installed applications like below.

5. Select the application you want to uninstall from above list and Click OK(For Multiple applications use Ctrl to select and proceed).
6. Will get confirmation to uninstall,Click on Yes.

7. Selected application is getting uninstalling(Alter the parameters in script to do silently).

8. Logs files get created under "C:\Windows\Logs"

9. Open the Overview log file to get the details of Exit code.

 

No comments:

Post a Comment