diff --git a/reference/5.1/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md b/reference/5.1/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md index 7ebfb8ef8be3..feef1af2271d 100644 --- a/reference/5.1/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md +++ b/reference/5.1/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md @@ -1,8 +1,7 @@ --- description: This article explains how PowerShell handles case-sensitivity. Locale: en-US -ms.custom: wiki-migration -ms.date: 06/06/2022 +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 --- @@ -14,38 +13,246 @@ PowerShell is as case-insensitive as possible while preserving case. ## Long description -As a general principle, PowerShell is as case insensitive as possible while +As a general principle, PowerShell is case-insensitive wherever possible while preserving case and not breaking the underlying OS. -### On Unix-based systems +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. -On Unix-based systems, PowerShell is case-sensitive because filesystem -manipulation and environment variables directly affect the underlying -operating system and integration with other tools. +PowerShell is guaranteed to be case-insensitive on all systems for the +following areas: -## On all systems +- 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 namespace` statements +- Type literals +- `#Requires` statements +- Comment-based help keywords +- PSProvider names +- PSDrive names +- Scope modifiers -- PowerShell variables are case-insensitive - - Variable names have no interaction between them and the underlying operating - system. PowerShell treats them case-insensitively. +## Special cases - 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| + 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 - `Update-Help` when looking for new help files. - The web service that serves the help files for Microsoft uses a - case-sensitive filesystem. When the case of the imported name of the module - doesn't match, `Update-Help` can't find the help files and reports an error. + by `Update-Help` when 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-Help` can't find + the help files and reports an error. + +- [PS providers][05]: + + The `FileSystem` and `Environment` providers are case-sensitive on + non-Windows systems. Generally, operations involving paths or environment + variables are case-sensitive on such systems. + + However, [wildcard matching][09] by [provider cmdlets][02] is + case-insensitive, irrespective of the system. + + ```powershell + 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 `DefaultParameterSetName` case must be identical to `ParameterSetName`. + +- .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. + +- `-Unique` cmdlets: + - [`Select-Object -Unique`][21] and [`Get-Unique`][15] are case-sensitive by + default. The [`-CaseInsensitive`][20] switch was added in PS v7.4. + - [`Sort-Object -Unique`][25] is case-insensitive by default, but has always + had the [`-CaseSensitive`][24] switch. + +- [`Compare-Object`][11] is case-insensitive by default, but has a + [`-CaseSensitive`][12] switch. Comparison of `[char]` types is case-sensitive + by default. String comparison is case-insensitive by default. + + ```powershell + # 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`][13]: + - `-AsHashtable` was 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.OrderedHashtable`][27] is 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. + - https://github.com/PowerShell/PowerShell/issues/19928 + +- [`Group-Object`][16]: + - Case-insensitive by default, but does have a [`-CaseSensitive`][18] + switch. + - In Windows PowerShell v5.1, `-CaseSensitive` and [`-AsHashtable`][17] + produces a case-insensitive hashtable. Duplicate keys result in an error. + + ```powershell + [pscustomobject] @{ Foo = 'Bar' }, [pscustomobject] @{ Foo = 'bar' } | + Group-Object -Property Foo -CaseSensitive -AsHashtable + ``` + + ```Output + 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, `-CaseSensitive` and `-AsHashtable` produces a + case-sensitive hashtable. No error occurs with duplicate keys. + + ```powershell + [pscustomobject] @{ Foo = 'Bar' }, [pscustomobject] @{ Foo = 'bar' } | + Group-Object -Property Foo -CaseSensitive -AsHashtable + ``` + + ```Output + Name Value + ---- ----- + Bar {@{Foo=Bar}} + bar {@{Foo=bar}} + ``` + +- [`Select-String`][22]: + - Case-insensitive by default, but does have a [`-CaseSensitive`][23] switch. + +- [`Get-Command`][14] and command discovery/invocation: + - On case-sensitive file systems, discovery and invocation of + `ExternalScript` and `Application` command are case-sensitive. + - `Get-Command` wildcard matching with these types is also case-sensitive. + - All other [`CommandTypes`][26] are case-insensitive. + +- [Comparison operators][03]: + - By default, operators are case-insensitive. + - `-c*` operators are case-sensitive. + - `-i*` operators are case-insensitive. + - `-replace`/`-ireplace` is case-insensitive by default, _except_ with [named + capture groups][01], which are case-sensitive. + + ```powershell + 'Bar' -replace '(?a)', '${a}${a}' + # Baar + + 'Bar' -replace '(?a)', '${A}${A}' + # B${A}${A}r + ``` + +- [`-split` operator][10]: + - `-split` and `-isplit` are case-insensitive. + - `-csplit` is case-sensitive, _unless_ the `IgnoreCase` option is specified. + + ```powershell + 'Bar' -csplit 'A', 0 + # Bar + + 'Bar' -csplit 'A', 0, 'IgnoreCase' + # B + # r + ``` + +- [Tab completion][07]: + - On case-sensitive file systems, tab completion and globbing are both + case-insensitive. For example, `TabExpansion2 -inputScript ./foo` will + complete to `./Foo.txt` on Linux. + +- [`using`][08] statement: + - On case-sensitive file systems, `using module` and `using assembly` are + case-sensitive when a path is specified. + - `using module` with just a module name is case-insensitive. + - `using namespace` is always case-insensitive. + +- [Special characters][06]: + - Escape sequences like `` `n `` are case-sensitive. ## See also -- [about_Environment_Variables](about_Environment_Variables.md) -- [Import-Module](xref:Microsoft.PowerShell.Core.Import-Module) +- [about_Environment_Variables][04] +- [Import-Module][19] + + +[01]: /dotnet/standard/base-types/substitutions-in-regular-expressions#substituting-a-named-group +[02]: /powershell/scripting/developer/provider/provider-cmdlets +[03]: about_comparison_operators.md +[04]: about_Environment_Variables.md +[05]: about_providers.md +[06]: about_special_characters.md +[07]: about_tab_expansion.md +[08]: about_using.md +[09]: about_wildcards.md +[10]: about_split.md +[11]: xref:Microsoft.PowerShell.Utility.Compare-Object +[12]: xref:Microsoft.PowerShell.Utility.Compare-Object#-casesensitive +[13]: xref:Microsoft.PowerShell.Utility.ConvertFrom-Json#-ashashtable +[14]: xref:Microsoft.PowerShell.Core.Get-Command +[15]: xref:Microsoft.PowerShell.Utility.Get-Unique +[16]: xref:Microsoft.PowerShell.Utility.Group-Object +[17]: xref:Microsoft.PowerShell.Utility.Group-Object#-ashashtable +[18]: xref:Microsoft.PowerShell.Utility.Group-Object#-casesensitive +[19]: xref:Microsoft.PowerShell.Core.Import-Module +[20]: xref:Microsoft.PowerShell.Utility.Select-Object#-caseinsensitive +[21]: xref:Microsoft.PowerShell.Utility.Select-Object#-unique +[22]: xref:Microsoft.PowerShell.Utility.Select-String +[23]: xref:Microsoft.PowerShell.Utility.Select-String#-casesensitive +[24]: xref:Microsoft.PowerShell.Utility.Sort-Object#-casesensitive +[25]: xref:Microsoft.PowerShell.Utility.Sort-Object#-unique +[26]: xref:System.Management.Automation.CommandTypes +[27]: xref:System.Management.Automation.OrderedHashtable diff --git a/reference/5.1/Microsoft.PowerShell.Diagnostics/Get-WinEvent.md b/reference/5.1/Microsoft.PowerShell.Diagnostics/Get-WinEvent.md index 0e7744168ee8..114bff329130 100644 --- a/reference/5.1/Microsoft.PowerShell.Diagnostics/Get-WinEvent.md +++ b/reference/5.1/Microsoft.PowerShell.Diagnostics/Get-WinEvent.md @@ -78,7 +78,7 @@ selected event providers. And, you can combine events from multiple sources in a `Get-WinEvent` allows you to filter events using XPath queries, structured XML queries, and hash table queries. -If you're not running PowerShell as an Administrator, you might see error messages that you cannot +If you're not running PowerShell as an Administrator, you might see error messages that you can't retrieve information about a log. ## EXAMPLES @@ -160,7 +160,7 @@ try{ $log.SaveChanges() Get-WinEvent -ListLog Security | Format-List -Property * }catch [System.UnauthorizedAccessException]{ - $ErrMsg = 'You do not have permission to configure this log!' + $ErrMsg = 'You don't have permission to configure this log!' $ErrMsg += ' Try running this script with administrator privileges. ' $ErrMsg += $_.Exception.Message Write-Error $ErrMsg @@ -445,7 +445,7 @@ other properties from the output. The grouped objects are sent down the pipeline ### Example 12: Get events from an archived event log `Get-WinEvent` can get event information from saved log files. This sample uses an archived -PowerShell log that is stored on the local computer. +PowerShell log that's stored on the local computer. ```powershell Get-WinEvent -Path 'C:\Test\Windows PowerShell.evtx' @@ -470,7 +470,7 @@ the directory and file name. These commands get a specific number of events from an archived event log. `Get-WinEvent` has parameters that can get a maximum number of events or the oldest events. This sample uses an -archived PowerShell log that is stored in **C:\Test\PowerShellCore Operational.evtx**. +archived PowerShell log that's stored in **C:\Test\PowerShellCore Operational.evtx**. ```powershell Get-WinEvent -Path 'C:\Test\PowerShellCore Operational.evtx' -MaxEvents 100 @@ -498,7 +498,7 @@ from newest to oldest. Event Tracing for Windows (ETW) writes events to the log as events occur. The events are stored in the order of oldest to newest. An archived ETW file is saved as an `.etl` such as **TraceLog.etl**. -The events are listed in the order in which they are written to the log, so the *Oldest* parameter +The events are listed in the order in which they're written to the log, so the *Oldest* parameter is required. ```powershell @@ -509,7 +509,7 @@ Get-WinEvent -Path 'C:\Tracing\TraceLog.etl' -Oldest | The `Get-WinEvent` cmdlet gets log information from the archived file. The **Path** parameter specifies the directory and file name. The **Oldest** parameter is used to output events in the -order they are written, oldest to newest. The objects are sent down the pipeline to the +order they're written, oldest to newest. The objects are sent down the pipeline to the `Sort-Object` cmdlet `Sort-Object` sorts the objects in descending order by the value of the **TimeCreated** property. The objects are sent down the pipeline to the `Select-Object` cmdlet that displays the 100 newest events. @@ -519,7 +519,7 @@ displays the 100 newest events. This example shows how to get the events from an event trace log file (`.etl`) and an archived Windows PowerShell log file (`.evtx`). You can combine multiple file types in a single command. Because the files contain the same type of **.NET Framework** object, **EventLogRecord**, you can -filter them with the same properties. The command requires the **Oldest** parameter because it is +filter them with the same properties. The command requires the **Oldest** parameter because it's reading from an `.etl` file, but the **Oldest** parameter applies to each file. ```powershell @@ -529,7 +529,7 @@ Get-WinEvent -Path 'C:\Tracing\TraceLog.etl', 'C:\Test\Windows PowerShell.evtx' The `Get-WinEvent` cmdlet gets log information from the archived files. The **Path** parameter uses a comma-separated list to specify each files directory and file name. The **Oldest** parameter is -used to output events in the order they are written, oldest to newest. The objects are sent down the +used to output events in the order they're written, oldest to newest. The objects are sent down the pipeline to the `Where-Object` cmdlet. `Where-Object` uses a script block to find events with an **Id** of **403**. The `$_` variable represents the current object in the pipeline and **Id** is the Event Id property. @@ -556,14 +556,14 @@ $xmlQuery = @' + TimeCreated[timediff(@SystemTime) <= 86400000]]] '@ Get-WinEvent -FilterXML $xmlQuery # Using the FilterXPath parameter: -$XPath = '*[System[Level=3 and TimeCreated[timediff(@SystemTime) &lt;= 86400000]]]' +$XPath = '*[System[Level=3 and TimeCreated[timediff(@SystemTime) <= 86400000]]]' Get-WinEvent -LogName 'Windows PowerShell' -FilterXPath $XPath ``` @@ -571,15 +571,17 @@ Get-WinEvent -LogName 'Windows PowerShell' -FilterXPath $XPath This example uses the **FilterHashtable** parameter to get events from the **Application** log. The hash table uses **key/value** pairs. For more information about the **FilterHashtable** parameter, -see [Creating Get-WinEvent queries with FilterHashtable](/powershell/scripting/samples/Creating-Get-WinEvent-queries-with-FilterHashtable). -For more information about hash tables, see [about_Hash_Tables](../Microsoft.PowerShell.Core/about/about_hash_tables.md). +see +[Creating Get-WinEvent queries with FilterHashtable](/powershell/scripting/samples/Creating-Get-WinEvent-queries-with-FilterHashtable). +For more information about hash tables, see +[about_Hash_Tables](../Microsoft.PowerShell.Core/about/about_hash_tables.md). ```powershell $Date = (Get-Date).AddDays(-2) Get-WinEvent -FilterHashtable @{ LogName='Application'; StartTime=$Date; Id='1003' } ``` -The `Get-Date` cmdlet uses the **AddDays** method to get a date that is two days before the current +The `Get-Date` cmdlet uses the **AddDays** method to get a date that's two days before the current date. The date object is stored in the `$Date` variable. The `Get-WinEvent` cmdlet gets log information. The **FilterHashtable** parameter is used to filter @@ -601,7 +603,7 @@ Get-WinEvent -FilterHashtable @{ } ``` -The `Get-Date` cmdlet uses the **AddDays** method to get a date that is seven days before the +The `Get-Date` cmdlet uses the **AddDays** method to get a date that's seven days before the current date. The date object is stored in the `$StartTime` variable. The `Get-WinEvent` cmdlet gets log information. The **FilterHashtable** parameter is used to filter @@ -620,8 +622,8 @@ value is the local computer, **localhost**. This parameter accepts only one comp To get event logs from remote computers, configure the firewall port for the event log service to allow remote access. -This cmdlet does not rely on PowerShell remoting. You can use the **ComputerName** parameter even if -your computer is not configured to run remote commands. +This cmdlet doesn't rely on PowerShell remoting. You can use the **ComputerName** parameter even if +your computer isn't configured to run remote commands. ```yaml Type: System.String @@ -675,7 +677,7 @@ Hash table queries have the following rules: - The **Data** value takes event data in an unnamed field. For example, events in classic event logs. -When `Get-WinEvent` cannot interpret a **key/value** pair, it interprets the key as a case-sensitive +When `Get-WinEvent` can't interpret a **key/value** pair, it interprets the key as a case-sensitive name for the event data in the event. The valid `Get-WinEvent` **key/value** pairs are as follows: @@ -715,8 +717,9 @@ Help. Use an XML query to create a complex query that contains several XPath statements. The XML format also allows you to use a **Suppress XML** element that excludes events from the query. For more -information about the XML schema for event log queries, see [Query Schema](/windows/win32/wes/queryschema-schema) -and the XML Event Queries section of [Event Selection](/previous-versions/aa385231(v=vs.85)). +information about the XML schema for event log queries, see +[Query Schema](/windows/win32/wes/queryschema-schema) and the XML Event Queries section of +[Event Selection](/previous-versions/aa385231(v=vs.85)). ```yaml Type: System.Xml.XmlDocument @@ -734,8 +737,9 @@ Accept wildcard characters: False Specifies an XPath query that this cmdlet select events from one or more logs. -For more information about the XPath language, see [XPath Reference](/previous-versions/dotnet/netframework-4.0/ms256115(v=vs.100)) -and the Selection Filters section of [Event Selection](/previous-versions/aa385231(v=vs.85)). +For more information about the XPath language, see +[XPath Reference](/previous-versions/dotnet/netframework-4.0/ms256115(v=vs.100)) and the +_Selection Filters_ section of [Event Selection](/previous-versions/aa385231(v=vs.85)). ```yaml Type: System.String @@ -813,10 +817,10 @@ comma-separated list. Wildcards are permitted. You can also pipe log names to th cmdlet. > [!NOTE] -> PowerShell does not limit the amount of logs you can request. However, the `Get-WinEvent` cmdlet +> PowerShell doesn't limit the amount of logs you can request. However, the `Get-WinEvent` cmdlet > queries the Windows API which has a limit of 256. This can make it difficult to filter through all -> of your logs at one time. You can work around this by using a `foreach` loop to iterate through each -> log like this: `Get-WinEvent -ListLog * | ForEach-Object{ Get-WinEvent -LogName $_.LogName }` +> of your logs at one time. You can work around this by using a `foreach` loop to iterate through +> each log like this: `Get-WinEvent -ListLog * | ForEach-Object{ Get-WinEvent -LogName $_.LogName }` ```yaml Type: System.String[] @@ -894,7 +898,7 @@ Specifies, as a string array, the event log providers from which this cmdlet get provider names in a comma-separated list, or use wildcard characters to create provider name patterns. -An event log provider is a program or service that writes events to the event log. It is not a +An event log provider is a program or service that writes events to the event log. It isn't a PowerShell provider. ```yaml @@ -913,7 +917,8 @@ Accept wildcard characters: True This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, --WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS @@ -949,7 +954,7 @@ With the **ListProvider** parameter, this cmdlet returns **ProviderMetadata** ob and later versions of Windows. `Get-EventLog` gets events only in classic event logs. `Get-EventLog` is retained for backward compatibility. -The `Get-WinEvent` and `Get-EventLog` cmdlets are not supported in Windows Pre-installation +The `Get-WinEvent` and `Get-EventLog` cmdlets aren't supported in Windows Pre-installation Environment (Windows PE). ## RELATED LINKS diff --git a/reference/7.4/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md b/reference/7.4/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md index f90576be83cc..fe8e508ea829 100644 --- a/reference/7.4/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md +++ b/reference/7.4/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md @@ -1,8 +1,7 @@ --- description: This article explains how PowerShell handles case-sensitivity. Locale: en-US -ms.custom: wiki-migration -ms.date: 06/06/2022 +ms.date: 01/06/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_case-sensitivity?view=powershell-7.4&WT.mc_id=ps-gethelp title: about_Case-Sensitivity --- @@ -14,38 +13,246 @@ PowerShell is as case-insensitive as possible while preserving case. ## Long description -As a general principle, PowerShell is as case insensitive as possible while +As a general principle, PowerShell is case-insensitive wherever possible while preserving case and not breaking the underlying OS. -### On Unix-based systems +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. -On Unix-based systems, PowerShell is case-sensitive because filesystem -manipulation and environment variables directly affect the underlying -operating system and integration with other tools. +PowerShell is guaranteed to be case-insensitive on all systems for the +following areas: -## On all systems +- 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 namespace` statements +- Type literals +- `#Requires` statements +- Comment-based help keywords +- PSProvider names +- PSDrive names +- Scope modifiers -- PowerShell variables are case-insensitive - - Variable names have no interaction between them and the underlying operating - system. PowerShell treats them case-insensitively. +## Special cases - 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| + 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 - `Update-Help` when looking for new help files. - The web service that serves the help files for Microsoft uses a - case-sensitive filesystem. When the case of the imported name of the module - doesn't match, `Update-Help` can't find the help files and reports an error. + by `Update-Help` when 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-Help` can't find + the help files and reports an error. + +- [PS providers][05]: + + The `FileSystem` and `Environment` providers are case-sensitive on + non-Windows systems. Generally, operations involving paths or environment + variables are case-sensitive on such systems. + + However, [wildcard matching][09] by [provider cmdlets][02] is + case-insensitive, irrespective of the system. + + ```powershell + 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 `DefaultParameterSetName` case must be identical to `ParameterSetName`. + +- .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. + +- `-Unique` cmdlets: + - [`Select-Object -Unique`][21] and [`Get-Unique`][15] are case-sensitive by + default. The [`-CaseInsensitive`][20] switch was added in PS v7.4. + - [`Sort-Object -Unique`][25] is case-insensitive by default, but has always + had the [`-CaseSensitive`][24] switch. + +- [`Compare-Object`][11] is case-insensitive by default, but has a + [`-CaseSensitive`][12] switch. Comparison of `[char]` types is case-sensitive + by default. String comparison is case-insensitive by default. + + ```powershell + # 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`][13]: + - `-AsHashtable` was 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.OrderedHashtable`][27] is 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. + - https://github.com/PowerShell/PowerShell/issues/19928 + +- [`Group-Object`][16]: + - Case-insensitive by default, but does have a [`-CaseSensitive`][18] + switch. + - In Windows PowerShell v5.1, `-CaseSensitive` and [`-AsHashtable`][17] + produces a case-insensitive hashtable. Duplicate keys result in an error. + + ```powershell + [pscustomobject] @{ Foo = 'Bar' }, [pscustomobject] @{ Foo = 'bar' } | + Group-Object -Property Foo -CaseSensitive -AsHashtable + ``` + + ```Output + 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, `-CaseSensitive` and `-AsHashtable` produces a + case-sensitive hashtable. No error occurs with duplicate keys. + + ```powershell + [pscustomobject] @{ Foo = 'Bar' }, [pscustomobject] @{ Foo = 'bar' } | + Group-Object -Property Foo -CaseSensitive -AsHashtable + ``` + + ```Output + Name Value + ---- ----- + Bar {@{Foo=Bar}} + bar {@{Foo=bar}} + ``` + +- [`Select-String`][22]: + - Case-insensitive by default, but does have a [`-CaseSensitive`][23] switch. + +- [`Get-Command`][14] and command discovery/invocation: + - On case-sensitive file systems, discovery and invocation of + `ExternalScript` and `Application` command are case-sensitive. + - `Get-Command` wildcard matching with these types is also case-sensitive. + - All other [`CommandTypes`][26] are case-insensitive. + +- [Comparison operators][03]: + - By default, operators are case-insensitive. + - `-c*` operators are case-sensitive. + - `-i*` operators are case-insensitive. + - `-replace`/`-ireplace` is case-insensitive by default, _except_ with [named + capture groups][01], which are case-sensitive. + + ```powershell + 'Bar' -replace '(?a)', '${a}${a}' + # Baar + + 'Bar' -replace '(?a)', '${A}${A}' + # B${A}${A}r + ``` + +- [`-split` operator][10]: + - `-split` and `-isplit` are case-insensitive. + - `-csplit` is case-sensitive, _unless_ the `IgnoreCase` option is specified. + + ```powershell + 'Bar' -csplit 'A', 0 + # Bar + + 'Bar' -csplit 'A', 0, 'IgnoreCase' + # B + # r + ``` + +- [Tab completion][07]: + - On case-sensitive file systems, tab completion and globbing are both + case-insensitive. For example, `TabExpansion2 -inputScript ./foo` will + complete to `./Foo.txt` on Linux. + +- [`using`][08] statement: + - On case-sensitive file systems, `using module` and `using assembly` are + case-sensitive when a path is specified. + - `using module` with just a module name is case-insensitive. + - `using namespace` is always case-insensitive. + +- [Special characters][06]: + - Escape sequences like `` `n `` are case-sensitive. ## See also -- [about_Environment_Variables](about_Environment_Variables.md) -- [Import-Module](xref:Microsoft.PowerShell.Core.Import-Module) +- [about_Environment_Variables][04] +- [Import-Module][19] + + +[01]: /dotnet/standard/base-types/substitutions-in-regular-expressions#substituting-a-named-group +[02]: /powershell/scripting/developer/provider/provider-cmdlets +[03]: about_comparison_operators.md +[04]: about_Environment_Variables.md +[05]: about_providers.md +[06]: about_special_characters.md +[07]: about_tab_expansion.md +[08]: about_using.md +[09]: about_wildcards.md +[10]: about_split.md +[11]: xref:Microsoft.PowerShell.Utility.Compare-Object +[12]: xref:Microsoft.PowerShell.Utility.Compare-Object#-casesensitive +[13]: xref:Microsoft.PowerShell.Utility.ConvertFrom-Json#-ashashtable +[14]: xref:Microsoft.PowerShell.Core.Get-Command +[15]: xref:Microsoft.PowerShell.Utility.Get-Unique +[16]: xref:Microsoft.PowerShell.Utility.Group-Object +[17]: xref:Microsoft.PowerShell.Utility.Group-Object#-ashashtable +[18]: xref:Microsoft.PowerShell.Utility.Group-Object#-casesensitive +[19]: xref:Microsoft.PowerShell.Core.Import-Module +[20]: xref:Microsoft.PowerShell.Utility.Select-Object#-caseinsensitive +[21]: xref:Microsoft.PowerShell.Utility.Select-Object#-unique +[22]: xref:Microsoft.PowerShell.Utility.Select-String +[23]: xref:Microsoft.PowerShell.Utility.Select-String#-casesensitive +[24]: xref:Microsoft.PowerShell.Utility.Sort-Object#-casesensitive +[25]: xref:Microsoft.PowerShell.Utility.Sort-Object#-unique +[26]: xref:System.Management.Automation.CommandTypes +[27]: xref:System.Management.Automation.OrderedHashtable diff --git a/reference/7.4/Microsoft.PowerShell.Diagnostics/Get-WinEvent.md b/reference/7.4/Microsoft.PowerShell.Diagnostics/Get-WinEvent.md index 3b8e233390e8..d0a69688054e 100644 --- a/reference/7.4/Microsoft.PowerShell.Diagnostics/Get-WinEvent.md +++ b/reference/7.4/Microsoft.PowerShell.Diagnostics/Get-WinEvent.md @@ -80,7 +80,7 @@ selected event providers. And, you can combine events from multiple sources in a `Get-WinEvent` allows you to filter events using XPath queries, structured XML queries, and hash table queries. -If you're not running PowerShell as an Administrator, you might see error messages that you cannot +If you're not running PowerShell as an Administrator, you might see error messages that you can't retrieve information about a log. ## EXAMPLES @@ -162,7 +162,7 @@ try{ $log.SaveChanges() Get-WinEvent -ListLog Security | Format-List -Property * }catch [System.UnauthorizedAccessException]{ - $ErrMsg = 'You do not have permission to configure this log!' + $ErrMsg = 'You don't have permission to configure this log!' $ErrMsg += ' Try running this script with administrator privileges. ' $ErrMsg += $_.Exception.Message Write-Error $ErrMsg @@ -447,7 +447,7 @@ other properties from the output. The grouped objects are sent down the pipeline ### Example 12: Get events from an archived event log `Get-WinEvent` can get event information from saved log files. This sample uses an archived -PowerShell log that is stored on the local computer. +PowerShell log that's stored on the local computer. ```powershell Get-WinEvent -Path 'C:\Test\Windows PowerShell.evtx' @@ -472,7 +472,7 @@ the directory and file name. These commands get a specific number of events from an archived event log. `Get-WinEvent` has parameters that can get a maximum number of events or the oldest events. This sample uses an -archived PowerShell log that is stored in **C:\Test\PowerShellCore Operational.evtx**. +archived PowerShell log that's stored in **C:\Test\PowerShellCore Operational.evtx**. ```powershell Get-WinEvent -Path 'C:\Test\PowerShellCore Operational.evtx' -MaxEvents 100 @@ -500,7 +500,7 @@ from newest to oldest. Event Tracing for Windows (ETW) writes events to the log as events occur. The events are stored in the order of oldest to newest. An archived ETW file is saved as an `.etl` such as **TraceLog.etl**. -The events are listed in the order in which they are written to the log, so the *Oldest* parameter +The events are listed in the order in which they're written to the log, so the *Oldest* parameter is required. ```powershell @@ -511,7 +511,7 @@ Get-WinEvent -Path 'C:\Tracing\TraceLog.etl' -Oldest | The `Get-WinEvent` cmdlet gets log information from the archived file. The **Path** parameter specifies the directory and file name. The **Oldest** parameter is used to output events in the -order they are written, oldest to newest. The objects are sent down the pipeline to the +order they're written, oldest to newest. The objects are sent down the pipeline to the `Sort-Object` cmdlet `Sort-Object` sorts the objects in descending order by the value of the **TimeCreated** property. The objects are sent down the pipeline to the `Select-Object` cmdlet that displays the 100 newest events. @@ -521,7 +521,7 @@ displays the 100 newest events. This example shows how to get the events from an event trace log file (`.etl`) and an archived Windows PowerShell log file (`.evtx`). You can combine multiple file types in a single command. Because the files contain the same type of **.NET Framework** object, **EventLogRecord**, you can -filter them with the same properties. The command requires the **Oldest** parameter because it is +filter them with the same properties. The command requires the **Oldest** parameter because it's reading from an `.etl` file, but the **Oldest** parameter applies to each file. ```powershell @@ -531,7 +531,7 @@ Get-WinEvent -Path 'C:\Tracing\TraceLog.etl', 'C:\Test\Windows PowerShell.evtx' The `Get-WinEvent` cmdlet gets log information from the archived files. The **Path** parameter uses a comma-separated list to specify each files directory and file name. The **Oldest** parameter is -used to output events in the order they are written, oldest to newest. The objects are sent down the +used to output events in the order they're written, oldest to newest. The objects are sent down the pipeline to the `Where-Object` cmdlet. `Where-Object` uses a script block to find events with an **Id** of **403**. The `$_` variable represents the current object in the pipeline and **Id** is the Event Id property. @@ -558,14 +558,14 @@ $xmlQuery = @' + TimeCreated[timediff(@SystemTime) <= 86400000]]] '@ Get-WinEvent -FilterXML $xmlQuery # Using the FilterXPath parameter: -$XPath = '*[System[Level=3 and TimeCreated[timediff(@SystemTime) &lt;= 86400000]]]' +$XPath = '*[System[Level=3 and TimeCreated[timediff(@SystemTime) <= 86400000]]]' Get-WinEvent -LogName 'Windows PowerShell' -FilterXPath $XPath ``` @@ -573,15 +573,17 @@ Get-WinEvent -LogName 'Windows PowerShell' -FilterXPath $XPath This example uses the **FilterHashtable** parameter to get events from the **Application** log. The hash table uses **key/value** pairs. For more information about the **FilterHashtable** parameter, -see [Creating Get-WinEvent queries with FilterHashtable](/powershell/scripting/samples/Creating-Get-WinEvent-queries-with-FilterHashtable). -For more information about hash tables, see [about_Hash_Tables](../Microsoft.PowerShell.Core/about/about_hash_tables.md). +see +[Creating Get-WinEvent queries with FilterHashtable](/powershell/scripting/samples/Creating-Get-WinEvent-queries-with-FilterHashtable). +For more information about hash tables, see +[about_Hash_Tables](../Microsoft.PowerShell.Core/about/about_hash_tables.md). ```powershell $Date = (Get-Date).AddDays(-2) Get-WinEvent -FilterHashtable @{ LogName='Application'; StartTime=$Date; Id='1003' } ``` -The `Get-Date` cmdlet uses the **AddDays** method to get a date that is two days before the current +The `Get-Date` cmdlet uses the **AddDays** method to get a date that's two days before the current date. The date object is stored in the `$Date` variable. The `Get-WinEvent` cmdlet gets log information. The **FilterHashtable** parameter is used to filter @@ -603,7 +605,7 @@ Get-WinEvent -FilterHashtable @{ } ``` -The `Get-Date` cmdlet uses the **AddDays** method to get a date that is seven days before the +The `Get-Date` cmdlet uses the **AddDays** method to get a date that's seven days before the current date. The date object is stored in the `$StartTime` variable. The `Get-WinEvent` cmdlet gets log information. The **FilterHashtable** parameter is used to filter @@ -641,8 +643,8 @@ value is the local computer, **localhost**. This parameter accepts only one comp To get event logs from remote computers, configure the firewall port for the event log service to allow remote access. -This cmdlet does not rely on PowerShell remoting. You can use the **ComputerName** parameter even if -your computer is not configured to run remote commands. +This cmdlet doesn't rely on PowerShell remoting. You can use the **ComputerName** parameter even if +your computer isn't configured to run remote commands. ```yaml Type: System.String @@ -697,7 +699,7 @@ Hash table queries have the following rules: logs. - `` key represents a named event data field. -When `Get-WinEvent` cannot interpret a **key/value** pair, it interprets the key as a case-sensitive +When `Get-WinEvent` can't interpret a **key/value** pair, it interprets the key as a case-sensitive name for the event data in the event. The valid `Get-WinEvent` **key/value** pairs are as follows: @@ -739,8 +741,9 @@ Help. Use an XML query to create a complex query that contains several XPath statements. The XML format also allows you to use a **Suppress XML** element that excludes events from the query. For more -information about the XML schema for event log queries, see [Query Schema](/windows/win32/wes/queryschema-schema) -and the XML Event Queries section of [Event Selection](/previous-versions/aa385231(v=vs.85)). +information about the XML schema for event log queries, see +[Query Schema](/windows/win32/wes/queryschema-schema) and the XML Event Queries section of +[Event Selection](/previous-versions/aa385231(v=vs.85)). You may also create a **Suppress** element using the **FilterHashtable** parameter. @@ -760,8 +763,9 @@ Accept wildcard characters: False Specifies an XPath query that this cmdlet select events from one or more logs. -For more information about the XPath language, see [XPath Reference](/previous-versions/dotnet/netframework-4.0/ms256115(v=vs.100)) -and the Selection Filters section of [Event Selection](/previous-versions/aa385231(v=vs.85)). +For more information about the XPath language, see +[XPath Reference](/previous-versions/dotnet/netframework-4.0/ms256115(v=vs.100)) and the +_Selection Filters_ section of [Event Selection](/previous-versions/aa385231(v=vs.85)). ```yaml Type: System.String @@ -839,10 +843,10 @@ comma-separated list. Wildcards are permitted. You can also pipe log names to th cmdlet. > [!NOTE] -> PowerShell does not limit the amount of logs you can request. However, the `Get-WinEvent` cmdlet +> PowerShell doesn't limit the amount of logs you can request. However, the `Get-WinEvent` cmdlet > queries the Windows API which has a limit of 256. This can make it difficult to filter through all -> of your logs at one time. You can work around this by using a `foreach` loop to iterate through each -> log like this: `Get-WinEvent -ListLog * | ForEach-Object{ Get-WinEvent -LogName $_.LogName }` +> of your logs at one time. You can work around this by using a `foreach` loop to iterate through +> each log like this: `Get-WinEvent -ListLog * | ForEach-Object{ Get-WinEvent -LogName $_.LogName }` ```yaml Type: System.String[] @@ -920,7 +924,7 @@ Specifies, as a string array, the event log providers from which this cmdlet get provider names in a comma-separated list, or use wildcard characters to create provider name patterns. -An event log provider is a program or service that writes events to the event log. It is not a +An event log provider is a program or service that writes events to the event log. It isn't a PowerShell provider. ```yaml @@ -939,7 +943,8 @@ Accept wildcard characters: True This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, --WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS @@ -975,7 +980,7 @@ With the **ListProvider** parameter, this cmdlet returns **ProviderMetadata** ob and later versions of Windows. `Get-EventLog` gets events only in classic event logs. `Get-EventLog` is retained for backward compatibility. -The `Get-WinEvent` and `Get-EventLog` cmdlets are not supported in Windows Pre-installation +The `Get-WinEvent` and `Get-EventLog` cmdlets aren't supported in Windows Pre-installation Environment (Windows PE). ## RELATED LINKS diff --git a/reference/7.5/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md b/reference/7.5/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md index 9e10e094c21f..411f0001cf84 100644 --- a/reference/7.5/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md +++ b/reference/7.5/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md @@ -1,8 +1,7 @@ --- description: This article explains how PowerShell handles case-sensitivity. Locale: en-US -ms.custom: wiki-migration -ms.date: 06/06/2022 +ms.date: 01/06/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_case-sensitivity?view=powershell-7.5&WT.mc_id=ps-gethelp title: about_Case-Sensitivity --- @@ -14,38 +13,246 @@ PowerShell is as case-insensitive as possible while preserving case. ## Long description -As a general principle, PowerShell is as case insensitive as possible while +As a general principle, PowerShell is case-insensitive wherever possible while preserving case and not breaking the underlying OS. -### On Unix-based systems +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. -On Unix-based systems, PowerShell is case-sensitive because filesystem -manipulation and environment variables directly affect the underlying -operating system and integration with other tools. +PowerShell is guaranteed to be case-insensitive on all systems for the +following areas: -## On all systems +- 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 namespace` statements +- Type literals +- `#Requires` statements +- Comment-based help keywords +- PSProvider names +- PSDrive names +- Scope modifiers -- PowerShell variables are case-insensitive - - Variable names have no interaction between them and the underlying operating - system. PowerShell treats them case-insensitively. +## Special cases - 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| + 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 - `Update-Help` when looking for new help files. - The web service that serves the help files for Microsoft uses a - case-sensitive filesystem. When the case of the imported name of the module - doesn't match, `Update-Help` can't find the help files and reports an error. + by `Update-Help` when 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-Help` can't find + the help files and reports an error. + +- [PS providers][05]: + + The `FileSystem` and `Environment` providers are case-sensitive on + non-Windows systems. Generally, operations involving paths or environment + variables are case-sensitive on such systems. + + However, [wildcard matching][09] by [provider cmdlets][02] is + case-insensitive, irrespective of the system. + + ```powershell + 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 `DefaultParameterSetName` case must be identical to `ParameterSetName`. + +- .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. + +- `-Unique` cmdlets: + - [`Select-Object -Unique`][21] and [`Get-Unique`][15] are case-sensitive by + default. The [`-CaseInsensitive`][20] switch was added in PS v7.4. + - [`Sort-Object -Unique`][25] is case-insensitive by default, but has always + had the [`-CaseSensitive`][24] switch. + +- [`Compare-Object`][11] is case-insensitive by default, but has a + [`-CaseSensitive`][12] switch. Comparison of `[char]` types is case-sensitive + by default. String comparison is case-insensitive by default. + + ```powershell + # 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`][13]: + - `-AsHashtable` was 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.OrderedHashtable`][27] is 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. + - https://github.com/PowerShell/PowerShell/issues/19928 + +- [`Group-Object`][16]: + - Case-insensitive by default, but does have a [`-CaseSensitive`][18] + switch. + - In Windows PowerShell v5.1, `-CaseSensitive` and [`-AsHashtable`][17] + produces a case-insensitive hashtable. Duplicate keys result in an error. + + ```powershell + [pscustomobject] @{ Foo = 'Bar' }, [pscustomobject] @{ Foo = 'bar' } | + Group-Object -Property Foo -CaseSensitive -AsHashtable + ``` + + ```Output + 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, `-CaseSensitive` and `-AsHashtable` produces a + case-sensitive hashtable. No error occurs with duplicate keys. + + ```powershell + [pscustomobject] @{ Foo = 'Bar' }, [pscustomobject] @{ Foo = 'bar' } | + Group-Object -Property Foo -CaseSensitive -AsHashtable + ``` + + ```Output + Name Value + ---- ----- + Bar {@{Foo=Bar}} + bar {@{Foo=bar}} + ``` + +- [`Select-String`][22]: + - Case-insensitive by default, but does have a [`-CaseSensitive`][23] switch. + +- [`Get-Command`][14] and command discovery/invocation: + - On case-sensitive file systems, discovery and invocation of + `ExternalScript` and `Application` command are case-sensitive. + - `Get-Command` wildcard matching with these types is also case-sensitive. + - All other [`CommandTypes`][26] are case-insensitive. + +- [Comparison operators][03]: + - By default, operators are case-insensitive. + - `-c*` operators are case-sensitive. + - `-i*` operators are case-insensitive. + - `-replace`/`-ireplace` is case-insensitive by default, _except_ with [named + capture groups][01], which are case-sensitive. + + ```powershell + 'Bar' -replace '(?a)', '${a}${a}' + # Baar + + 'Bar' -replace '(?a)', '${A}${A}' + # B${A}${A}r + ``` + +- [`-split` operator][10]: + - `-split` and `-isplit` are case-insensitive. + - `-csplit` is case-sensitive, _unless_ the `IgnoreCase` option is specified. + + ```powershell + 'Bar' -csplit 'A', 0 + # Bar + + 'Bar' -csplit 'A', 0, 'IgnoreCase' + # B + # r + ``` + +- [Tab completion][07]: + - On case-sensitive file systems, tab completion and globbing are both + case-insensitive. For example, `TabExpansion2 -inputScript ./foo` will + complete to `./Foo.txt` on Linux. + +- [`using`][08] statement: + - On case-sensitive file systems, `using module` and `using assembly` are + case-sensitive when a path is specified. + - `using module` with just a module name is case-insensitive. + - `using namespace` is always case-insensitive. + +- [Special characters][06]: + - Escape sequences like `` `n `` are case-sensitive. ## See also -- [about_Environment_Variables](about_Environment_Variables.md) -- [Import-Module](xref:Microsoft.PowerShell.Core.Import-Module) +- [about_Environment_Variables][04] +- [Import-Module][19] + + +[01]: /dotnet/standard/base-types/substitutions-in-regular-expressions#substituting-a-named-group +[02]: /powershell/scripting/developer/provider/provider-cmdlets +[03]: about_comparison_operators.md +[04]: about_Environment_Variables.md +[05]: about_providers.md +[06]: about_special_characters.md +[07]: about_tab_expansion.md +[08]: about_using.md +[09]: about_wildcards.md +[10]: about_split.md +[11]: xref:Microsoft.PowerShell.Utility.Compare-Object +[12]: xref:Microsoft.PowerShell.Utility.Compare-Object#-casesensitive +[13]: xref:Microsoft.PowerShell.Utility.ConvertFrom-Json#-ashashtable +[14]: xref:Microsoft.PowerShell.Core.Get-Command +[15]: xref:Microsoft.PowerShell.Utility.Get-Unique +[16]: xref:Microsoft.PowerShell.Utility.Group-Object +[17]: xref:Microsoft.PowerShell.Utility.Group-Object#-ashashtable +[18]: xref:Microsoft.PowerShell.Utility.Group-Object#-casesensitive +[19]: xref:Microsoft.PowerShell.Core.Import-Module +[20]: xref:Microsoft.PowerShell.Utility.Select-Object#-caseinsensitive +[21]: xref:Microsoft.PowerShell.Utility.Select-Object#-unique +[22]: xref:Microsoft.PowerShell.Utility.Select-String +[23]: xref:Microsoft.PowerShell.Utility.Select-String#-casesensitive +[24]: xref:Microsoft.PowerShell.Utility.Sort-Object#-casesensitive +[25]: xref:Microsoft.PowerShell.Utility.Sort-Object#-unique +[26]: xref:System.Management.Automation.CommandTypes +[27]: xref:System.Management.Automation.OrderedHashtable diff --git a/reference/7.5/Microsoft.PowerShell.Diagnostics/Get-WinEvent.md b/reference/7.5/Microsoft.PowerShell.Diagnostics/Get-WinEvent.md index 5aef0e80c4d8..216f9de7b6e5 100644 --- a/reference/7.5/Microsoft.PowerShell.Diagnostics/Get-WinEvent.md +++ b/reference/7.5/Microsoft.PowerShell.Diagnostics/Get-WinEvent.md @@ -80,7 +80,7 @@ selected event providers. And, you can combine events from multiple sources in a `Get-WinEvent` allows you to filter events using XPath queries, structured XML queries, and hash table queries. -If you're not running PowerShell as an Administrator, you might see error messages that you cannot +If you're not running PowerShell as an Administrator, you might see error messages that you can't retrieve information about a log. ## EXAMPLES @@ -151,9 +151,9 @@ with the asterisk (`*`) wildcard to display each property. ### Example 3: Configure the classic Security log -This command gets an **EventLogConfiguration** object that represents the classic **Security** log. -The object is then used to configure settings for the log, such as max file size, file path, and -whether the log is enabled. +This command gets an **EventLogConfiguration** object that represents the classic **Security** log. The +object is then used to configure settings for the log, such as max file size, file path, and whether the +log is enabled. ```powershell $log = Get-WinEvent -ListLog Security @@ -162,7 +162,7 @@ try{ $log.SaveChanges() Get-WinEvent -ListLog Security | Format-List -Property * }catch [System.UnauthorizedAccessException]{ - $ErrMsg = 'You do not have permission to configure this log!' + $ErrMsg = 'You don't have permission to configure this log!' $ErrMsg += ' Try running this script with administrator privileges. ' $ErrMsg += $_.Exception.Message Write-Error $ErrMsg @@ -196,18 +196,17 @@ ProviderLatency : 1000 ProviderControlGuid : ``` -The `Get-WinEvent` cmdlet uses the **ListLog** parameter to specify the **Security** log. The object -is saved to a variable. The **MaximumSizeInBytes** property is set to 1 gigabyte on the object. The +The `Get-WinEvent` cmdlet uses the **ListLog** parameter to specify the **Security** log. The object is +saved to a variable. The **MaximumSizeInBytes** property is set to 1 gigabyte on the object. The **SaveChanges** method is called to push the change to the system inside of a try block to handle -access violations. The `Get-WinEvent` cmdlet is called again on the **Security** log and piped to -the `Format-List` cmdlet to verify that the **MaximumSizeInBytes** property has been saved on the -machine. +access violations. The `Get-WinEvent` cmdlet is called again on the **Security** log and piped to the +`Format-List` cmdlet to verify that the **MaximumSizeInBytes** property has been saved on the machine. ### Example 4: Get event logs from a server This command only gets event logs on the local computer that contain events. It's possible for a log's **RecordCount** to be null or zero. The example uses the `$_` variable. For more information, -see [about_Automatic_Variables](../Microsoft.PowerShell.Core/About/about_Automatic_Variables.md). +see [about_Automatic_Variables](../Microsoft.PowerShell.Core/about/about_automatic_variables.md). ```powershell Get-WinEvent -ListLog * -ComputerName localhost | Where-Object { $_.RecordCount } @@ -234,8 +233,7 @@ is a property of the object with a non-null value. This example gets objects that represent the **Application** event logs on three computers: Server01, Server02, and Server03. The `foreach` keyword is used because the **ComputerName** -parameter accepts only one value. For more information, see -[about_Foreach](../Microsoft.PowerShell.Core/About/about_Foreach.md). +parameter accepts only one value. For more information, see [about_Foreach](../Microsoft.PowerShell.Core/about/about_Foreach.md). ```powershell $S = 'Server01', 'Server02', 'Server03' @@ -347,8 +345,7 @@ This command lists the Event Ids that the **Microsoft-Windows-GroupPolicy** even along with the event description. ```powershell -(Get-WinEvent -ListProvider Microsoft-Windows-GroupPolicy).Events | - Format-Table Id, Description +(Get-WinEvent -ListProvider Microsoft-Windows-GroupPolicy).Events | Format-Table Id, Description ``` ```Output @@ -450,7 +447,7 @@ other properties from the output. The grouped objects are sent down the pipeline ### Example 12: Get events from an archived event log `Get-WinEvent` can get event information from saved log files. This sample uses an archived -PowerShell log that is stored on the local computer. +PowerShell log that's stored on the local computer. ```powershell Get-WinEvent -Path 'C:\Test\Windows PowerShell.evtx' @@ -475,7 +472,7 @@ the directory and file name. These commands get a specific number of events from an archived event log. `Get-WinEvent` has parameters that can get a maximum number of events or the oldest events. This sample uses an -archived PowerShell log that is stored in **C:\Test\PowerShellCore Operational.evtx**. +archived PowerShell log that's stored in **C:\Test\PowerShellCore Operational.evtx**. ```powershell Get-WinEvent -Path 'C:\Test\PowerShellCore Operational.evtx' -MaxEvents 100 @@ -503,18 +500,18 @@ from newest to oldest. Event Tracing for Windows (ETW) writes events to the log as events occur. The events are stored in the order of oldest to newest. An archived ETW file is saved as an `.etl` such as **TraceLog.etl**. -The events are listed in the order in which they are written to the log, so the *Oldest* parameter +The events are listed in the order in which they're written to the log, so the *Oldest* parameter is required. ```powershell Get-WinEvent -Path 'C:\Tracing\TraceLog.etl' -Oldest | - Sort-Object -Property TimeCreated -Descending | + Sort-Object -Property TimeCreated -Descending | Select-Object -First 100 ``` The `Get-WinEvent` cmdlet gets log information from the archived file. The **Path** parameter specifies the directory and file name. The **Oldest** parameter is used to output events in the -order they are written, oldest to newest. The objects are sent down the pipeline to the +order they're written, oldest to newest. The objects are sent down the pipeline to the `Sort-Object` cmdlet `Sort-Object` sorts the objects in descending order by the value of the **TimeCreated** property. The objects are sent down the pipeline to the `Select-Object` cmdlet that displays the 100 newest events. @@ -524,17 +521,17 @@ displays the 100 newest events. This example shows how to get the events from an event trace log file (`.etl`) and an archived Windows PowerShell log file (`.evtx`). You can combine multiple file types in a single command. Because the files contain the same type of **.NET Framework** object, **EventLogRecord**, you can -filter them with the same properties. The command requires the **Oldest** parameter because it is +filter them with the same properties. The command requires the **Oldest** parameter because it's reading from an `.etl` file, but the **Oldest** parameter applies to each file. ```powershell Get-WinEvent -Path 'C:\Tracing\TraceLog.etl', 'C:\Test\Windows PowerShell.evtx' -Oldest | - Where-Object { $_.Id -eq '403' } + Where-Object { $_.Id -eq '403' } ``` The `Get-WinEvent` cmdlet gets log information from the archived files. The **Path** parameter uses a comma-separated list to specify each files directory and file name. The **Oldest** parameter is -used to output events in the order they are written, oldest to newest. The objects are sent down the +used to output events in the order they're written, oldest to newest. The objects are sent down the pipeline to the `Where-Object` cmdlet. `Where-Object` uses a script block to find events with an **Id** of **403**. The `$_` variable represents the current object in the pipeline and **Id** is the Event Id property. @@ -561,14 +558,14 @@ $xmlQuery = @' + TimeCreated[timediff(@SystemTime) <= 86400000]]] '@ Get-WinEvent -FilterXML $xmlQuery # Using the FilterXPath parameter: -$XPath = '*[System[Level=3 and TimeCreated[timediff(@SystemTime) &lt;= 86400000]]]' +$XPath = '*[System[Level=3 and TimeCreated[timediff(@SystemTime) <= 86400000]]]' Get-WinEvent -LogName 'Windows PowerShell' -FilterXPath $XPath ``` @@ -576,16 +573,17 @@ Get-WinEvent -LogName 'Windows PowerShell' -FilterXPath $XPath This example uses the **FilterHashtable** parameter to get events from the **Application** log. The hash table uses **key/value** pairs. For more information about the **FilterHashtable** parameter, -see [Creating Get-WinEvent queries with FilterHashtable](/powershell/scripting/samples/creating-get-winevent-queries-with-filterhashtable). +see +[Creating Get-WinEvent queries with FilterHashtable](/powershell/scripting/samples/Creating-Get-WinEvent-queries-with-FilterHashtable). For more information about hash tables, see -[about_Hash_Tables](../Microsoft.PowerShell.Core/About/about_Hash_Tables.md). +[about_Hash_Tables](../Microsoft.PowerShell.Core/about/about_hash_tables.md). ```powershell $Date = (Get-Date).AddDays(-2) Get-WinEvent -FilterHashtable @{ LogName='Application'; StartTime=$Date; Id='1003' } ``` -The `Get-Date` cmdlet uses the **AddDays** method to get a date that is two days before the current +The `Get-Date` cmdlet uses the **AddDays** method to get a date that's two days before the current date. The date object is stored in the `$Date` variable. The `Get-WinEvent` cmdlet gets log information. The **FilterHashtable** parameter is used to filter @@ -600,14 +598,14 @@ that occurred within the last week. ```powershell $StartTime = (Get-Date).AddDays(-7) Get-WinEvent -FilterHashtable @{ - LogName='Application' + Logname='Application' ProviderName='Application Error' Data='iexplore.exe' StartTime=$StartTime } ``` -The `Get-Date` cmdlet uses the **AddDays** method to get a date that is seven days before the +The `Get-Date` cmdlet uses the **AddDays** method to get a date that's seven days before the current date. The date object is stored in the `$StartTime` variable. The `Get-WinEvent` cmdlet gets log information. The **FilterHashtable** parameter is used to filter @@ -645,8 +643,8 @@ value is the local computer, **localhost**. This parameter accepts only one comp To get event logs from remote computers, configure the firewall port for the event log service to allow remote access. -This cmdlet does not rely on PowerShell remoting. You can use the **ComputerName** parameter even if -your computer is not configured to run remote commands. +This cmdlet doesn't rely on PowerShell remoting. You can use the **ComputerName** parameter even if +your computer isn't configured to run remote commands. ```yaml Type: System.String @@ -701,7 +699,7 @@ Hash table queries have the following rules: logs. - `` key represents a named event data field. -When `Get-WinEvent` cannot interpret a **key/value** pair, it interprets the key as a case-sensitive +When `Get-WinEvent` can't interpret a **key/value** pair, it interprets the key as a case-sensitive name for the event data in the event. The valid `Get-WinEvent` **key/value** pairs are as follows: @@ -766,8 +764,8 @@ Accept wildcard characters: False Specifies an XPath query that this cmdlet select events from one or more logs. For more information about the XPath language, see -[XPath Reference](/previous-versions/dotnet/netframework-4.0/ms256115(v=vs.100)) -and the Selection Filters section of [Event Selection](/previous-versions/aa385231(v=vs.85)). +[XPath Reference](/previous-versions/dotnet/netframework-4.0/ms256115(v=vs.100)) and the +_Selection Filters_ section of [Event Selection](/previous-versions/aa385231(v=vs.85)). ```yaml Type: System.String @@ -845,7 +843,7 @@ comma-separated list. Wildcards are permitted. You can also pipe log names to th cmdlet. > [!NOTE] -> PowerShell does not limit the amount of logs you can request. However, the `Get-WinEvent` cmdlet +> PowerShell doesn't limit the amount of logs you can request. However, the `Get-WinEvent` cmdlet > queries the Windows API which has a limit of 256. This can make it difficult to filter through all > of your logs at one time. You can work around this by using a `foreach` loop to iterate through > each log like this: `Get-WinEvent -ListLog * | ForEach-Object{ Get-WinEvent -LogName $_.LogName }` @@ -926,7 +924,7 @@ Specifies, as a string array, the event log providers from which this cmdlet get provider names in a comma-separated list, or use wildcard characters to create provider name patterns. -An event log provider is a program or service that writes events to the event log. It is not a +An event log provider is a program or service that writes events to the event log. It isn't a PowerShell provider. ```yaml @@ -982,18 +980,18 @@ With the **ListProvider** parameter, this cmdlet returns **ProviderMetadata** ob and later versions of Windows. `Get-EventLog` gets events only in classic event logs. `Get-EventLog` is retained for backward compatibility. -The `Get-WinEvent` and `Get-EventLog` cmdlets are not supported in Windows Pre-installation +The `Get-WinEvent` and `Get-EventLog` cmdlets aren't supported in Windows Pre-installation Environment (Windows PE). ## RELATED LINKS -[about_Automatic_Variables](../Microsoft.PowerShell.Core/About/about_Automatic_Variables.md) +[about_Automatic_Variables](../Microsoft.PowerShell.Core/about/about_automatic_variables.md) -[about_Foreach](../Microsoft.PowerShell.Core/About/about_Foreach.md) +[about_Foreach](../Microsoft.PowerShell.Core/about/about_Foreach.md) -[about_Hash_Tables](../Microsoft.PowerShell.Core/About/about_Hash_Tables.md) +[about_Hash_Tables](../Microsoft.PowerShell.Core/about/about_hash_tables.md) -[Creating Get-WinEvent queries with FilterHashtable](/powershell/scripting/samples/creating-get-winevent-queries-with-filterhashtable) +[Creating Get-WinEvent queries with FilterHashtable](/powershell/scripting/samples/Creating-Get-WinEvent-queries-with-FilterHashtable) [Format-Table](../Microsoft.PowerShell.Utility/Format-Table.md) diff --git a/reference/7.6/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md b/reference/7.6/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md index 073acc106651..81fb331d81dd 100644 --- a/reference/7.6/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md +++ b/reference/7.6/Microsoft.PowerShell.Core/About/about_Case-Sensitivity.md @@ -1,8 +1,7 @@ --- description: This article explains how PowerShell handles case-sensitivity. Locale: en-US -ms.custom: wiki-migration -ms.date: 06/06/2022 +ms.date: 01/06/2026 online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_case-sensitivity?view=powershell-7.6&WT.mc_id=ps-gethelp title: about_Case-Sensitivity --- @@ -14,38 +13,246 @@ PowerShell is as case-insensitive as possible while preserving case. ## Long description -As a general principle, PowerShell is as case insensitive as possible while +As a general principle, PowerShell is case-insensitive wherever possible while preserving case and not breaking the underlying OS. -### On Unix-based systems +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. -On Unix-based systems, PowerShell is case-sensitive because filesystem -manipulation and environment variables directly affect the underlying -operating system and integration with other tools. +PowerShell is guaranteed to be case-insensitive on all systems for the +following areas: -## On all systems +- 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 namespace` statements +- Type literals +- `#Requires` statements +- Comment-based help keywords +- PSProvider names +- PSDrive names +- Scope modifiers -- PowerShell variables are case-insensitive - - Variable names have no interaction between them and the underlying operating - system. PowerShell treats them case-insensitively. +## Special cases - 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| + 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 - `Update-Help` when looking for new help files. - The web service that serves the help files for Microsoft uses a - case-sensitive filesystem. When the case of the imported name of the module - doesn't match, `Update-Help` can't find the help files and reports an error. + by `Update-Help` when 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-Help` can't find + the help files and reports an error. + +- [PS providers][05]: + + The `FileSystem` and `Environment` providers are case-sensitive on + non-Windows systems. Generally, operations involving paths or environment + variables are case-sensitive on such systems. + + However, [wildcard matching][09] by [provider cmdlets][02] is + case-insensitive, irrespective of the system. + + ```powershell + 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 `DefaultParameterSetName` case must be identical to `ParameterSetName`. + +- .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. + +- `-Unique` cmdlets: + - [`Select-Object -Unique`][21] and [`Get-Unique`][15] are case-sensitive by + default. The [`-CaseInsensitive`][20] switch was added in PS v7.4. + - [`Sort-Object -Unique`][25] is case-insensitive by default, but has always + had the [`-CaseSensitive`][24] switch. + +- [`Compare-Object`][11] is case-insensitive by default, but has a + [`-CaseSensitive`][12] switch. Comparison of `[char]` types is case-sensitive + by default. String comparison is case-insensitive by default. + + ```powershell + # 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`][13]: + - `-AsHashtable` was 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.OrderedHashtable`][27] is 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. + - https://github.com/PowerShell/PowerShell/issues/19928 + +- [`Group-Object`][16]: + - Case-insensitive by default, but does have a [`-CaseSensitive`][18] + switch. + - In Windows PowerShell v5.1, `-CaseSensitive` and [`-AsHashtable`][17] + produces a case-insensitive hashtable. Duplicate keys result in an error. + + ```powershell + [pscustomobject] @{ Foo = 'Bar' }, [pscustomobject] @{ Foo = 'bar' } | + Group-Object -Property Foo -CaseSensitive -AsHashtable + ``` + + ```Output + 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, `-CaseSensitive` and `-AsHashtable` produces a + case-sensitive hashtable. No error occurs with duplicate keys. + + ```powershell + [pscustomobject] @{ Foo = 'Bar' }, [pscustomobject] @{ Foo = 'bar' } | + Group-Object -Property Foo -CaseSensitive -AsHashtable + ``` + + ```Output + Name Value + ---- ----- + Bar {@{Foo=Bar}} + bar {@{Foo=bar}} + ``` + +- [`Select-String`][22]: + - Case-insensitive by default, but does have a [`-CaseSensitive`][23] switch. + +- [`Get-Command`][14] and command discovery/invocation: + - On case-sensitive file systems, discovery and invocation of + `ExternalScript` and `Application` command are case-sensitive. + - `Get-Command` wildcard matching with these types is also case-sensitive. + - All other [`CommandTypes`][26] are case-insensitive. + +- [Comparison operators][03]: + - By default, operators are case-insensitive. + - `-c*` operators are case-sensitive. + - `-i*` operators are case-insensitive. + - `-replace`/`-ireplace` is case-insensitive by default, _except_ with [named + capture groups][01], which are case-sensitive. + + ```powershell + 'Bar' -replace '(?a)', '${a}${a}' + # Baar + + 'Bar' -replace '(?a)', '${A}${A}' + # B${A}${A}r + ``` + +- [`-split` operator][10]: + - `-split` and `-isplit` are case-insensitive. + - `-csplit` is case-sensitive, _unless_ the `IgnoreCase` option is specified. + + ```powershell + 'Bar' -csplit 'A', 0 + # Bar + + 'Bar' -csplit 'A', 0, 'IgnoreCase' + # B + # r + ``` + +- [Tab completion][07]: + - On case-sensitive file systems, tab completion and globbing are both + case-insensitive. For example, `TabExpansion2 -inputScript ./foo` will + complete to `./Foo.txt` on Linux. + +- [`using`][08] statement: + - On case-sensitive file systems, `using module` and `using assembly` are + case-sensitive when a path is specified. + - `using module` with just a module name is case-insensitive. + - `using namespace` is always case-insensitive. + +- [Special characters][06]: + - Escape sequences like `` `n `` are case-sensitive. ## See also -- [about_Environment_Variables](about_Environment_Variables.md) -- [Import-Module](xref:Microsoft.PowerShell.Core.Import-Module) +- [about_Environment_Variables][04] +- [Import-Module][19] + + +[01]: /dotnet/standard/base-types/substitutions-in-regular-expressions#substituting-a-named-group +[02]: /powershell/scripting/developer/provider/provider-cmdlets +[03]: about_comparison_operators.md +[04]: about_Environment_Variables.md +[05]: about_providers.md +[06]: about_special_characters.md +[07]: about_tab_expansion.md +[08]: about_using.md +[09]: about_wildcards.md +[10]: about_split.md +[11]: xref:Microsoft.PowerShell.Utility.Compare-Object +[12]: xref:Microsoft.PowerShell.Utility.Compare-Object#-casesensitive +[13]: xref:Microsoft.PowerShell.Utility.ConvertFrom-Json#-ashashtable +[14]: xref:Microsoft.PowerShell.Core.Get-Command +[15]: xref:Microsoft.PowerShell.Utility.Get-Unique +[16]: xref:Microsoft.PowerShell.Utility.Group-Object +[17]: xref:Microsoft.PowerShell.Utility.Group-Object#-ashashtable +[18]: xref:Microsoft.PowerShell.Utility.Group-Object#-casesensitive +[19]: xref:Microsoft.PowerShell.Core.Import-Module +[20]: xref:Microsoft.PowerShell.Utility.Select-Object#-caseinsensitive +[21]: xref:Microsoft.PowerShell.Utility.Select-Object#-unique +[22]: xref:Microsoft.PowerShell.Utility.Select-String +[23]: xref:Microsoft.PowerShell.Utility.Select-String#-casesensitive +[24]: xref:Microsoft.PowerShell.Utility.Sort-Object#-casesensitive +[25]: xref:Microsoft.PowerShell.Utility.Sort-Object#-unique +[26]: xref:System.Management.Automation.CommandTypes +[27]: xref:System.Management.Automation.OrderedHashtable diff --git a/reference/7.6/Microsoft.PowerShell.Diagnostics/Get-WinEvent.md b/reference/7.6/Microsoft.PowerShell.Diagnostics/Get-WinEvent.md index 9ef87c95fd4a..29e6b34c649c 100644 --- a/reference/7.6/Microsoft.PowerShell.Diagnostics/Get-WinEvent.md +++ b/reference/7.6/Microsoft.PowerShell.Diagnostics/Get-WinEvent.md @@ -80,7 +80,7 @@ selected event providers. And, you can combine events from multiple sources in a `Get-WinEvent` allows you to filter events using XPath queries, structured XML queries, and hash table queries. -If you're not running PowerShell as an Administrator, you might see error messages that you cannot +If you're not running PowerShell as an Administrator, you might see error messages that you can't retrieve information about a log. ## EXAMPLES @@ -162,7 +162,7 @@ try{ $log.SaveChanges() Get-WinEvent -ListLog Security | Format-List -Property * }catch [System.UnauthorizedAccessException]{ - $ErrMsg = 'You do not have permission to configure this log!' + $ErrMsg = 'You don't have permission to configure this log!' $ErrMsg += ' Try running this script with administrator privileges. ' $ErrMsg += $_.Exception.Message Write-Error $ErrMsg @@ -447,7 +447,7 @@ other properties from the output. The grouped objects are sent down the pipeline ### Example 12: Get events from an archived event log `Get-WinEvent` can get event information from saved log files. This sample uses an archived -PowerShell log that is stored on the local computer. +PowerShell log that's stored on the local computer. ```powershell Get-WinEvent -Path 'C:\Test\Windows PowerShell.evtx' @@ -472,7 +472,7 @@ the directory and file name. These commands get a specific number of events from an archived event log. `Get-WinEvent` has parameters that can get a maximum number of events or the oldest events. This sample uses an -archived PowerShell log that is stored in **C:\Test\PowerShellCore Operational.evtx**. +archived PowerShell log that's stored in **C:\Test\PowerShellCore Operational.evtx**. ```powershell Get-WinEvent -Path 'C:\Test\PowerShellCore Operational.evtx' -MaxEvents 100 @@ -500,7 +500,7 @@ from newest to oldest. Event Tracing for Windows (ETW) writes events to the log as events occur. The events are stored in the order of oldest to newest. An archived ETW file is saved as an `.etl` such as **TraceLog.etl**. -The events are listed in the order in which they are written to the log, so the *Oldest* parameter +The events are listed in the order in which they're written to the log, so the *Oldest* parameter is required. ```powershell @@ -511,7 +511,7 @@ Get-WinEvent -Path 'C:\Tracing\TraceLog.etl' -Oldest | The `Get-WinEvent` cmdlet gets log information from the archived file. The **Path** parameter specifies the directory and file name. The **Oldest** parameter is used to output events in the -order they are written, oldest to newest. The objects are sent down the pipeline to the +order they're written, oldest to newest. The objects are sent down the pipeline to the `Sort-Object` cmdlet `Sort-Object` sorts the objects in descending order by the value of the **TimeCreated** property. The objects are sent down the pipeline to the `Select-Object` cmdlet that displays the 100 newest events. @@ -521,7 +521,7 @@ displays the 100 newest events. This example shows how to get the events from an event trace log file (`.etl`) and an archived Windows PowerShell log file (`.evtx`). You can combine multiple file types in a single command. Because the files contain the same type of **.NET Framework** object, **EventLogRecord**, you can -filter them with the same properties. The command requires the **Oldest** parameter because it is +filter them with the same properties. The command requires the **Oldest** parameter because it's reading from an `.etl` file, but the **Oldest** parameter applies to each file. ```powershell @@ -531,7 +531,7 @@ Get-WinEvent -Path 'C:\Tracing\TraceLog.etl', 'C:\Test\Windows PowerShell.evtx' The `Get-WinEvent` cmdlet gets log information from the archived files. The **Path** parameter uses a comma-separated list to specify each files directory and file name. The **Oldest** parameter is -used to output events in the order they are written, oldest to newest. The objects are sent down the +used to output events in the order they're written, oldest to newest. The objects are sent down the pipeline to the `Where-Object` cmdlet. `Where-Object` uses a script block to find events with an **Id** of **403**. The `$_` variable represents the current object in the pipeline and **Id** is the Event Id property. @@ -558,14 +558,14 @@ $xmlQuery = @' + TimeCreated[timediff(@SystemTime) <= 86400000]]] '@ Get-WinEvent -FilterXML $xmlQuery # Using the FilterXPath parameter: -$XPath = '*[System[Level=3 and TimeCreated[timediff(@SystemTime) &lt;= 86400000]]]' +$XPath = '*[System[Level=3 and TimeCreated[timediff(@SystemTime) <= 86400000]]]' Get-WinEvent -LogName 'Windows PowerShell' -FilterXPath $XPath ``` @@ -573,15 +573,17 @@ Get-WinEvent -LogName 'Windows PowerShell' -FilterXPath $XPath This example uses the **FilterHashtable** parameter to get events from the **Application** log. The hash table uses **key/value** pairs. For more information about the **FilterHashtable** parameter, -see [Creating Get-WinEvent queries with FilterHashtable](/powershell/scripting/samples/Creating-Get-WinEvent-queries-with-FilterHashtable). -For more information about hash tables, see [about_Hash_Tables](../Microsoft.PowerShell.Core/about/about_hash_tables.md). +see +[Creating Get-WinEvent queries with FilterHashtable](/powershell/scripting/samples/Creating-Get-WinEvent-queries-with-FilterHashtable). +For more information about hash tables, see +[about_Hash_Tables](../Microsoft.PowerShell.Core/about/about_hash_tables.md). ```powershell $Date = (Get-Date).AddDays(-2) Get-WinEvent -FilterHashtable @{ LogName='Application'; StartTime=$Date; Id='1003' } ``` -The `Get-Date` cmdlet uses the **AddDays** method to get a date that is two days before the current +The `Get-Date` cmdlet uses the **AddDays** method to get a date that's two days before the current date. The date object is stored in the `$Date` variable. The `Get-WinEvent` cmdlet gets log information. The **FilterHashtable** parameter is used to filter @@ -596,14 +598,14 @@ that occurred within the last week. ```powershell $StartTime = (Get-Date).AddDays(-7) Get-WinEvent -FilterHashtable @{ - LogName='Application' + Logname='Application' ProviderName='Application Error' Data='iexplore.exe' StartTime=$StartTime } ``` -The `Get-Date` cmdlet uses the **AddDays** method to get a date that is seven days before the +The `Get-Date` cmdlet uses the **AddDays** method to get a date that's seven days before the current date. The date object is stored in the `$StartTime` variable. The `Get-WinEvent` cmdlet gets log information. The **FilterHashtable** parameter is used to filter @@ -641,8 +643,8 @@ value is the local computer, **localhost**. This parameter accepts only one comp To get event logs from remote computers, configure the firewall port for the event log service to allow remote access. -This cmdlet does not rely on PowerShell remoting. You can use the **ComputerName** parameter even if -your computer is not configured to run remote commands. +This cmdlet doesn't rely on PowerShell remoting. You can use the **ComputerName** parameter even if +your computer isn't configured to run remote commands. ```yaml Type: System.String @@ -697,7 +699,7 @@ Hash table queries have the following rules: logs. - `` key represents a named event data field. -When `Get-WinEvent` cannot interpret a **key/value** pair, it interprets the key as a case-sensitive +When `Get-WinEvent` can't interpret a **key/value** pair, it interprets the key as a case-sensitive name for the event data in the event. The valid `Get-WinEvent` **key/value** pairs are as follows: @@ -739,8 +741,9 @@ Help. Use an XML query to create a complex query that contains several XPath statements. The XML format also allows you to use a **Suppress XML** element that excludes events from the query. For more -information about the XML schema for event log queries, see [Query Schema](/windows/win32/wes/queryschema-schema) -and the XML Event Queries section of [Event Selection](/previous-versions/aa385231(v=vs.85)). +information about the XML schema for event log queries, see +[Query Schema](/windows/win32/wes/queryschema-schema) and the XML Event Queries section of +[Event Selection](/previous-versions/aa385231(v=vs.85)). You may also create a **Suppress** element using the **FilterHashtable** parameter. @@ -760,8 +763,9 @@ Accept wildcard characters: False Specifies an XPath query that this cmdlet select events from one or more logs. -For more information about the XPath language, see [XPath Reference](/previous-versions/dotnet/netframework-4.0/ms256115(v=vs.100)) -and the Selection Filters section of [Event Selection](/previous-versions/aa385231(v=vs.85)). +For more information about the XPath language, see +[XPath Reference](/previous-versions/dotnet/netframework-4.0/ms256115(v=vs.100)) and the +_Selection Filters_ section of [Event Selection](/previous-versions/aa385231(v=vs.85)). ```yaml Type: System.String @@ -839,10 +843,10 @@ comma-separated list. Wildcards are permitted. You can also pipe log names to th cmdlet. > [!NOTE] -> PowerShell does not limit the amount of logs you can request. However, the `Get-WinEvent` cmdlet +> PowerShell doesn't limit the amount of logs you can request. However, the `Get-WinEvent` cmdlet > queries the Windows API which has a limit of 256. This can make it difficult to filter through all -> of your logs at one time. You can work around this by using a `foreach` loop to iterate through each -> log like this: `Get-WinEvent -ListLog * | ForEach-Object{ Get-WinEvent -LogName $_.LogName }` +> of your logs at one time. You can work around this by using a `foreach` loop to iterate through +> each log like this: `Get-WinEvent -ListLog * | ForEach-Object{ Get-WinEvent -LogName $_.LogName }` ```yaml Type: System.String[] @@ -920,7 +924,7 @@ Specifies, as a string array, the event log providers from which this cmdlet get provider names in a comma-separated list, or use wildcard characters to create provider name patterns. -An event log provider is a program or service that writes events to the event log. It is not a +An event log provider is a program or service that writes events to the event log. It isn't a PowerShell provider. ```yaml @@ -939,7 +943,8 @@ Accept wildcard characters: True This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, --WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). +-WarningAction, and -WarningVariable. For more information, see +[about_CommonParameters](https://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS @@ -975,7 +980,7 @@ With the **ListProvider** parameter, this cmdlet returns **ProviderMetadata** ob and later versions of Windows. `Get-EventLog` gets events only in classic event logs. `Get-EventLog` is retained for backward compatibility. -The `Get-WinEvent` and `Get-EventLog` cmdlets are not supported in Windows Pre-installation +The `Get-WinEvent` and `Get-EventLog` cmdlets aren't supported in Windows Pre-installation Environment (Windows PE). ## RELATED LINKS