I decided to put together a script to determine the installed versions of the .Net Framework. In researching this I found people using a wide variety of methods including looking at the registry, the file system, checking dll versions, looking at installed programs and others. Looking at the registry seemed to be the ‘official’ way, but I found it to not always work for earlier versions. Here is what I can up with that I thought gave a accurate and readable view of the installs.

I used WinForms for the GUI. I used ListView Class to display the output in two columns. I defined the Form and then made the total ListView columns width slightly narrower to allow for a scroll bar, if needed. I used the Details View so the data is displayed and not an icon. I turned on Gridlines to make it easy to read and made the list Scrollable in case there are many detail lines. I added the columns at full width for when there is no need to scroll.

Add-Type -AssemblyName System.Windows.Forms

# WinForm Setup
$mainForm = New-Object System.Windows.Forms.Form
$mainForm.Font = “Comic Sans MS,8.25″
$mainForm.Text = ” .Net Framework Versions”
$mainForm.Width = 400
$mainForm.Height = 272

$listView = New-Object System.Windows.Forms.ListView
$listView.View = ‘Details’
$listView.Width = 386
$listView.Height = 272
$listView.GridLines = 1
$listView.Scrollable = 1

$listView.Columns.Add(‘Framework’, 230)
$listView.Columns.Add(‘Version’, 170)

I next collect the Framework install info. I first gather the version 1.x info.  I get that from the file system. I trim the name and remove the leading ‘v’ from the version and place them in the array.

# Collect v1.x Frameworks
$report = ls $Env:windir\Microsoft.NET\Framework |
Where { $_.PSIsContainer } |
Where { $_.Name -like “v1.*” } |
Select @{N=”Framework”;E={$_.Name.Substring(0,4)}},@{N=”Version”;E={$_.Name.Substring(1)}}

I then collect the versions above v1 from the registry. I go to the key and recurse through it looking for a ‘Version” string value. I skip some keys like the 1033, because it is a common duplicate used in Windows Language Localization, meaning ‘English’. I also skip a Setup key in v3 with is a dupe. Lastly I skip the keys for Windows Presentation and Communication Foundations. They are an integrated part of the v3 .Net stack and I decided not to show them. If you want to see them just comment out that line. I noticed the Windows Workgroup Foundation doesn’t show under the current algorithm as it doesn’t have a ‘Version’ value.

# Collect v2.x and above Frameworks
$report += Get-ChildItem ‘HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP’ -recurse |
Get-ItemProperty -name Version -erroraction SilentlyContinue |
Where { $_.PSChildName -ne “1033”} |
Where { $_.PSChildName -ne “Setup”} |
Where { $_.PSChildName -notlike “Windows*”} |
Select @{N=”Framework”;E={$_.PSChildName}},@{N=”Version”;E={$_.Version}}

I then sorted the data in the array added the info collected to the ListView as Items. To add an Item to your ListView, first define the new Item while adding the first item element. Then add the next element as a SubItem. Lastly add the Item to the ListView control.
$report = $report | Sort Version

# Load List
ForEach ($line in $report) {
    $item = New-Object System.Windows.Forms.ListViewItem($line.Framework)

Lastly, I added the now populated ListView control to the form and displayed it.
[void] $mainForm.ShowDialog()