A quick update today that version 1.0.1 of my Powershell script and module for uninstalling Java has been released.

One fix and one update are in this version. The fix is for the detection of running Java processes which weren’t triggering the while loop to wait and/or kill before uninstalling Java. The update was to update the query string to pick up Java 8 installations.


I still need to put together a more robust testing process, right now my thoughts are to use Teamcity and Pester to run up VM’s and do automated testing against all the permutations that are now possible.


Managing Configuration Drift

Posted: October 7, 2014 in Uncategorized

Much has been written on the rise of the devops culture and the use of configuration as code tools such as Chef. Puppet and DSC.

However once you have your infrastructure configuration built as code and deployed, how do you validate that it is actually being applied as expected?

Once you have more than a handful of nodes and multiple roles you can’t easily just manually log on to the servers and check. (Not to mention this is totally counter intuitive in the pets vs cattle approach to infrastructure management)

I’ve run into a tool from a start up called Scriptrock called Guardrail. It’s whole reason for existing is to solve the problem of validating deployed configuration. It takes the philosophy that you can’t rely on the police to police themselves. If Chef or DSC says it applied the config can you be sure it actually did?

Guardrail also can take a config policy and scaffold out a Chef, puppet or DSC configuration to speed up automating deployments.

I wholeheartedly recommend checking not out. They have a basic hosted trial option that allows for a rapid POC.

Today I’ve released what I’m considering a 1.0 release of the Uninstall-Java Powershell script and Module code.

I’ve performed some testing of both the script and module on Windows 7, 8 and 8.1 and the code seems to be stable and clean. As always I highly recommend testing in your environment.

This project started after the furor over major security bugs in Java and now has developed into a full project aimed at simplifying the management of Java versions in large environments by ensuring wither java is not installed or only the approved version is deployed. Previous articles (here and here) I wrote go into some of the detail and the development progress is tracked in some of the comments.

In the process I started my first Codeplex project as a way to distribute the code. There was a bit of a learning curve in using Codeplex and Git and along with some character encoding issues led to code being available which didn’t run when downloaded from Codeplex. These have been fixed (sorry to anyone who tried to use the damaged code) and is now available from the Codeplex project download page at https://poshuninstalljava.codeplex.com.

I’d appreciate any feedback or results of any testing that any of you do, either on the Codeplex project site or as a comment against this post. Documentation should be sufficient for anyone with basic Powershell knowledge and as time allows I’ll try and improve both the documentation in Codeplex and within the code itself.

I’ve hit upon the following bug in what should have been a simple DNS search server change. Initially we thought this was due to us using a method in the Win32_networkconnection WMI class to change the DNS search servers list but apparently this will occur if you completely change the DNS servers in the list via the gui.

If you change the dns search server list completely then reboot the server then the server will trigger the original DNS servers to remove the A record for that server and then on restart attempt to register itself with the new DNS servers configured. This leads to an issue if both the orginal and new DNS servers are part of the same replicated AD DNS zone. The time between the two events means that the new DNS servers may still have the orginal A record listed and will reject the servers attempt to re register. Then the deletion replicates and the record is removed leaving you with a server with no A record in the zone.

The current workaround is to use the ipconfig /registerdns command twice, with a time gap between the two issued commands to ensure the deletion is replicated to the new DNS servers before registering again. Having a reasonably long TTl on the record will improve your odds of DNS client cache retaining the IP of that server while you apply the commands.


I ran into this post whilst browsing Powershell.Org, for useful tidbits for improving my Powershell skills. If you’re starting to write modules or functions, then you have probably started to think about validating inputs. For a few modules I wrote big chunks of code to try and catch invalid inputs. Now, having read the following article, I have slapped myself silly for not finding out about Powershell’s validation capabilities earlier..


I’ve come to realise with Powershell that if  something seems complicated then you’re probably doing it wrong.

Uninstall Java using Powershell and WMI either as a script or module with options to keep a specified version installed and optional list the versions installed.

UPDATE: 1.0 Released, see post here

Download from here if you don’t want to read on: https://poshuninstalljava.codeplex.com

I’ve had a couple of comments from my previous post on uninstalling Java with Powershell. They have been in regards to either enhancing the WMI query or leaving a particular Java version installed. That has spurred me on to rewrite the script in a more complete form and include some optional arguments.

The new script is written as a Powershell module (you’ll see the psm1 extension on the file) so the module will have to be loaded and then called just like a normal cmdlet. There’s lots of info on the web about how to use modules, so I won’t repeat that here, but to quickly load the module use “ipmo .\uninstall-java.psm1” from Powershell.

The cmdlet has two optional arguments:

-KeepVersionJava version number” will uninstall all other versions of Java except the versions that match the string provided. Using “7.0.51” will retain Java version 7 Update 51, for example. Note that this switch does a match on the start of the version string, so passing “7” will keep all updates of the major version 7 whilst uninstalling versions 6 and 5.

-Whatif will flag the cmdlet to not uninstall any software but will output (as an object from WMI) all the software that matches the query that would be uninstalled if the switch was not used. This can also be used to get a list of all versions of Java that are installed as a series of objects that can be piped to other powershell commands or to a text file.

In either mode the cmdlet outputs the results as an array of WMI objects which can be piped into other commands.

I’ve included in the WMI query a set of additional product name matches supplied by a commenter “Carsten” which excludes a number of non Oracle software packages that otherwise would have been accidentally triggered by the cmdlet. There is a line early in the module which sets the base query string which reads something like:

$query=“select * from win32_Product where (Name like ‘Java %’ or Name like ‘Java(TM)%’ or Name like ‘J2SE%’) and (Name <> ‘Java Auto Updater’) and ((Vendor=’Sun Microsystems, Inc.’) or (Vendor=’Oracle’)) and (NOT Name like ‘%CompuGROUP%’) and (NOT Name like ‘%IBM%’) and (NOT Name like ‘%DB%’) and (NOT Name like ‘%Advanced Imaging%’) and (NOT Name like ‘%Media Framework%’) and (NOT Name like ‘%SDK%’) and (NOT Name like ‘%Development Kit%’)“

This is where you can add any other possible strings to exclude from the un-installation process.

A final word of warning. This module was written as a quick way of screening and removing Java from computers in an environment where there hasn’t been a lot of control in terms of software distribution. As you’ll see from the changes to the WMI query, there are a number of software packages that could have been accidentally removed because of the broad query used. I suggest you run the cmdlet with the -Whatif switch and capture the output for review before running properly.

UPDATE: The Win32_Product WMI class will cause the MSI Installer service to scan through all installed applications and generate a number of events (ID 1035) but otherwise does not seem to cause major issues. The Microsoft KB articel is here: http://support.microsoft.com/kb/974524/en-us. There is no way to avoid this and using the Win32_AddRemovePrograms class offers no uninstall() method. For the time being if you want to use this script then I would avoid using it as a login script or s start up script which may slow down login times..

You can download the file from the Codeplex project I’ve started : https://poshuninstalljava.codeplex.com

EDIT: There is now a ps1 version to provide the same functionality but as a script rather than a full module for those who may want to remotely launch or embed in something like SCCM or Group Policy.

Much has been posted in regards to Java and how to uninstall it. A lot of scripts rely on knowing every product GUID in the registry and calling msiexec for each GUID to rid yourself of Java. After a bit of research I came up with the following approach using Powershell and WMI that avoids needing to know every GUID.

It uses a WMI query to find any product names that match specific strings. You’ll see in the code I look for ‘Java %’, with a space as there are lots of visual studio add ins that refer to “javascript”. I also look for ‘Java(TM)%’ as the JRE 6 runtime uses this specific string in it’s name. I also put into the query a filter to exclude Java Auto Updater which will be removed by the main program uninstaller and if called directly throws a 1603 return code.

I have also added a check to find any running Java processes. This is necessary as if you call the Uninstall() method, with Java processes running, the computer will reboot immediately on uninstall, without any warning.

The final part of the script will loop through the installed programs and call the Uninstall() method on each one. I plan to add a check to the script to verify that the program has an uninstall method, as some programs don’t have this method.

A word of warning that this has only been tested in my environment and I give no guarantee that this script will work correctly in your environment or won’t cause any unexpected results. You should test this script in your environment properly before use.

EDIT: I’ve updated the script to provide some more functionality and parameters in line with the Powershell Module version in a later post. I suggest you read the later post. The code is now hosted as a codeplex project to make any future changes easier to manage. Link is below.