How to List Windows Features Using PowerShell (Windows 11, 10 and Server)

To list Windows features using PowerShell on Windows 11 or 10, run Get-WindowsOptionalFeature in an admin window. It shows every optional feature and whether it’s enabled:

Get-WindowsOptionalFeature -Online | Sort-Object FeatureName | Format-Table FeatureName, State

Without admin rights, the Win32_OptionalFeature class gives the same list to any user, so most examples below use it.

On Windows Server, Get-WindowsFeature lists roles and features instead. I tested everything in PowerShell 7 and Windows PowerShell 5.1.

List all Windows features without admin rights

Get-CimInstance reads Win32_OptionalFeature from WMI. Its InstallState is a number, so I map it to a name and count the features in each state:

$state = @{ 1 = 'Enabled'; 2 = 'Disabled'; 3 = 'Absent'; 4 = 'Unknown' }
$features = Get-CimInstance -ClassName Win32_OptionalFeature

"Windows features found: $($features.Count)"
$features | Group-Object InstallState | Sort-Object { [int]$_.Name } | ForEach-Object {
    '{0,-9} {1,4}' -f $state[[int]$_.Name], $_.Count
}

Output:

Windows features found: 135
Enabled     14
Disabled   120
Absent       1

My Windows 11 PC has 135 features and 14 are turned on. Microsoft defines four states: 1 Enabled, 2 Disabled, 3 Absent and 4 Unknown. For more on grouping results like this, see sorting objects with Sort-Object.

Show only the enabled Windows features

A WMI filter returns just the features that are turned on. It runs before PowerShell gets the data, so it’s faster than filtering afterwards:

Get-CimInstance -ClassName Win32_OptionalFeature -Filter 'InstallState = 1' |
    Sort-Object Name |
    Format-Table Name, Caption -AutoSize

Output:

Name                                        Caption
----                                        -------
MediaPlayback                               Media Features
MSRDC-Infrastructure                        Remote Differential Compression API Support
NetFx4-AdvSrvs                              .NET Framework 4.8 Advanced Services
NetFx4Extended-ASPNET45                     ASP.NET 4.8
Printing-Foundation-Features                Print and Document Services
Printing-Foundation-InternetPrinting-Client Internet Printing Client
Printing-PrintToPDFServices-Features        Microsoft Print to PDF
SearchEngine-Client-Package                 Windows Search
SmbDirect                                   SMB Direct
VirtualMachinePlatform                      Virtual Machine Platform
WCF-Services45                              WCF Services
WCF-TCP-PortSharing45                       TCP Port Sharing
WindowsMediaPlayer                          Windows Media Player Legacy (App)
WorkFolders-Client                          Work Folders Client
PowerShell list enabled Windows features with Win32_OptionalFeature
The 14 Windows features turned on for this PC (PowerShell 7)

Name is the ID you pass to install commands, and Caption is the name you see in the Windows Features dialog. Change the filter to InstallState = 2 for the disabled ones. Format-Table controls which columns you see.

Check the state of specific features

Usually you care about a handful of features, like Hyper-V, WSL or the old SMB1 protocol. Pass their names to Where-Object -in:

$state = @{ 1 = 'Enabled'; 2 = 'Disabled'; 3 = 'Absent'; 4 = 'Unknown' }
$names = 'Microsoft-Hyper-V-All', 'Microsoft-Windows-Subsystem-Linux', 'VirtualMachinePlatform',
         'Containers-DisposableClientVM', 'NetFx3', 'TelnetClient', 'SMB1Protocol'

Get-CimInstance -ClassName Win32_OptionalFeature |
    Where-Object Name -in $names |
    Sort-Object Name |
    Select-Object Name, @{ n = 'State'; e = { $state[[int]$_.InstallState] } } |
    Format-Table -AutoSize

Output:

Name                              State
----                              -----
Containers-DisposableClientVM     Disabled
Microsoft-Hyper-V-All             Disabled
Microsoft-Windows-Subsystem-Linux Disabled
NetFx3                            Disabled
SMB1Protocol                      Disabled
TelnetClient                      Disabled
VirtualMachinePlatform            Enabled
PowerShell check Windows feature state for Hyper-V, WSL and SMB1
Seven common features and their state on this PC (Windows PowerShell 5.1)

Windows Sandbox shows up as Containers-DisposableClientVM, so the Name column isn’t always obvious. If you only know part of the display name, search the Caption with -like:

Get-CimInstance -ClassName Win32_OptionalFeature |
    Where-Object Caption -like '*Hyper-V*' |
    Sort-Object Name |
    Select-Object -First 5 -ExpandProperty Name

Output:

Microsoft-Hyper-V
Microsoft-Hyper-V-All
Microsoft-Hyper-V-Hypervisor
Microsoft-Hyper-V-Management-Clients
Microsoft-Hyper-V-Management-PowerShell

Where-Object supports the same -like and -match operators on any property.

How do I check if a Windows feature is enabled?

In scripts, a True or False answer is easier to work with. This function returns False for a disabled feature and “Not found” for a wrong name:

function Test-WindowsFeature ([string]$Name) {
    $f = Get-CimInstance -ClassName Win32_OptionalFeature -Filter "Name = '$Name'"
    if (-not $f) { return 'Not found' }
    $f.InstallState -eq 1
}

foreach ($name in 'Microsoft-Windows-Subsystem-Linux', 'VirtualMachinePlatform', 'Hyper-V') {
    '{0,-34} {1}' -f $name, (Test-WindowsFeature $name)
}

Output:

Microsoft-Windows-Subsystem-Linux  False
VirtualMachinePlatform             True
Hyper-V                            Not found

Hyper-V isn’t a feature name, which is why it’s not found. The real name is Microsoft-Hyper-V-All. To check whether a feature folder or file exists on disk instead, use Test-Path.

Get-WindowsOptionalFeature needs an elevated window

The DISM cmdlet gives more detail, but it refuses to run without admin rights. Here’s what happens in a normal window:

try {
    Get-WindowsOptionalFeature -Online -ErrorAction Stop | Select-Object -First 3
}
catch {
    "Failed. $($_.Exception.Message)"
}

Output:

Failed. The requested operation requires elevation.
PowerShell Get-WindowsOptionalFeature requires elevation error
Get-WindowsOptionalFeature fai