PowerShell Problem Solver: Finding Installed Software Using CIM Cmdlets

Posted on December 10, 2014 by Jeff Hicks in PowerShell with 0 Comments

Over the last several articles I’ve been guiding you on how to discover what applications might be installed. In the previous article in this series I demonstrated how to use WMI to query the registry on remote computers, where I specifically showed you how to use StdRegProv. One of the drawbacks is that this uses legacy technology and requires DCOM, which means it is not very firewall friendly.

There is also no provision for alternate credentials like there is with the Get-WMIObject cmdlet. Although you can get around that using PowerShell remoting and Invoke-Command, then you might as well use the CIM cmdlets. With CIM, we get an easy way to provide alternate credentials and also eliminate DCOM and RPC from the picture.

The first step is to create a CIM session to the remote computer. If you need to use alternate credentials, this is where you would do so.

Even though we will be using CIM, we are still accessing the same StdRegProv provider, so we still need to provide the appropriate hive values and paths.

For now I’m going to search the Uninstall key under HKLM.

Next we’ll create an object for StdRedProv using Get-CimClass. Remember, StdRegProv is not something with instances. We will be using the class’s methods directly.

To query, we will use the EnumKey() method that requires a few parameters. If you have been following the article series, then these will look familiar. Let me quickly show you how to discover them. The $regcim object includes definitions of all the class methods.

Using the $regcim object to find definitions of all the class methods in Windows PowerShell. (Image Credit: Jeff Hicks)

Using the $regcim object to find definitions of all the class methods in Windows PowerShell. (Image Credit: Jeff Hicks)

Let’s narrow the focus to EnumKey().

Looking at parameters for EnumKey() in Windows PowerShell. (Image Credit: Jeff Hicks)

Looking at parameters for EnumKey() in Windows PowerShell. (Image Credit: Jeff Hicks)

The “IN” parameters are what we need. We will be using Invoke-CimMethod, so all we need to do is define a hashtable of the necessary parameters and their values.

To make the Invoke-CimMethod expression easier to read, I’m going to create a hashtable of parameters to splat to the cmdlet.

Essentially I’m going to invoke EnumKey with my arguments on the StdRegProv object using the remote CIMSession. I know that the method is going to write an array of strings called sNames that I’ll expand, which should give me the names of each entry under Uninstall.

Writing an array of strings called sNames in Windows PowerShell. (Image Credit: Jeff Hicks)

Writing an array of strings called sNames in Windows PowerShell. (Image Credit: Jeff Hicks)

Once I know the name of the subkey, then I can get its values. In turn, I can grab the string value of the properties I am interested in. Here’s a version of code that will also filter out the Microsoft Office updates.

Essentially there is an iterative process here of enumerating the sNames, the values, and their actual data. This requires different methods and parameters, but by splatting my code, it stays relatively simple, as all I have to do is update the Invoke-Command parameters that have changed.

Updating Invoke-Command parameters that have changed. (Image Credit: Jeff Hicks)

Updating Invoke-Command parameters that have changed. (Image Credit: Jeff Hicks)

On x64 systems I might also want to check this path:

Sponsored

Re-running my code provides this result:

The Out-GridView dialog box. (Image Credit: Jeff Hicks)

The Out-GridView dialog box. (Image Credit: Jeff Hicks)

Finally, let’s check for user specific applications using CIM. The concepts are the same as what I used with WMI in the previous article, except I’m going to use CIM methods to enumerate keys and values.

One step I had to do differently was to resolve the SID name.

You can’t query the Win32_SID class with a filter, and I have yet to find any way to specify the WMI path to the specific SID instance. Instead I use Get-WSManInstance, which allows me to specify a WMI path. Here’s my final result:

Specifying a WMI path. (Image Credit: Jeff Hicks)

Specifying a WMI path. (Image Credit: Jeff Hicks)

Querying the registry with either WMI or CIM is certainly not a beginning PowerShell topic and in terms of identifying applications, it still may not be the most foolproof way to identify applications. But this solution may be enough. I will leave you with a script that uses CIM to pull everything together that I have shown you.

Sponsored

You can run it like this:

The results of the CMI-based script. (Image Credit: Jeff Hicks)

The results of the CMI-based script. (Image Credit: Jeff Hicks)

Hopefully I’ve given you enough information to build the tools you need to discover what applications are installed using PowerShell. If you run into issues or have follow up questions, feel free to leave a comment or post in the PowerShell forum here on the site.

Sponsored

Tagged with , ,