When the Question Is Not So Simple; What’s Your Version of Dot Net?

<#

Surprisingly, trying to determine the level of .Net (dotNet) installed on a system is a difficult thing to do. dotNet does not self-report the version in use. Since dotNet is a collection of items plus the CLR (Common Runtime Language), file checking is convoluted and often inaccurate. Even the version of record – contained in the Registry, is fragmented due to the evolving nature of its programming (I’m not a registry expert but this is one of only a few times where there is no definitive key=value pair. What makes it worse is the method of recording the versions in the registry has changed over the years). There is simply no easy or pre-built solution to checking the versions of .Net installed. Which means, there cannot be a simple Powershell script that will check for the installed versions of .Net on any specific system. Legacy can have its issues.

However, most of the time, we don’t really care about any previous installation. We just need to know what is the current version (usually for compatibility reasons). Today’s posting is about a simple (sort of) script that will answer that for most business machines. We will do this by using an assumption script. Assumption scripts ‘assume’ certain factors exist in the operating environment. In this case, a certain level of .Net is installed; specifically dotNet version 4.5 or higher. For Windows 7 machines and above, this is a pretty safe assumption. Without becoming a primer on the differences, let’s just say the installations prior to .net 4.5 is where the registry structure issues reside.

The root path in the registry for dotNet is in the HKEY_Local_Machine directory: HKLM\SOFTWARE\Microsoft\.NetFramework…

When talking about dotNet 4.5, the registry keys reside under the cryptic subdirectory v4.0.30319 and are listed by SKUs. However, this is where things get interesting because instead of a key value pair or further sub-directories, you find a ‘product listing’. Looking like a subdirectory, the name will be a mashup of the term ‘.NETFramework’ and a key=value pair looking ‘Version=vXXX’ pattern (the mashup is done with a comma symbol ‘,’). The content of these, as such, is an unset Default value. Prior to version 4.5, there is a second sub-directory that extends the mashup with a Profile=Client addition that adds even more confusion and no actual information. Fun stuff.

So, bearing the above in mind, a Powershell script that returns the highest level of dotNet installed will have to find these sub-directories, split out the mashups, and then apply logic to determine the highest level. Easy peasy right!?!

Line 1: Get all the SKUs entries from the registry path. Sorting them ascending will give us a known structure

Line 2: There are two entries under SKUs that are non-standard (of course). So, we are going to find the third entry which will be our senior .Net installation

Line 3: Break the mash-up apart and return the salient part (the second part that shows the version number).

I borrowed the above code from a function I wrote (with all the try/catch, write-debug, validates, remote computer options, functions can give you). However, when I was first using this, it was a one-liner that used the semicolon token “;” to emulate the separate lines. If that doesn’t make sense to you, here it is as a one liner:

*** With a small amount of rewrite, this script could give you all versions (even prior to v4.5) if you so desired. ***

[NOTE: There is also an entry that is more key=value like. HKLM\SOFTWARE\Microsoft\Net Framework Setup\NDP\V4\Client. You will have to translate the Release= DWORD entry and know whether the machine being tested is Windows 10 or not. And, if it is Windows 10, you’ll need to know which flavor (Nov. Update, Anniversary Update, or Creators Update). However, they MAY be a Version key. If there IS a Version key, it does work exactly as you would expect a registry structure to work. B-T-W the DWORD entry for Version 4.7 is 0x000707fe (460798) on a Windows 10 Creator Update edition.]