Search code examples
powershellwmic

WMIC If / Else Statement for Software Version


I'm trying to use PowerShell to move install files, uninstall any previous version of the software, remove the install directories, and execute the BAT file.

My domain has finally updated and allowed WinRM to run on our machines, making patching much easier to facilitate remotely. I'm working my first script to do this involving updating Java. What I want to do is use PowerShell Studio to deploy a script, this script will kill all the tasks Java is attached to, use wmic to query the installed Java version and call for uninstall, and then Start-Process a BAT file which will do the install, and then clean itself up. What's happening is when I run into a machine with NO Java on it, I get "No Instance(s) Available".

Googling and looking around here, I can't seem to get my If / Else statement right and was looking for some help.

taskkill /F /IM iexplorer.exe
taskkill /F /IM chrome.exe
taskkill /F /IM outlook.exe

wmic product where "name like 'Java%%'" call uninstall /nointeractive

Start-Process -FilePath 'C:\Suppot\Java\java.bat' -Verb runas -Wait

RD /S /Q "C:\support\java"

What I would like to happen is to watch the machine update and install Java quietly in the background, refreshing Control Panel to verify in testing, that it works.

What happened is there was an error in the code, and the uninstall worked and it failed after that. On the next run, it now fails when it can't find a version of Java to remove.


Solution

  • The way your script is written is not very PoSh. Essentially you're just running batch code in PowerShell.

    For enumerating/killing processes use Get-Process:

    Get-Process -Name 'chrome', 'iexplore', 'outlook' | ForEach-Object { $_.Kill() }
    

    For querying WMI you'd use Get-WmiObject or Get-CimInstance (the latter is essentially a modernized version of the former) unless you're really pressed for performance. Then, and only then, you'd resort to wmic.

    However, for your particular task one wouldn't use WMI in the first place, because querying the Win32_Product class is considered harmful. Look up the uninstall string in the registry instead, split the string, and run it via Start-Process. Add the argument /qn to the parameter string for an unattended removal.

    $path = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
    Get-ChildItem $path | ForEach-Object {
        Get-ItemProperty -Path $_.PSPath | Where-Object {
            $_.DisplayName -like '*java*'
        } | ForEach-Object {
            $cmd, $params = $_.UninstallString -split ' ', 2
            Start-Process $cmd -ArgumentList "${params} /qn" -Wait
        }
    }
    

    Files and folders can be removed with Remove-Item:

    Remove-Item 'C:\support\java' -Recurse -Force