Windows Management Framework versions directly impact PowerShell capabilities across different Windows OS versions. Here's the version compatibility matrix:
- Windows 7/Server 2008 R2: WMF 2.0 (default), upgradable to 3.0 or 4.0
- Windows Server 2012: Ships with WMF 3.0, upgradable to 4.0
- Windows Server 2012 R2: Comes with WMF 4.0 by default
The most reliable programmatic approach is querying the Win32_QuickFixEngineering
WMI class. Here's a robust PowerShell function:
function Get-WMFVersion {
$hotfixes = Get-WmiObject -Class Win32_QuickFixEngineering |
Where-Object { $_.HotFixID -like "KB*" }
$wmfVersions = @{
"KB2506143" = "3.0"
"KB2506146" = "3.0"
"KB2819745" = "4.0"
"KB3119938" = "5.0"
}
foreach ($hotfix in $hotfixes) {
if ($wmfVersions.ContainsKey($hotfix.HotFixID)) {
return [PSCustomObject]@{
Version = $wmfVersions[$hotfix.HotFixID]
KBArticle = $hotfix.HotFixID
Description = $hotfix.Description
}
}
}
return [PSCustomObject]@{Version = "2.0"; KBArticle = $null; Description = "Default version"}
}
For environments where WMI might be restricted, check the registry:
$regPath = "HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine"
if (Test-Path $regPath) {
$psVersion = (Get-ItemProperty $regPath).PowerShellVersion
Write-Output "PowerShell version: $psVersion"
} else {
Write-Output "PowerShell 2.0 or older detected"
}
For quick checks in existing PowerShell sessions:
$PSVersionTable.PSVersion.ToString()
Note: This only works if you're already running the desired WMF version's PowerShell.
For GPO filtering, create a WMI filter with this query:
SELECT * FROM Win32_QuickFixEngineering
WHERE HotFixID = 'KB2506143' OR HotFixID = 'KB2506146' OR HotFixID = 'KB2819745'
Here's how to conditionally execute code based on WMF version:
$wmfVersion = (Get-WMFVersion).Version
if ([version]$wmfVersion -ge [version]"3.0") {
# Use WMF 3.0+ features
Get-CimInstance -ClassName Win32_Process
} else {
# Fallback for WMF 2.0
Get-WmiObject -Class Win32_Process
}
When working with legacy systems like Windows 7 SP1 or Server 2008 R2, you might encounter three potential WMF versions (2.0, 3.0, 4.0). Newer systems like Server 2012 R2 ship with WMF 4.0 by default. This version fragmentation creates challenges when writing scripts that require specific PowerShell features.
The most reliable approach checks the Win32_QuickFixEngineering
WMI class, which records Windows Update installations including WMF:
$wmfVersion = Get-WmiObject -Class Win32_QuickFixEngineering |
Where-Object { $_.HotFixID -match 'KB(KB2506143|KB2506146|KB2819745|KB2819746|KB2819747|KB2925219|KB3191567)' } |
Select-Object -ExpandProperty HotFixID
switch -Wildcard ($wmfVersion) {
"*250614*" { $version = "2.0"; break }
"*281974*" { $version = "3.0"; break }
"*2925219*" { $version = "4.0"; break }
"*3191567*" { $version = "5.0"; break }
default { $version = "Unknown" }
}
For environments where WMI might be restricted, check these registry paths:
$path = "HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine"
if (Test-Path $path) {
$version = (Get-ItemProperty $path).PowerShellVersion
} else {
$version = "2.0"
}
Here's a complete function you can use in scripts:
function Get-WMFVersion {
[CmdletBinding()]
param()
try {
$build = [System.Environment]::OSVersion.Version.Build
$hotfixes = Get-WmiObject -Class Win32_QuickFixEngineering -ErrorAction Stop
if ($build -ge 7601) { # Win7/2008R2+
$wmfHotfix = $hotfixes | Where-Object {
$_.HotFixID -match 'KB(2506143|2506146|2819745|2819746|2819747|2925219|3191567)'
}
switch -Wildcard ($wmfHotfix.HotFixID) {
"*250614*" { return "2.0" }
"*281974*" { return "3.0" }
"*2925219*" { return "4.0" }
"*3191567*" { return "5.0" }
}
}
# Fallback to PowerShell engine version
$psEnginePath = "HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine"
if (Test-Path $psEnginePath) {
return (Get-ItemProperty $psEnginePath).PowerShellVersion
}
return "2.0"
}
catch {
Write-Warning "Detection failed: $_"
return "Unknown"
}
}
For GPO filtering, create a WMI filter with this query:
SELECT * FROM Win32_QuickFixEngineering
WHERE HotFixID LIKE 'KB250614%' OR
HotFixID LIKE 'KB281974%' OR
HotFixID LIKE 'KB2925219%' OR
HotFixID LIKE 'KB3191567%'
Be aware of these scenarios:
- Systems with multiple WMF versions installed (upgrade artifacts)
- Custom builds that might modify registry keys
- Systems where WMI is disabled by security policies