Skip to content

Commit c0c8099

Browse files
committed
Add more specific cases of sensitivity
1 parent 2dc6dda commit c0c8099

4 files changed

Lines changed: 892 additions & 80 deletions

File tree

Lines changed: 223 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,254 @@
11
---
22
description: This article explains how PowerShell handles case-sensitivity.
33
Locale: en-US
4-
ms.custom: wiki-migration
5-
ms.date: 06/06/2022
4+
ms.date: 01/06/2026
65
online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_case-sensitivity?view=powershell-5.1&WT.mc_id=ps-gethelp
76
title: about_Case-Sensitivity
87
---
98
# about_Case-Sensitivity
109

1110
## Short description
1211

13-
PowerShell is as case-insensitive as possible while preserving case.
12+
PowerShell is as case-insensitive while preserving case.
1413

1514
## Long description
1615

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
1817
preserving case and not breaking the underlying OS.
1918

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.
2122

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:
2525

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
2740

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
3242

3343
- Module names are case-insensitive (with exceptions)
3444

3545
The _name_ of the module is purely a PowerShell concept and treated
3646
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
3848
modules with the same case-insensitive name has the same behavior as
3949
importing two modules with the same name from different paths.
4050

4151
The name of a module is stored in the session state using the case by which
4252
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.
47222
48223
## See also
49224
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

Comments
 (0)