|
1 | 1 | --- |
2 | 2 | description: This article explains how PowerShell handles case-sensitivity. |
3 | 3 | Locale: en-US |
4 | | -ms.custom: wiki-migration |
5 | | -ms.date: 06/06/2022 |
| 4 | +ms.date: 01/06/2026 |
6 | 5 | online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_case-sensitivity?view=powershell-5.1&WT.mc_id=ps-gethelp |
7 | 6 | title: about_Case-Sensitivity |
8 | 7 | --- |
9 | 8 | # about_Case-Sensitivity |
10 | 9 |
|
11 | 10 | ## Short description |
12 | 11 |
|
13 | | -PowerShell is as case-insensitive as possible while preserving case. |
| 12 | +PowerShell is as case-insensitive while preserving case. |
14 | 13 |
|
15 | 14 | ## Long description |
16 | 15 |
|
17 | | -As a general principle, PowerShell is as case insensitive as possible while |
| 16 | +As a general principle, PowerShell is case-insensitive wherever possible while |
18 | 17 | preserving case and not breaking the underlying OS. |
19 | 18 |
|
20 | | -### On Unix-based systems |
| 19 | +Windows-based systems are case-insensitive for most operations. However, |
| 20 | +non-Windows systems are case-sensitive for most operations, especially for |
| 21 | +file system and environment variable access. |
21 | 22 |
|
22 | | -On Unix-based systems, PowerShell is case-sensitive because filesystem |
23 | | -manipulation and environment variables directly affect the underlying |
24 | | -operating system and integration with other tools. |
| 23 | +PowerShell is guaranteed to be case-insensitive on all systems for the |
| 24 | +following areas: |
25 | 25 |
|
26 | | -## On all systems |
| 26 | +- Variable names |
| 27 | +- Operator names |
| 28 | +- Non-dictionary member-access |
| 29 | +- Command discovery of PowerShell commands and aliases. This excludes |
| 30 | + ExternalScript and Application commands. |
| 31 | +- Parameter names and aliases |
| 32 | +- PowerShell language keywords |
| 33 | +- `using namespace` statements |
| 34 | +- Type literals |
| 35 | +- `#Requires` statements |
| 36 | +- Comment-based help keywords |
| 37 | +- PSProvider names |
| 38 | +- PSDrive names |
| 39 | +- Scope modifiers |
27 | 40 |
|
28 | | -- PowerShell variables are case-insensitive |
29 | | - |
30 | | - Variable names have no interaction between them and the underlying operating |
31 | | - system. PowerShell treats them case-insensitively. |
| 41 | +## Special cases |
32 | 42 |
|
33 | 43 | - Module names are case-insensitive (with exceptions) |
34 | 44 |
|
35 | 45 | The _name_ of the module is purely a PowerShell concept and treated |
36 | 46 | case-insensitively. However, there is a strong mapping to a foldername, which |
37 | | - can be case-sensitive in the underlying operating system. Importing two| |
| 47 | + can be case-sensitive in the underlying operating system. Importing two |
38 | 48 | modules with the same case-insensitive name has the same behavior as |
39 | 49 | importing two modules with the same name from different paths. |
40 | 50 |
|
41 | 51 | The name of a module is stored in the session state using the case by which |
42 | 52 | it was imported. The name, as stored in the session state, is used |
43 | | - `Update-Help` when looking for new help files. |
44 | | - The web service that serves the help files for Microsoft uses a |
45 | | - case-sensitive filesystem. When the case of the imported name of the module |
46 | | - doesn't match, `Update-Help` can't find the help files and reports an error. |
| 53 | + `Update-Help` when looking for new help files. The web service that serves |
| 54 | + the help files for Microsoft uses a case-sensitive file system. When the case |
| 55 | + of the imported name of the module doesn't match, `Update-Help` can't find |
| 56 | + the help files and reports an error. |
| 57 | + |
| 58 | +- [PS providers][05]: |
| 59 | + |
| 60 | + The `FileSystem` and `Environment` providers are case-sensitive on |
| 61 | + non-Windows systems. Generally, operations involving paths or environment |
| 62 | + variables are case-sensitive on such systems. |
| 63 | + |
| 64 | + However, [wildcard matching][09] by [provider cmdlets][02] is |
| 65 | + case-insensitive, irrespective of the system. |
| 66 | + |
| 67 | + ```powershell |
| 68 | + [void] (New-Item -Path Temp:foo.txt -Force) |
| 69 | +
|
| 70 | + (Get-Item -Path Temp:FOO.txt).Name |
| 71 | + # Get-Item: Cannot find path 'Temp:/FOO.txt' because it does not exist. |
| 72 | +
|
| 73 | + (Get-Item -Path Temp:F[O]*.txt).Name |
| 74 | + # foo.txt |
| 75 | +
|
| 76 | + (Get-Item -Path Env:hOME).Name |
| 77 | + # Get-Item: Cannot find path 'Env:/hOME' because it does not exist. |
| 78 | +
|
| 79 | + (Get-Item -Path Env:hOM[E]).Name |
| 80 | + # HOME |
| 81 | + ``` |
| 82 | + |
| 83 | +- Parameter set names are case-sensitive. |
| 84 | + |
| 85 | + The `DefaultParameterSetName` case must be identical to `ParameterSetName`. |
| 86 | + |
| 87 | +- .NET methods often exhibit case-sensitive behavior by default. |
| 88 | + |
| 89 | + Examples include: |
| 90 | + |
| 91 | + - Equivalent .NET methods (without explicit opt-in) for common PowerShell |
| 92 | + operators such as: |
| 93 | + - `Array.Contains()`, `String.Contains()`, `String.Replace()`, |
| 94 | + `Regex.Match()`, `Regex.Replace()` |
| 95 | + - Reflection; member names must use the correct case. |
| 96 | + - Non-literal dictionary instantiation. For example: |
| 97 | + - `[hashtable]::new()` has case-sensitive keys, whereas a hashtable |
| 98 | + literal `@{}` has case-insensitive keys. |
| 99 | + - `[ordered]::new()` has case-sensitive keys, whereas a `[ordered] @{}` has |
| 100 | + case-insensitive keys. The `[ordered]` type _accelerator_ isn't available |
| 101 | + in PowerShell v5.1 and earlier. |
| 102 | + - Explicitly calling `Enum.Parse()` is case-sensitive by default, whereas |
| 103 | + PowerShell typically handles enums in a case-insensitive manner. |
| 104 | + |
| 105 | +- `-Unique` cmdlets: |
| 106 | + - [`Select-Object -Unique`][21] and [`Get-Unique`][15] are case-sensitive by |
| 107 | + default. The [`-CaseInsensitive`][20] switch was added in PS v7.4. |
| 108 | + - [`Sort-Object -Unique`][25] is case-insensitive by default, but has always |
| 109 | + had [`-CaseSensitive`][24] switch. |
| 110 | + |
| 111 | +- [`Compare-Object`][11] is case-insensitive by default, but has a |
| 112 | + [`-CaseSensitive`][12] switch. Comparison of `[char]` types is case-sensitive |
| 113 | + by default. String comparison is case-insensitive by default. |
| 114 | + |
| 115 | + ```powershell |
| 116 | + # Compare strings - Equal (no output) |
| 117 | + Compare-object -ReferenceObject a -DifferenceObject A |
| 118 | + # Compare chars - Different (output) |
| 119 | + Compare-object -ReferenceObject ([char] 'a') -DifferenceObject ([char] 'A') |
| 120 | + ``` |
| 121 | + |
| 122 | +- [`ConvertFrom-Json -AsHashtable`][13]: |
| 123 | + - `-AsHashtable` was added in PS v6. In PS v7.3, a change was made to treat |
| 124 | + JSON keys as case-sensitive when this parameter is specified. |
| 125 | + - With the parameter, an object of type |
| 126 | + [`Management.Automation.OrderedHashtable`][27] is emitted, which has |
| 127 | + case-sensitive keys. |
| 128 | + - Without the parameter, JSON keys are treated as case-insensitive. Output |
| 129 | + is a custom object; last case-insensitive key wins. |
| 130 | + - https://github.com/PowerShell/PowerShell/issues/19928 |
| 131 | + |
| 132 | +- [`Group-Object`][16]: |
| 133 | + - Case-insensitive by default, but does have a [`-CaseSensitive`][18] |
| 134 | + switch. |
| 135 | + - In Windows PowerShell v5.1, `-CaseSensitive` and [`-AsHashtable`][17] |
| 136 | + produces a case-insensitive hashtable. Duplicate keys result in an error. |
| 137 | + |
| 138 | + ```powershell |
| 139 | + [pscustomobject] @{ Foo = 'Bar' }, [pscustomobject] @{ Foo = 'bar' } | |
| 140 | + Group-Object -Property Foo -CaseSensitive -AsHashtable |
| 141 | + ``` |
| 142 | +
|
| 143 | + ```Output |
| 144 | + Group-Object : The objects grouped by this property cannot be expanded |
| 145 | + because there is a key duplication. Provide a valid value for the |
| 146 | + property, and then try again. |
| 147 | + At line:2 char:11 |
| 148 | + + Group-Object -Property Foo -CaseSensitive -AsHashtable |
| 149 | + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 150 | + + CategoryInfo : InvalidArgument: (:) [Group-Object], Exception |
| 151 | + + FullyQualifiedErrorId : The objects grouped by this property |
| 152 | + cannot be expanded because there is a key duplication. Provide a valid |
| 153 | + value for the property, and then try again.,Microsoft.PowerShell.Comman |
| 154 | + ds.GroupObjectCommand |
| 155 | + ``` |
| 156 | +
|
| 157 | + - In PowerShell v7 and higher, `-CaseSensitive` and `-AsHashtable` produces a |
| 158 | + case-sensitive hashtable. No error occurs with duplicate keys. |
| 159 | +
|
| 160 | + ```powershell |
| 161 | + [pscustomobject] @{ Foo = 'Bar' }, [pscustomobject] @{ Foo = 'bar' } | |
| 162 | + Group-Object -Property Foo -CaseSensitive -AsHashtable |
| 163 | + ``` |
| 164 | +
|
| 165 | + ```Output |
| 166 | + Name Value |
| 167 | + ---- ----- |
| 168 | + Bar {@{Foo=Bar}} |
| 169 | + bar {@{Foo=bar}} |
| 170 | + ``` |
| 171 | +
|
| 172 | +- [`Select-String`][22]: |
| 173 | + - Case-insensitive by default, but does have a [`-CaseSensitive`][23] switch. |
| 174 | +
|
| 175 | +- [`Get-Command`][14] and command discovery/invocation: |
| 176 | + - On case-sensitive file systems, discovery and invocation of |
| 177 | + `ExternalScript` and `Application` command are case-sensitive. |
| 178 | + - `Get-Command` wildcard matching with these types is also case-sensitive. |
| 179 | + - All other [`CommandTypes`][26] are case-insensitive. |
| 180 | +
|
| 181 | +- [Comparison operators][03]: |
| 182 | + - By default, operators are case-insensitive. |
| 183 | + - `-c*` operators are case-sensitive. |
| 184 | + - `-i*` operators are case-insensitive. |
| 185 | + - `-replace`/`-ireplace` is case-insensitive by default, _except_ with [named |
| 186 | + capture groups][01], which are case-sensitive. |
| 187 | +
|
| 188 | + ```powershell |
| 189 | + 'Bar' -replace '(?<a>a)', '${a}${a}' |
| 190 | + # Baar |
| 191 | +
|
| 192 | + 'Bar' -replace '(?<a>a)', '${A}${A}' |
| 193 | + # B${A}${A}r |
| 194 | + ``` |
| 195 | +
|
| 196 | +- [`-split` operator](about_split): |
| 197 | + - `-split` and `-isplit` are case-insensitive. |
| 198 | + - `-csplit` is case-sensitive, _unless_ the `IgnoreCase` option is specified. |
| 199 | +
|
| 200 | + ```powershell |
| 201 | + 'Bar' -csplit 'A', 0 |
| 202 | + # Bar |
| 203 | +
|
| 204 | + 'Bar' -csplit 'A', 0, 'IgnoreCase' |
| 205 | + # B |
| 206 | + # r |
| 207 | + ``` |
| 208 | +
|
| 209 | +- [Tab completion][07]: |
| 210 | + - On case-sensitive file systems, tab completion and globbing are both |
| 211 | + case-insensitive. For example, `TabExpansion2 -inputScript ./foo` will |
| 212 | + complete to `./Foo.txt` on Linux. |
| 213 | +
|
| 214 | +- [`using`][08] statement: |
| 215 | + - On case-sensitive file systems, `using module` and `using assembly` are |
| 216 | + case-sensitive when a path is specified. |
| 217 | + - `using module` with just a module name is case-insensitive. |
| 218 | + - `using namespace` is always case-insensitive. |
| 219 | +
|
| 220 | +- [Special characters][06]: |
| 221 | + - Escape sequences like `` `n `` are case-sensitive. |
47 | 222 |
|
48 | 223 | ## See also |
49 | 224 |
|
50 | | -- [about_Environment_Variables](about_Environment_Variables.md) |
51 | | -- [Import-Module](xref:Microsoft.PowerShell.Core.Import-Module) |
| 225 | +- [about_Environment_Variables][04] |
| 226 | +- [Import-Module][19] |
| 227 | +
|
| 228 | +<!-- link references --> |
| 229 | +[01]: /dotnet/standard/base-types/substitutions-in-regular-expressions#substituting-a-named-group |
| 230 | +[02]: /powershell/scripting/developer/provider/provider-cmdlets |
| 231 | +[03]: about_comparison_operators.md |
| 232 | +[04]: about_Environment_Variables.md |
| 233 | +[05]: about_providers.md |
| 234 | +[06]: about_special_characters.md |
| 235 | +[07]: about_tab_expansion.md |
| 236 | +[08]: about_using.md |
| 237 | +[09]: about_wildcards.md |
| 238 | +[11]: xref:Microsoft.PowerShell.Core.Compare-Object |
| 239 | +[12]: xref:Microsoft.PowerShell.Core.Compare-Object#-casesensitive |
| 240 | +[13]: xref:Microsoft.PowerShell.Core.ConvertFrom-Json#-ashashtable |
| 241 | +[14]: xref:Microsoft.PowerShell.Core.Get-Command |
| 242 | +[15]: xref:Microsoft.PowerShell.Core.Get-Unique |
| 243 | +[16]: xref:Microsoft.PowerShell.Core.Group-Object |
| 244 | +[17]: xref:Microsoft.PowerShell.Core.Group-Object#-ashashtable |
| 245 | +[18]: xref:Microsoft.PowerShell.Core.Group-Object#-casesensitive |
| 246 | +[19]: xref:Microsoft.PowerShell.Core.Import-Module |
| 247 | +[20]: xref:Microsoft.PowerShell.Core.Select-Object#-caseinsensitive |
| 248 | +[21]: xref:Microsoft.PowerShell.Core.Select-Object#-unique |
| 249 | +[22]: xref:Microsoft.PowerShell.Core.Select-String |
| 250 | +[23]: xref:Microsoft.PowerShell.Core.Select-String#-casesensitive |
| 251 | +[24]: xref:Microsoft.PowerShell.Core.Sort-Object#-casesensitive |
| 252 | +[25]: xref:Microsoft.PowerShell.Core.Sort-Object#-unique |
| 253 | +[26]: xref:System.Management.Automation.CommandTypes |
| 254 | +[27]: xref:System.Management.Automation.OrderedHashtable |
0 commit comments