In response to this forum post:

I cobbled together a VERY rough approximation of a powershell script + mof edit that MIGHT work to gather the bare minimum information.

Download the files in the -->  Attached Zip File <-- In the .zip file are two files

TestScript1.ps1  -- this is a powershell script you will need to have every ConfigMgr client you have run, presumably the ones with Google Chrome installed.  You can either deploy it as a recurring advertisement, or my favorite is to create a "Configuration Item", and deploy the script that way on a recurring basis.

ToBeImported.mof -- Once  you've had test workstations run that powershell script, AND you've confirmed that data appears on those test workstations' root\cimv2\cm_chromeExtensions, AND that data appears to be stuff you find interesting, THEN in your CM Console, Administration, Client Settings, Default Client Settings, Hardware Inventory, Import... this file.

"let the buyer beware":  Read the .ps1 file--especially the top section.  the part where the author (ok, it was me) said that this was all cobbled together and is probably useless. 

1) 1 thing I noticed even with only 15 minutes worth of testing...I uninstalled Google Chrome from the test workstation.  That does NOT clear out the user profile appdata folders where "chrome extensions" are listed.  So everything was still reported.  So it is highly likely, in fact probably guaranteed, that this will in no way EVER be indicative of "Google Chrome is actually installed and working".  It's indicative of "Google Chrome was installed once and launched once for this user--sometime during the life of the computer".  It could have been installed and uninstalled within 30 minutes and never used again--but the user profile information about chrome extensions will be there.  Forever.  Welcome to user-centric nightmares (if you weren't already aware of them).  Also by the way, chrome apparently comes pre-packaged with multiple extensions so no matter what you'll have entries if any user ever launched Chrome on that workstation--even if it was immediately uninstalled.  It won't matter.

so my recommendation is *if* you think in your weeks of testing that this might be useful in some way--in reporting you will need to be extremely careful to tie the reports about chrome extensions to machines which clearly indicate that chrome is actually installed.  Or, of course--feel free to re-write this chrome extensions script to detect that before recording anything.

2) There were some extensions in the user profile folder for chrome extensions for which I couldn't figure out any way to clearly identify what it was.  Those will be labeled unknown.  You are certainly welcome to edit the script if you know how to identify those.

3) No promises of usefulness or compatibility or even functionality are implied.  I'm just tossing this out there in the hopes that someone else can make it work better.  If in fact anyone even cares about Chrome extensions. Ever.

fyi, in testing, I got this type of information on the test box:


 Counter   Name Version ProfilePath ScriptLastRan
 0 Google Docs 0.9 c:\users\fakeuser 3/28/2016 4:55:13 PM
 1 Google Drive 14.1 c:\users\fakeuser 3/28/2016 4:55:13 PM
 2  YouTube 4.2.8  c:\users\fakeuser  3/28/2016 4:55:13 PM
 ...  <more data>      3/28/2016 4:55:13 PM
 14  iHeartRadio 1.1.0 c:\users\anotheruser  3/28/2016 4:55:14 PM

In the above example, "fakeuser" used Chrome and never added any CUSTOM or additional extensions.  "anotheruser" using the same computer did add a custom extension for iHeartRadio.

As mentioned, only tested in a distracted way in a test environment on 1 test workstation in a lab.  This is probably horrible code, a horrible idea, and will need to be re-written from scratch.  Or.... it just might work fine.  <shrug>

This is an update to this older blog:

Nash Pherson, Enterprise Client Management MVP, pointed out that for versions 4.5x and higher Microsoft is recommending using the dword registry key called "release" to better pinpoint what version of .net is installed. Because "buildNumber" in the registry will say something like "4.5.51209"--but what it MEANS is that's version 4.5.2 (don't ask me why, I don't get it either).

Unfortunately, "Release" also isn't in nice, plain English. I couldn't find anything "easy" to make using BuildNumber any more or less useful than using "Release" number. But if you want to do exactly what Microsoft tells you to use, attached are updated mof edits for reporting on .net versions. The only thing added to this is "release"; which is only applicable to .net 4.5 and higher (well, up to 4.6.1 as far as I can tell; maybe it'll still be there in newer versions as those are released, but for now, that's all I can see)

If you already have the DotNetFramework edits, you replace your existing snippet for DotNetFrameworks in your configuration.mof with the configuration.mof edit in --> This Zip File <--   If you've never edited your \inboxes\clifiles.src\hinv\configuration.mof for dotNetFrameworks yet, you will add that attached snippet to the bottom of that file. Monitor your 'dataldr.log' to confirm all is well.

Once configuration.mof is edited, you take the attached "to-be-imported-dot-net.mof" and in your CM console, Administration, Client Settings, right-click on "Default Client Settings", Properties, Hardware Inventory, "Set Classes..." then Import that to-be-imported-dot-net.mof file. If you already have one from previously, not to worry. It'll just accept the new one and modify your tables and views. Just monitor your dataldr.log to confirm all is well.
Then, of course, it's the typical waiting that one does in ConfigMgr. Just wait a while; how long depends upon how often you have hardware inventory configured to run; the # of clients you have, and other factors unique to your environment. But in a couple hours or by the next day, try running one of the reports in the attached .zip file.

Regardless of whether you have the "old" DotNetFrameworks mof edit (which doesn't have release) or are using this new one, attached in the .zip file are also some sample reports. With versions of .net 4.0-4.5.1 no longer under support, your organization may be under hightened awareness of finding and upgrading anyone with those older versions to the supported versions. For example, below is what a report might look like, using 2 of the SQL queries attached. The top one is the results of the 'SQLtoCountDotNetVersions', and bottom one would be the 'SQLToShowVersionsInYourDatabase' -- what values you have in your database will vary from company to company.


Geek notes: the "how to tell what .net is installed", came from two different Microsoft articles.
As I write this blog, this covers from .net 1.0 through .net 4.6.1
For V1-4:
For v4-4.61:

Update to an older blog entry... inventory/ :

Because this thread: 4d1f-9b2b-eb1b2f53ed87, got me thinking about it, I went to the adobe blog entry they referenced, here:

Searched our lab for a couple of clients with full Adobe products, and low and behold… found the .swtag files mentioned. Interestingly, that blog was a little misleading–it didn’t seem to cover some of the tags that are really in the .swtag files for serial number, version, etc… so I doubt the script (attached) will actually find everything. but it’s a start; so I thought I’d throw this out into the wild (blog it) and see what others can make of it.

Attached is a script, which you’d run similar to the "all members of all local groups" type of thing–run it on clients (either as a recurring advertisement or as a DCM ConfigItem, with no validation), and the sms_def.mof edit to pull the info back into your DB. Some of what it returns you’ll already have from ARP (name, version), but the golden nuggets of info are the SerialNumber, and whether it’s part of a Suite (according to that blog, anyway). There’s also something about "licensedState", but one of my test boxes had a serial number, but said it was unlicensed. Not sure what that is really about–that the human didn’t click on something after launching to register online? Not sure. But hey, that field is there if it means anything. You could always set that to FALSE in the mof if that LicenseState information is pointless.

What was nice about the above routine was that in the "partofasuite" returned results, it would say "Std" or "Pro" right in there, so that when the licensing folk would come knocking and ask for your pro vs std counts, it was relatively easy to run a report, and show them exactly what you had out there, based on Adobe's own information. With the "DC" version, they've apparently decided to make it even MORE difficult to tell the difference between Pro vs. Std.

Here's a new link to their swid tag information:

Fortunately, the Script + Mof edit will pull back all of the information necessary to tell the difference, it just makes reports more, uh... "fun"

and basically you'll see that that std, the serial numbers start with 9101 and for pro, the serial numbers start with 9707

Here's a sample report, once you've created the ConfigItem and Baseline, deployed it, and imported the mof snippet into inventory, and start getting back results:

This sample report is ONLY for Acrobat, there are other Adobe products returned with the AdobeInfo routine, so this is just a sample report, it's not meant to showcase everything returned.

;with cte as (
Select distinct resourceid, Case when a.SerialNumber0 like '9101%' then 'Std'
when a.SerialNumber like '9707%' then 'Pro' end as 'Type',
Case when a.PartOfASuite0 like 'v7%' then 'DC'
when a.PartOfASuite0 like 'v6%' then '11'
when a.PartOfASuite0 like 'Acrobat%' then '10' end as 'Version'
from v_gs_AdobeInfo0
where a.PartOfASuite0 like 'v%{}Acrobat%' or a.PartOfASuite0 like 'Acrobat%'
select cte.version as [Acrobat Version] , cte.type as [Acrobat Type] ,count(*) as 'Count'
from cte group by [version], [type]
order by [version], [type]
would result in something sorta like this (#'s have been changed from my production environment to fake #'s)
Acrobat Version Acrobat Type Count
10                    Pro                20
10                    Std                15
11                    Pro                300
11                     Std               210
DC                   Pro                700
DC                   Std                800
Of course, the best part of this routine is *if* Adobe comes knocking, you can show them that the information about pro vs. std originates from their SWID tag files, and you can point to their web site about how to tell the difference, so they should be satisfied and quickly leave you alone (unless, of course... you did deploy Pro to all of your environment, and you thought you were deploying Standard... well, then... pay up...)

--> Link --< to get the mof file for importing for ConfigMgr Inventory, and the script to add to a Configuration Item (or you could deploy it as a recurring Advertisement, if you are adverse to Configuration Baselines).  Basically, the client, on a recurring basis, needs to run the script to populate--or wipe and re-populate--the custom WMI location with the Adobe swid tag information.

Based on information contained in here:

Below is a potential custom hardware inventory MOF edit to use to pull back installed versions of .net using Configuration Manager 2012

There's a section you would need to add to your <installed location on your server>\inboxes\clifiles.src\hinv\Configuration.mof, near the bottom.

Then there's the section you would save as a text file, called "dotnet.mof", and you would import that into via your CM Console, into "Default Client Settings", hardware inventory, import.

Once clients start reporting back, there's a potential report for you to use, with, if you just-so-happened-to-have workstations that were named starting with "WIN7-", a sample output. Obviously you can modify the "where" statement to use a @ parameter in sql, or re arrange the SQL report in whatever way is needed for your reporting requirements.

WARNING!!! Sometimes when one copies and pastes from a web browser, "straight" quotes are changed for you to "Smart Quotes". You will want to carefully look at what you've copied and pasted, and if necessary, use a notepad "replace" to replace any curly smart quotes to straight quotes.


#pragma namespace("\\\\.\\root\\cimv2")
#pragma deleteclass("DotNETFrameworks",NOFAIL)
class DotNETFrameworks

{ [key] string Version="";
boolean Installed;
string ServicePack;
string BuildNumber;

instance of DotNETFrameworks
{ Version="1.0";
[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Active Setup\\Installed Components\\{78705f0d-e8db-4b2d-8193-982bdda15ecd}|Version"),Dynamic,Provider("RegPropProv")] BuildNumber;

instance of DotNETFrameworks
{ Version="1.0 MCE";
[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Active Setup\\Installed Components\\{FDC11A6F-17D1-48f9-9EA3-9051954BAA24}|Version"),Dynamic,Provider("RegPropProv")] BuildNumber;

instance of DotNETFrameworks
{ Version="1.1";
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v1.1.4322|Install"),Dynamic,Provider("RegPropProv")] Installed;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v1.1.4322|SP"),Dynamic,Provider("RegPropProv")] ServicePack;

instance of DotNETFrameworks
{ Version="2.0";
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v2.0.50727|Install"),Dynamic,Provider("RegPropProv")] Installed;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v2.0.50727|SP"),Dynamic,Provider("RegPropProv")] ServicePack;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v2.0.50727|Version"),Dynamic,Provider("RegPropProv")] BuildNumber;

instance of DotNETFrameworks
{ Version="3.0";
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.0|Install"),Dynamic,Provider("RegPropProv")] Installed;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.0|SP"),Dynamic,Provider("RegPropProv")] ServicePack;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.0|Version"),Dynamic,Provider("RegPropProv")] BuildNumber;

instance of DotNETFrameworks
{ Version="3.5";
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.5|Install"),Dynamic,Provider("RegPropProv")] Installed;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.5|SP"),Dynamic,Provider("RegPropProv")] ServicePack;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v3.5|Version"),Dynamic,Provider("RegPropProv")] BuildNumber;

instance of DotNETFrameworks
{ Version="4.0";
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Client|Install"),Dynamic,Provider("RegPropProv")] Installed;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Client|SP"),Dynamic,Provider("RegPropProv")] ServicePack;
[PropertyContext("local|HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Client|Version"),Dynamic,Provider("RegPropProv")] BuildNumber;

//===========End of section to be added to Configuration.mof

// Save the below as DotNet.mof, and import into Default Client Settings, Hardware Inventory

[ SMS_Report (TRUE),
SMS_Group_Name ("DotNetFrameworks"),
SMS_Class_ID ("DotNETFrameworks"),
Namespace ("\\\\\\\\.\\\\root\\\\cimv2") ]
class DotNETFrameworks : SMS_Class_Template
[ SMS_Report (TRUE), key ] String Version;
[ SMS_Report (TRUE) ] String BuildNumber;
[ SMS_Report (TRUE) ] String Installed;
[ SMS_Report (TRUE) ] String ServicePack;
// ========End of To-be-Imported.mof

Sample Report:

sys1.netbios_name0 as [Computername],
MAX(CASE dn.version0 when '1.0' THEN
case dn.buildNumber0 when isnull(dn.buildnumber0,1) then dn.BuildNumber0 End END) AS [.Net 1.0],
MAX(CASE dn.version0 when '1.1' THEN
case dn.BuildNumber0 when isnull(dn.buildnumber0,1) then dn.buildnumber0 End END) AS [.Net 1.1],
MAX(CASE dn.version0 when '2.0' THEN
case dn.BuildNumber0 when isNull(dn.buildnumber0,1) then dn.BuildNumber0 end END) AS [.Net 2.0],
MAX(CASE dn.version0 when '3.0' THEN
case dn.BuildNumber0 when isNull(dn.buildnumber0,1) then dn.BuildNumber0 end END) AS [.Net 3.0],
MAX(CASE dn.version0 when '3.5' THEN
case dn.BuildNumber0 when isNull(dn.buildnumber0,1) then dn.BuildNumber0 end END) AS [.Net 3.5],
MAX(CASE dn.version0 when '3.5' THEN
case dn.ServicePack0 when isnull(DN.ServicePack0,1) then dn.ServicePack0 end END) AS [.Net 3.5 ServicePack],
MAX(CASE dn.version0 when '4.0' THEN
case dn.BuildNumber0 when isNull(dn.buildnumber0,1) then dn.BuildNumber0 end END) AS [.Net 4.0]
v_r_system_valid sys1
Left Join v_gs_dotnetframeworks0 dn
ON dn.resourceid=sys1.ResourceID
where sys1.netbios_name0 like 'Win7-%'
Group By

The report would end up looking something sort of like this:

ComputerName   .Net 1.0  .Net 1.1   .Net 2.0               .Net 3.0               .Net 3.5            .Net 3.5 Service Pack     .Net 4.0
Win7-ABC12345   NULL     1.1.4322   2.0.50727.5420   3.0.30729.5420   3.5.30729.5420  1                                 4.5.50938
WIN7-ABC23456  NULL     1.1.4322   2.0.50727.5420   3.0.30729.5420   3.5.30729.5420  1                                 4.5.51209

This ask came up recently, so I did a bit of research.  It is NOT, I repeat NOT perfect, and NOT complete.  I did NOT include all of the possible "Team" editions for Visual Studio 2005 or Visual Studio 2008. But for Visual Studio 2010, 2012, 2013, and (I think) 2015, the editions should be reported correctly. If you want to (need to) add in all of the potential "team" editions for Visual Studio 2005/2008, you can use this as a guide and add in all the additional columns for those.

If you're familiar with the "DotNetFrameworks" mof edits, it's similar to that type of MOF edit.  --> attached <--, are what you would add to the bottom of your configuration.mof file in <installed location>\inboxes\clifiles.src\hinv, and the snippet you would import into your "Default Client Settings", hardware inventory, and then enable, or create a custom client agent setting to enable it only to a specific collection of machines.

Using a sql query like this, you can then pull out the "highest" Edition.

sys1.netbios_name0 as 'computername',
vised.version0 as 'Visual Studio Version',
case when vised.ultimate0 = 1 then 'Ultimate'
  when vised.Enterprise0 = 1 then 'Enterprise'
  when vised.Premium0 = 1 then 'Premium'
  when vised.Professional0 = 1 then 'Professional'
  when vised.Community0 = 1 then 'Community' end as 'Highest Edition Installed'
from v_gs_visualstudioeditions0 vised
join v_r_system sys1 on sys1.resourceid=vised.resourceid
where ( vised.professional0 is not null or vised.premium0 is not null or
        vised.ultimate0 is not null or vised.standard0 is not null or
        vised.community0 is not null or vised.enterprise0 is not null
and vised.version0 in ('2005','2008','2010','2012','2013','2015')
order by sys1.computername, vised.version0

which could help you make a report like that could look like this. Computer names have been changed, but note that Computer3 and Computer5 have two versions of Visual Studio, and then their editions:

Sources for where I got these regkeys:

for Visual Studio 2005:
  There may be more subkeys for Team System, but I didn't grab them..
for Visual Studio 2008:
   There's a WHOLE bunch of VSDB, VSTA, VSTD, VSTS, VSTT for all the team System 2008 editions
for Visual Studio 2010:
    Note, Ultimate replaces Team Suite
for Visual Studio 2012:
for Visual Studio 2013: Couldn't find a direct link, but found a note that there's Professional, Premium, and Ultimate, so guessing it's these. And data comes back from clients, so appears to work.
for Visual Studio 2015:
   Note, Enterprise replaces premium and ultimate