Here’s a scenario: you are writing install scripts which configure your IIS instance, or a deployment script that deploys an application which depends on a certain .NET version. Ideally, you’d want to detect the absence of your required framework and have an option to install said framework. Here’s a start on how to get this done using PowerShell.
First off, we need to find out how to detect which frameworks are installed. Luckily, StackOverflow came to the rescue. THIS question, and in particular the first answer, details on how to detect which frameworks are installed, by querying the registry.
The registry is the "official" way to detect if a specific version of the Framework is installed, but which registry keys are needed change depending on the Framework version you are looking for.
Framework Version Registry Key
------------------------------------------------------------------------------------------
1.0 HKLM\Software\Microsoft\.NETFramework\Policy\v1.0\3705
1.1 HKLM\Software\Microsoft\NET Framework Setup\NDP\v1.1.4322\Install
2.0 HKLM\Software\Microsoft\NET Framework Setup\NDP\v2.0.50727\Install
3.0 HKLM\Software\Microsoft\NET Framework Setup\NDP\v3.0\Setup\InstallSuccess
3.5 HKLM\Software\Microsoft\NET Framework Setup\NDP\v3.5\Install
4.0 Client Profile HKLM\Software\Microsoft\NET Framework Setup\NDP\v4\Client\Install
4.0 Full Profile HKLM\Software\Microsoft\NET Framework Setup\NDP\v4\Full\Install
PowerShell offers, by default, an option to query the registry. Simply set HKLM: or HKCU: as your location, and you’re set. So my first thought was to simply use ‘Test-Path’ to check for the existence of these keys:
$installed1 = Test-Path “HKLM:\Software\Microsoft\.NETFramework\Policy\v1.0\3705”
However, this ALWAYS returned false. Turns out, you can’t test if a registry key exists by using Test-Path, because the actual keys are properties on the parent hive. So we’ll have to check if the hive exists, and if it exists check the property. This is typically something to wrap in a function, so I did:
function Test-Key([string]$path, [string]$key)
{
if(!(Test-Path $path)) { return $false }
if ((Get-ItemProperty $path).$key -eq $null) { return $false }
return $true
}
It really does just what I stated: ‘Test-Path’ on the path to the hive. ‘Get-Property’ on the key. Now, putting this together with the list of registry keys for installed frameworks, we get something like this:
function Get-Framework-Versions()
{
$installedFrameworks = @()
if(Test-Key "HKLM:\Software\Microsoft\.NETFramework\Policy\v1.0" "3705") { $installedFrameworks += "1.0" }
if(Test-Key "HKLM:\Software\Microsoft\NET Framework Setup\NDP\v1.1.4322" "Install") { $installedFrameworks += "1.1" }
if(Test-Key "HKLM:\Software\Microsoft\NET Framework Setup\NDP\v2.0.50727" "Install") { $installedFrameworks += "2.0" }
if(Test-Key "HKLM:\Software\Microsoft\NET Framework Setup\NDP\v3.0\Setup" "InstallSuccess") { $installedFrameworks += "3.0" }
if(Test-Key "HKLM:\Software\Microsoft\NET Framework Setup\NDP\v3.5" "Install") { $installedFrameworks += "3.5" }
if(Test-Key "HKLM:\Software\Microsoft\NET Framework Setup\NDP\v4\Client" "Install") { $installedFrameworks += "4.0c" }
if(Test-Key "HKLM:\Software\Microsoft\NET Framework Setup\NDP\v4\Full" "Install") { $installedFrameworks += "4.0" }
return $installedFrameworks
}
function Test-Key([string]$path, [string]$key)
{
if(!(Test-Path $path)) { return $false }
if ((Get-ItemProperty $path).$key -eq $null) { return $false }
return $true
}
It’s really simple, literally just checking each entry in the list hardcoded. It returns an array of strings, which will tell you which frameworks are installed. When I run it on my dev PC, I get the following output:
PS C:\Users\Erik> Get-Framework-Versions
2.0
3.0
3.5
4.0c
4.0
It’s pretty easy to incorporate this into your deployments scripts. Just pipe the array to a where call, and check for your required framework!