| description | This article explains how PowerShell handles case-sensitivity. |
|---|---|
| Locale | en-US |
| ms.date | 01/06/2026 |
| online version | https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_case-sensitivity?view=powershell-5.1&WT.mc_id=ps-gethelp |
| title | about_Case-Sensitivity |
PowerShell is as case-insensitive as possible while preserving case.
As a general principle, PowerShell is case-insensitive wherever possible while preserving case and not breaking the underlying OS.
Windows-based systems are case-insensitive for most operations. However, non-Windows systems are case-sensitive for most operations, especially for file system and environment variable access.
PowerShell is guaranteed to be case-insensitive on all systems for the following areas:
- Variable names
- Operator names
- Non-dictionary member-access
- Command discovery of PowerShell commands and aliases. This excludes ExternalScript and Application commands.
- Parameter names and aliases
- PowerShell language keywords
using namespacestatements- Type literals
#Requiresstatements- Comment-based help keywords
- PSProvider names
- PSDrive names
- Scope modifiers
-
Module names are case-insensitive (with exceptions)
The name of the module is purely a PowerShell concept and treated case-insensitively. However, there is a strong mapping to a foldername, which can be case-sensitive in the underlying operating system. Importing two modules with the same case-insensitive name has the same behavior as importing two modules with the same name from different paths.
The name of a module is stored in the session state using the case by which it was imported. The name, as stored in the session state, is used by
Update-Helpwhen looking for new help files. The web service that serves the help files for Microsoft uses a case-sensitive file system. When the case of the imported name of the module doesn't match,Update-Helpcan't find the help files and reports an error. -
The
FileSystemandEnvironmentproviders are case-sensitive on non-Windows systems. Generally, operations involving paths or environment variables are case-sensitive on such systems.However, wildcard matching by provider cmdlets is case-insensitive, irrespective of the system.
PS /home/user01> New-Item -Path Temp:foo.txt -Force Directory: /tmp UnixMode User Group LastWriteTime Size Name -------- ---- ----- ------------- ---- ---- -rw-r--r-- user01 user01 1/6/2026 10:53 0 foo.txt PS /home/user01> (Get-Item -Path Temp:FOO.txt).Name Get-Item: Cannot find path 'Temp:/FOO.txt' because it does not exist. PS /home/user01> (Get-Item -Path Temp:F[O]*.txt).Name foo.txt PS /home/user01> (Get-Item -Path Env:hOM[E]).Name HOME
-
Parameter set names are case-sensitive.
The
DefaultParameterSetNamecase must be identical toParameterSetName. -
.NET methods often exhibit case-sensitive behavior by default.
Examples include:
- Equivalent .NET methods (without explicit opt-in) for common PowerShell
operators such as:
Array.Contains(),String.Contains(),String.Replace(),Regex.Match(),Regex.Replace()
- Reflection; member names must use the correct case.
- Non-literal dictionary instantiation. For example:
[hashtable]::new()has case-sensitive keys, whereas a hashtable literal@{}has case-insensitive keys.[ordered]::new()has case-sensitive keys, whereas a[ordered] @{}has case-insensitive keys. The[ordered]type accelerator isn't available in PowerShell v5.1 and earlier.
- Explicitly calling
Enum.Parse()is case-sensitive by default, whereas PowerShell typically handles enums in a case-insensitive manner.
- Equivalent .NET methods (without explicit opt-in) for common PowerShell
operators such as:
-
-Uniquecmdlets:Select-Object -UniqueandGet-Uniqueare case-sensitive by default. The-CaseInsensitiveswitch was added in PS v7.4.Sort-Object -Uniqueis case-insensitive by default, but has always had the-CaseSensitiveswitch.
-
Compare-Objectis case-insensitive by default, but has a-CaseSensitiveswitch. Comparison of[char]types is case-sensitive by default. String comparison is case-insensitive by default.# Compare strings - Equal (no output) Compare-object -ReferenceObject a -DifferenceObject A # Compare chars - Different (output) Compare-object -ReferenceObject ([char] 'a') -DifferenceObject ([char] 'A')
-
ConvertFrom-Json -AsHashtable:-AsHashtablewas added in PS v6. In PS v7.3, a change was made to treat JSON keys as case-sensitive when this parameter is specified.- With the parameter, an object of type
Management.Automation.OrderedHashtableis emitted, which has case-sensitive keys. - Without the parameter, JSON keys are treated as case-insensitive. Output is a custom object; last case-insensitive key wins.
- With the parameter, an object of type
- PowerShell/PowerShell#19928
-
Group-Object:-
Case-insensitive by default, but does have a
-CaseSensitiveswitch. -
In Windows PowerShell v5.1,
-CaseSensitiveand-AsHashtableproduces a case-insensitive hashtable. Duplicate keys result in an error.[pscustomobject] @{ Foo = 'Bar' }, [pscustomobject] @{ Foo = 'bar' } | Group-Object -Property Foo -CaseSensitive -AsHashtable
Group-Object : The objects grouped by this property cannot be expanded because there is a key duplication. Provide a valid value for the property, and then try again. At line:2 char:11 + Group-Object -Property Foo -CaseSensitive -AsHashtable + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Group-Object], Exception + FullyQualifiedErrorId : The objects grouped by this property cannot be expanded because there is a key duplication. Provide a valid value for the property, and then try again.,Microsoft.PowerShell.Comman ds.GroupObjectCommand -
In PowerShell v7 and higher,
-CaseSensitiveand-AsHashtableproduces a case-sensitive hashtable. No error occurs with duplicate keys.[pscustomobject] @{ Foo = 'Bar' }, [pscustomobject] @{ Foo = 'bar' } | Group-Object -Property Foo -CaseSensitive -AsHashtable
Name Value ---- ----- Bar {@{Foo=Bar}} bar {@{Foo=bar}}
-
-
Select-String:- Case-insensitive by default, but does have a
-CaseSensitiveswitch.
- Case-insensitive by default, but does have a
-
Get-Commandand command discovery/invocation:- On case-sensitive file systems, discovery and invocation of
ExternalScriptandApplicationcommand are case-sensitive. Get-Commandwildcard matching with these types is also case-sensitive.- All other
CommandTypesare case-insensitive.
- On case-sensitive file systems, discovery and invocation of
-
-
By default, operators are case-insensitive.
-
-c*operators are case-sensitive. -
-i*operators are case-insensitive. -
-replace/-ireplaceis case-insensitive by default, except with named capture groups, which are case-sensitive.'Bar' -replace '(?<a>a)', '${a}${a}' # Baar 'Bar' -replace '(?<a>a)', '${A}${A}' # B${A}${A}r
-
-
-
-splitand-isplitare case-insensitive. -
-csplitis case-sensitive, unless theIgnoreCaseoption is specified.'Bar' -csplit 'A', 0 # Bar 'Bar' -csplit 'A', 0, 'IgnoreCase' # B # r
-
-
- On case-sensitive file systems, tab completion and globbing are both
case-insensitive. For example,
TabExpansion2 -inputScript ./foowill complete to./Foo.txton Linux.
- On case-sensitive file systems, tab completion and globbing are both
case-insensitive. For example,
-
usingstatement:- On case-sensitive file systems,
using moduleandusing assemblyare case-sensitive when a path is specified. using modulewith just a module name is case-insensitive.using namespaceis always case-insensitive.
- On case-sensitive file systems,
-
- Escape sequences like
`nare case-sensitive.
- Escape sequences like
- about_Environment_Variables
- Import-Module