How to get a list of COM objects via WMI & PowerShell

Let’s see what WMI can tell us about COM objects on the system.

Get a list of all WMI classes with the word “COM” in them (doing a case sensitive match to avoid entries like “computer”).

Win32_COMApplication gives me about 386 results. It includes the AppID of the application associated with the COM object.

I am not a programmer so I won’t be going further into AppIDs and such, but it’s worth knowing about this and related COM terminology so here’s a quick rundown:

  1. All COM objects have a CLSID which is basically a 128-bit hexadecimal Globally Unique IDentifier (GUID) for the COM object. This way COM objects can be referred to independent of their installation path. The CLSID is unique across network computers too (relevant, when used with DCOM).

    WMI objects refer to this as ComponentID. They can also be found in the registry under HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID. For example, the CLSID for WordPad is {73FDDC80-AEA9-101A-98A7-00AA00374959}

  2. CLSIDs are not easy to remember, and sometimes COM objects with different CLSIDs can be used interchangeably (for instance: different versions of Internet Explorer will have different CLSIDs but you need some way of referring to the Internet Explorer COM object such that whatever version is installed on the system is used). For this reason you have ProgIDs (Programmatic IDentifier).

    ProgIDs can be found in the registry under HKEY_LOCAL_MACHINE\SOFTWARE\Classes. The format of a ProgID is <Program>.<Component>.<Version>, separated by periods and with no spaces. For example, the ProgID for WordPad is WordPad.Document.1.

    PowerShell’s New-Object cmdlet uses ProgID when creating new objects that refer to COM objects so ProgIDs are relevant to us.

  3. While not relevant to the current topic, there’s also an AppID which is yet another 128-bit hexadecimal GUID. You can read more about it here.

Now let’s get a list of how many objects are returned by each WMI class.

The biggest results are from the Win32_COMSetting class. Let’s compare the results of this with the Win32_ClassicCOMClassSetting class (which has the second largest number of results) to see what’s different. Since the ProgID property is what’s relevant to PowerShell, let’s filter the results to objects where ProgID is not $null.

There’s no difference. So in terms of ProgID both classes contain the same number of objects. Now let’s recreate the above table to only consider results where ProgID is not $null.

The interesting thing to note is that all the other classes have 0 objects now. In fact, we can see that the number of objects returned by the Win32_COMSetting class is equal to the number returned by Win32_ClassicCOMClassSetting plus Win32_COMApplication or Win32_DCOMApplication or Win32_DCOMApplicationSetting or Win32_COMApplicationSettings. Something to investigate later?

So, the best way to get COM objects via WMI & PowerShell is to use the Win32_COMSetting class. And to get the ProgID or any application (such as Internet Explorer in the previous post) something along the following lines will do:

If there’s only one version, the version number can be skipped in ProgID which is why InternetExplorer.Application too works.

Update: In fact, only the Win32_COMSetting and Win32_ClassicCOMClassSetting classes contain ProgID in their output. So these are the only two classes one can use. And since the only difference them is that Win32_COMSetting contains objects without any ProgID (of no use in our case!) it’s ok to use either class.

Update2: Turns out WMI is not a good way to get the list of COM objects. A better approach is to query the registry. See my next post.