Public/Dism/Get-MyWindowsCapability.ps1
<#
.SYNOPSIS Gets Windows capabilities for an image or a running operating system. Modified version of Get-WindowsCapability .DESCRIPTION The Get-MyWindowsCapability function gets Windows capabilities installed in an image or running operating system .PARAMETER Path Specifies the full path to the root directory of the offline Windows image that you will service. .PARAMETER State Installation state of the Windows Capability Get-MyWindowsCapability -State Installed Get-MyWindowsCapability -State NotPresent .PARAMETER Category Category of the Windows Capability Get-MyWindowsCapability -Category Language Get-MyWindowsCapability -Category Rsat Get-MyWindowsCapability -Category Other .PARAMETER Culture Culture of the Capability Get-MyWindowsCapability -Culture 'de-DE' Get-MyWindowsCapability -Culture 'de-DE','es-ES','fr-FR' .PARAMETER Like Searches the Capability Name for the specified string. Wildcards are permitted Get-MyWindowsCapability -Like "*Dns*" .PARAMETER Match Searches the Capability Name for a matching string. Wildcards are not permitted Get-MyWindowsCapability -Match 'Dhcp' Get-MyWindowsCapability -Match 'Dhcp','Rsat' .PARAMETER Detail Processes a foreach Get-WindowsCapability <Name> to get further details of the Windows Capability .INPUTS None .OUTPUTS Microsoft.Dism.Commands.ImageObject .LINK https://osd.osdeploy.com/module/functions/dism/get-mywindowscapability .LINK https://docs.microsoft.com/en-us/powershell/module/dism/get-windowscapability?view=win10-ps .LINK Add-WindowsCapability .LINK Get-WindowsCapability .LINK Remove-WindowsCapability .NOTES 21.2.8.1 Initial Release 21.2.8.2 Added IsAdmin requirement Added validation for Get-WindowsCapability Resolved issue if multiple OSD modules are installed Renamed Language parameter to Culture #> function Get-MyWindowsCapability { [CmdletBinding(DefaultParameterSetName = 'Online')] Param ( [Parameter(Mandatory = $true, ParameterSetName = "Offline", ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)] [string]$Path, [ValidateSet('Installed','NotPresent')] [string]$State, [ValidateSet('Language','Rsat','Other')] [string]$Category, [string[]]$Culture, [string[]]$Like, [string[]]$Match, [switch]$Detail ) #=================================================================================================== # Require Admin Rights #=================================================================================================== if ((Get-OSDGather -Property IsAdmin) -eq $false) { Write-Warning 'This function requires Admin Rights ELEVATED' Break } #=================================================================================================== # Test Get-WindowsCapability #=================================================================================================== if (Get-Command -Name Get-WindowsCapability -ErrorAction SilentlyContinue) { Write-Verbose 'Verified command Get-WindowsCapability' } else { Write-Warning 'This function requires Get-WindowsCapability which is not present' Break } #=================================================================================================== # Get Module Path #=================================================================================================== $GetModuleBase = Get-Module -Name OSD | Select-Object -ExpandProperty ModuleBase -First 1 #=================================================================================================== # Get-WindowsCapability #=================================================================================================== if ($PSCmdlet.ParameterSetName -eq 'Online') { $GetAllItems = Get-WindowsCapability -Online } if ($PSCmdlet.ParameterSetName -eq 'Offline') { $GetAllItems = Get-WindowsCapability -Path $Path } #=================================================================================================== # Like #=================================================================================================== foreach ($Item in $Like) { $GetAllItems = $GetAllItems | Where-Object {$_.Name -like "$Like"} } #=================================================================================================== # Match #=================================================================================================== foreach ($Item in $Match) { $GetAllItems = $GetAllItems | Where-Object {$_.Name -match "$Match"} } #=================================================================================================== # State #=================================================================================================== if ($State) {$GetAllItems = $GetAllItems | Where-Object {$_.State -eq $State}} #=================================================================================================== # Category #=================================================================================================== if ($Category -eq 'Other') { $GetAllItems = $GetAllItems | Where-Object {$_.Name -notmatch 'Language'} $GetAllItems = $GetAllItems | Where-Object {$_.Name -notmatch 'Rsat'} } if ($Category -eq 'Language') { $GetAllItems = $GetAllItems | Where-Object {$_.Name -match 'Language'} } if ($Category -eq 'Rsat') { $GetAllItems = $GetAllItems | Where-Object {$_.Name -match 'Rsat'} } #=================================================================================================== # Culture #=================================================================================================== $FilteredItems = @() if ($Culture) { foreach ($Item in $Culture) { $FilteredItems += $GetAllItems | Where-Object {$_.Name -match $Item} } } else { $FilteredItems = $GetAllItems } #=================================================================================================== # Dictionary #=================================================================================================== if (Test-Path "$GetModuleBase\Dictionary\Get-MyWindowsCapability.json") { $GetAllItemsDictionary = Get-Content "$GetModuleBase\Dictionary\Get-MyWindowsCapability.json" | ConvertFrom-Json } #=================================================================================================== # Create Object #=================================================================================================== if ($Detail -eq $true) { $Results = foreach ($Item in $FilteredItems) { $ItemProductName = ($Item.Name -split ',*~')[0] $ItemCulture = ($Item.Name -split ',*~')[3] $ItemVersion = ($Item.Name -split ',*~')[4] $ItemDetails = $null $ItemDetails = $GetAllItemsDictionary | ` Where-Object {($_.ProductName -eq $ItemProductName)} | ` Where-Object {($_.Culture -eq $ItemCulture)} | ` Select-Object -First 1 if ($null -eq $ItemDetails) { Write-Verbose "$($Item.Name) ... gathering details" -Verbose if ($PSCmdlet.ParameterSetName -eq 'Online') { $ItemDetails = Get-WindowsCapability -Name $Item.Name -Online } if ($PSCmdlet.ParameterSetName -eq 'Offline') { $ItemDetails = Get-WindowsCapability -Name $Item.Name -Path $Path } } if ($PSCmdlet.ParameterSetName -eq 'Online') { [PSCustomObject] @{ DisplayName = $ItemDetails.DisplayName Culture = $ItemCulture Version = $ItemVersion State = $Item.State Description = $ItemDetails.Description Name = $Item.Name Online = $Item.Online ProductName = $ItemProductName } } if ($PSCmdlet.ParameterSetName -eq 'Offline') { [PSCustomObject] @{ DisplayName = $ItemDetails.DisplayName Culture = $ItemCulture Version = $ItemVersion State = $Item.State Description = $ItemDetails.Description Name = $Item.Name Path = $Item.Path ProductName = $ItemProductName } } } } else { $Results = foreach ($Item in $FilteredItems) { $ItemProductName = ($Item.Name -split ',*~')[0] $ItemCulture = ($Item.Name -split ',*~')[3] $ItemVersion = ($Item.Name -split ',*~')[4] if ($PSCmdlet.ParameterSetName -eq 'Online') { [PSCustomObject] @{ ProductName = $ItemProductName Culture = $ItemCulture Version = $ItemVersion State = $Item.State Name = $Item.Name Online = $Item.Online } } if ($PSCmdlet.ParameterSetName -eq 'Offline') { [PSCustomObject] @{ ProductName = $ItemProductName Culture = $ItemCulture Version = $ItemVersion State = $Item.State Name = $Item.Name Path = $Item.Path } } } } #=================================================================================================== # Rebuild Dictionary #=================================================================================================== $Results | ` Sort-Object ProductName, Culture | ` Select-Object Name, ProductName, Culture, DisplayName, Description | ` ConvertTo-Json | ` Out-File "$env:TEMP\Get-MyWindowsCapability.json" #=================================================================================================== # Install / Return #=================================================================================================== if ($Install -eq $true) { foreach ($Item in $Results) { if ($_.State -eq 'Installed') { Write-Verbose "$_.Name is already installed" -Verbose } else { $Item | Add-WindowsCapability -Online } } } else { Return $Results } #=================================================================================================== } |