function Get-WindowsFeatureInventory { <# .SYNOPSIS Returns an OrderedDictionary that Represents the Windows Feature Inventory. #> [CmdletBinding()] param() $logLead = (Get-LogLeadName); $providerStopWatch = [System.Diagnostics.StopWatch]::StartNew() $featureDictionary = New-Object System.Collections.Specialized.OrderedDictionary $featureDetails = New-Object System.Collections.Specialized.OrderedDictionary try { if ((Get-CIMInstance -Namespace "root\CIMV2" -Class Win32_OperatingSystem -Property Caption).Caption -notmatch "Server") { $logError = "Windows Feature Inventory Not Supported on Client Operating Systems" Write-Warning "$logLead : $logError" throw $logError } Write-Verbose "$logLead : [$($providerStopWatch.Elapsed)] : Reading Windows Feature and Role Details" Import-Module ServerManager -Verbose:$false | Out-Null $features = Get-WindowsFeature | Where-Object {$_.Installed} Write-Verbose "$logLead : [$($providerStopWatch.Elapsed)] : Windows Feature and Role Data Retrieved" foreach ($feature in $features) { $featureDetails[$feature.Name] = New-Object System.Collections.Specialized.OrderedDictionary $featureDetails[$feature.Name]["Name"] = $feature.Name $featureDetails[$feature.Name]["DisplayName"] = $feature.DisplayName $featureDetails[$feature.Name]["FeatureType"] = $feature.FeatureType $featureDetails[$feature.Name]["Path"] = $feature.Path $featureDetails[$feature.Name]["Depth"] = $feature.Depth $featureDetails[$feature.Name]["Parent"] = $feature.Parent } } catch { $featureDetails["Error"] = $_.Exception.ToString() } $featureDictionary.Add("Features", $featureDetails) Write-Verbose "$logLead : [$($providerStopWatch.Elapsed)] : Provider Complete" $providerStopWatch.Stop() return $featureDictionary }