Windows PowerShell and PowerShell 7 compatibility
Microsoft's edit ·
Microsoft's commit message in MicrosoftDocs/PowerShell-Docs · commit ed225b5 · +71 −72 lines · also on GitHub
11
---
2
−ms.date: 04/02/2024
2
+ms.date: 02/04/2026
33
title: Differences between Windows PowerShell 5.1 and PowerShell 7.x
4
−description: This article summarizes the differences and breaking changes from Windows PowerShell 5.1 and the current version of PowerShell that is based on .NET Core.
4
+description: This article summarizes the differences and breaking changes from Windows PowerShell 5.1 and the current version of PowerShell that's based on .NET Core.
55
---
66
# Differences between Windows PowerShell 5.1 and PowerShell 7.x
77
⋯ 8 unchanged lines
1616
and .NET Core.
1717
1818
This article summarizes the significant differences and breaking changes between Windows PowerShell
19
−and the current version of PowerShell. This summary does not include new features or cmdlets that
19
+and the current version of PowerShell. This summary doesn't include new features or cmdlets that
2020
have been added. Nor does this article discuss what changed between versions. The goal of this
21
−article is to present the current state of PowerShell and how that is different from Windows
21
+article is to present the current state of PowerShell and how that's different from Windows
2222
PowerShell. For a detailed discussion of changes between versions and the addition of new features,
2323
see the **What's New** articles for each version.
2424
⋯ 16 unchanged lines
4141
Each new release of PowerShell is built on a newer version of .NET. There can be breaking changes in
4242
.NET that affect PowerShell.
4343
44
+- PowerShell 7.6 - Built on .NET 10.0 (LTS)
4445
- PowerShell 7.5 - Built on .NET 9.0
45
−- PowerShell 7.4 - Built on .NET 8.0
46
+- PowerShell 7.4 - Built on .NET 8.0 (LTS)
4647
- PowerShell 7.3 - Built on .NET 7.0
47
−- PowerShell 7.2 (LTS-current) - Built on .NET 6.0 (LTS-current)
48
+- PowerShell 7.2 - Built on .NET 6.0 (LTS)
4849
- PowerShell 7.1 - Built on .NET 5.0
49
−- PowerShell 7.0 (LTS) - Built on .NET Core 3.1 (LTS)
50
+- PowerShell 7.0 - Built on .NET Core 3.1 (LTS)
5051
- PowerShell 6.2 - Built on .NET Core 2.1
5152
- PowerShell 6.1 - Built on .NET Core 2.1
5253
- PowerShell 6.0 - Built on .NET Core 2.0
⋯ 10 unchanged lines
6364
6465
### Be aware of .NET method changes
6566
66
−While .NET method changes are not specific to PowerShell, they can affect your scripts, especially
67
+While .NET method changes aren't specific to PowerShell, they can affect your scripts, especially
6768
if you are calling .NET methods directly. Also, there might be new overloads for constructors. This
6869
can have an impact on how you create objects using `New-Object` or the `[type]::new()` method.
6970
⋯ 83 unchanged lines
153154
In the future, we would like to enable native parallelism/concurrency in the PowerShell language
154155
without the need for PowerShell Workflow.
155156
156
−If there is a need to use checkpoints to resume a script after the OS restarts, we recommend
157
−using Task Scheduler to run a script on OS startup, but the script would need to maintain
158
−its own state (like persisting it to a file).
157
+If there is a need to use checkpoints to resume a script after the OS restarts, we recommend using
158
+Task Scheduler to run a script on OS startup, but the script would need to maintain its own state
159
+(like persisting it to a file).
159160
160161
## Cmdlets removed from PowerShell
161162
⋯ 86 unchanged lines
248249
249250
### `New-WebServiceProxy` cmdlet removed
250251
251
−.NET Core does not support the Windows Communication Framework, which provide services for using the
252
+.NET Core doesn't support the Windows Communication Framework, which provides services for using the
252253
SOAP protocol. This cmdlet was removed because it requires SOAP.
253254
254255
### `*-Transaction` cmdlets removed
⋯ 43 unchanged lines
298299
on non-Windows platforms. It also means that you can run commands like `pwsh foo.ps1` or
299300
`pwsh fooScript` without specifying `-File`. However, this change requires that you explicitly
300301
specify `-c` or `-Command` when trying to run commands like `pwsh.exe -Command Get-Command`.
301
−- `pwsh` accepts the `-i` (or `-Interactive`) switch to indicate an interactive shell.
302
− This allows PowerShell to be used as a default shell on Unix platforms.
302
+- `pwsh` accepts the `-i` (or `-Interactive`) switch to indicate an interactive shell. This allows
303
+ PowerShell to be used as a default shell on Unix platforms.
303304
- Removed parameters `-ImportSystemModules` and `-PSConsoleFile` from `pwsh.exe`.
304305
- Changed `pwsh -Version` and built-in help for `pwsh.exe` to align with other native tools.
305306
- Invalid argument error messages for `-File` and `-Command` and exit codes consistent with Unix
⋯ 28 unchanged lines
334335
335336
- `USE_MU` - This property has two possible values:
336337
- `1` (default) - Opts into updating through Microsoft Update or WSUS
337
− - `0` - Do not opt into updating through Microsoft Update or WSUS
338
+ - `0` - Don't opt into updating through Microsoft Update or WSUS
338339
- `ENABLE_MU`
339340
- `1` (default) - Opts into using Microsoft Update the Automatic Updates or Windows Update
340
− - `0` - Do not opt into using Microsoft Update the Automatic Updates or Windows Update
341
+ - `0` - Don't opt into using Microsoft Update the Automatic Updates or Windows Update
341342
342343
## Engine changes
343344
344345
### Support PowerShell as a default Unix shell
345346
346
−On Unix, it is a convention for shells to accept `-i` for an interactive shell and many tools
347
−expect this behavior (`script` for example, and when setting PowerShell as the default shell) and
348
−calls the shell with the `-i` switch. This change is breaking in that `-i` previously could be used
349
−as short hand to match `-InputFormat`, which now needs to be `-in`.
347
+On Unix, it's a convention for shells to accept `-i` for an interactive shell and many tools expect
348
+this behavior (`script` for example, and when setting PowerShell as the default shell) and calls the
349
+shell with the `-i` switch. This change is breaking in that `-i` previously could be used as short
350
+hand to match `-InputFormat`, which now needs to be `-in`.
350351
351352
### Custom snap-ins
352353
353
−[PowerShell snap-ins][07] are a predecessor to PowerShell modules that do not have widespread
354
+[PowerShell snap-ins][07] are a predecessor to PowerShell modules that don't have widespread
354355
adoption in the PowerShell community.
355356
356357
Due to the complexity of supporting snap-ins and their lack of usage in the community, we no longer
⋯ 21 unchanged lines
378379
### Preserve `$?` for **ParenExpression**, **SubExpression** and **ArrayExpression**
379380
380381
This PR alters the way we compile subpipelines `(...)`, subexpressions `$(...)` and array
381
−expressions `@()` so that `$?` is not automatically **true**. Instead the value of `$?` depends on
382
+expressions `@()` so that `$?` isn't automatically **true**. Instead the value of `$?` depends on
382383
the result of the pipeline or statements executed.
383384
384385
### Fix `$?` to not be `$false` when native command writes to `stderr`
385386
386
−`$?` is not set to `$false` when native command writes to `stderr`. It is common for native commands
387
+`$?` isn't set to `$false` when native command writes to `stderr`. It's common for native commands
387388
to write to `stderr` without intending to indicate a failure. `$?` is set to `$false` only when the
388389
native command has a non-zero exit code.
389390
390391
### Make `$ErrorActionPreference` not affect `stderr` output of native commands
391392
392
−It is common for native commands to write to `stderr` without intending to indicate a failure. With
393
+It's common for native commands to write to `stderr` without intending to indicate a failure. With
393394
this change, `stderr` output is still captured in **ErrorRecord** objects, but the runtime no longer
394395
applies `$ErrorActionPreference` if the **ErrorRecord** comes from a native command.
395396
⋯ 37 unchanged lines
433434
### Allow explicitly specified named parameter to supersede the same one from hashtable splatting
434435
435436
With this change, the named parameters from splatting are moved to the end of the parameter list so
436
−that they are bound after all explicitly specified named parameters are bound. Parameter binding for
437
−simple functions doesn't throw an error when a specified named parameter cannot be found. Unknown
437
+that they're bound after all explicitly specified named parameters are bound. Parameter binding for
438
+simple functions doesn't throw an error when a specified named parameter can't be found. Unknown
438439
named parameters are bound to the `$args` parameter of the simple function. Moving splatting to the
439440
end of the argument list changes the order the parameters appears in `$args`.
440441
⋯ 9 unchanged lines
450451
}
451452
```
452453
453
−In the previous behavior, **MyPath** is not bound to `-Path` because it's the third argument in the
454
+In the previous behavior, **MyPath** isn't bound to `-Path` because it's the third argument in the
454455
argument list. ## So it ends up being stuffed into '$args' along with `Blah = "World"`
455456
456457
```powershell
⋯ 3 unchanged lines
460461
```
461462
462463
With this change, the arguments from `@hash` are moved to the end of the argument list. **MyPath**
463
−becomes the first argument in the list, so it is bound to `-Path`.
464
+becomes the first argument in the list, so it's bound to `-Path`.
464465
465466
```powershell
466467
PS> SimpleTest @hash "MyPath"
⋯ 64 unchanged lines
531532
its operand only if that operand evaluates to non-null; otherwise, it returns null.
532533
533534
Since PowerShell allows `?` to be part of the variable name, formal specification of the variable
534
−name is required for using these operators. So it is required to use `{}` around the variable names
535
+name is required for using these operators. So it's required to use `{}` around the variable names
535536
like `${a}` or when `?` is part of the variable name `${a?}`.
536537
537538
In the following example, the value of **PropName** is returned.
⋯ 34 unchanged lines
572573
```
573574
574575
> [!NOTE]
575
−> The variable name syntax of `${<name>}` should not be confused with the `$()` subexpression
576
+> The variable name syntax of `${<name>}` shouldn't be confused with the `$()` subexpression
576577
> operator. For more information, see Variable name section of [about_Variables][08].
577578
578579
### Added `&` operator for job control
⋯ 90 unchanged lines
669670
670671
## New cmdlets
671672
672
−### New Get-Uptime cmdlet
673
+### New `Get-Uptime` cmdlet
673674
674675
The [Get-Uptime][19] cmdlet returns the time elapsed since the last boot of the operating system.
675676
The cmdlet was introduced in PowerShell 6.0.
676677
677
−### New Remove-Alias cmdlet
678
+### New `Remove-Alias` cmdlet
678679
679680
The [Remove-Alias][21] cmdlet removes an alias from the current PowerShell session. The cmdlet was
680681
introduced in PowerShell 6.0.
681682
682
−### New cmdlet Remove-Service
683
+### New `Remove-Service` cmdlet
683684
684685
The [Remove-Service][15] cmdlet removes a Windows service in the registry and in the service
685686
database. The `Remove-Service` cmdlet was introduced in PowerShell 6.0.
⋯ 13 unchanged lines
699700
console.
700701
- [Show-Markdown][23] - Displays Markdown content in the console or as HTML
701702
702
−### New Test-Json cmdlet
703
+### New `Test-Json` cmdlet
703704
704705
The [Test-Json][24] cmdlet tests whether a string is a valid JavaScript Object Notation (JSON)
705706
document and can optionally verify that JSON document against a provided schema.
⋯ 8 unchanged lines
714715
- [Enable-ExperimentalFeature][11]
715716
- [Get-ExperimentalFeature][13]
716717
717
−### New Join-String cmdlet
718
+### New `Join-String` cmdlet
718719
719720
The [Join-String][20] cmdlet combines objects from the pipeline into a single string. This cmdlet
720721
was added in PowerShell 6.2.
721722
722
−### New view ConciseView and cmdlet Get-Error
723
+### New view **ConciseView** and cmdlet `Get-Error`
723724
724725
PowerShell 7.0 enhances the display of error messages to improve the readability of interactive and
725726
script errors with a new default view, **ConciseView**. The views are user-selectable through the
726727
preference variable `$ErrorView`.
727728
728
−With **ConciseView**, if an error is not from a script or parser error, then it's a single line
729
+With **ConciseView**, if an error isn't from a script or parser error, then it's a single line
729730
error message:
730731
731732
```powershell
⋯ 1 unchanged line
733734
```
734735
735736
```Output
736
−Get-ChildItem: Cannot find path 'C:\NotReal' because it does not exist
737
+Get-ChildItem: Can't find path 'C:\NotReal' because it doesn't exist
737738
```
738739
739740
If the error occurs during script execution or is a parsing error, PowerShell returns a multiline
740741
error message that contains the error, a pointer, and an error message showing where the error is in
741
−that line. If the terminal doesn't support ANSI color escape sequences (VT100), then colors are not
742
+that line. If the terminal doesn't support ANSI color escape sequences (VT100), then colors aren't
742743
displayed.
743744
744745
The default view in PowerShell 7 is **ConciseView**. The previous default view was **NormalView**
⋯ 30 unchanged lines
775776
776777
## Cmdlet changes
777778
778
−### Parallel execution added to ForEach-Object
779
+### Parallel execution added to `ForEach-Object`
779780
780781
Beginning in PowerShell 7.0, the `ForEach-Object` cmdlet, which iterates items in a collection, now
781782
has built-in parallelism with the new **Parallel** parameter.
⋯ 15 unchanged lines
797798
50000
798799
```
799800
800
−The **Parallel** parameter specifies the script block that is run in parallel for each input log
801
+The **Parallel** parameter specifies the script block that's run in parallel for each input log
801802
name.
802803
803804
The new **ThrottleLimit** parameter limits the number of script blocks running in parallel at a
⋯ 34 unchanged lines
838839
839840
### Remove `-Protocol` from `*-Computer` cmdlets
840841
841
−Due to issues with RPC remoting in CoreFX (particularly on non-Windows platforms) and ensuring a
842
−consistent remoting experience in PowerShell, the `-Protocol` parameter was removed from the
843
−`\*-Computer` cmdlets. DCOM is no longer supported for remoting. The following cmdlets only support
844
−WSMAN remoting:
842
+The `-Protocol` parameter was removed from following cmdlets:
845843
846844
- `Rename-Computer`
847845
- `Restart-Computer`
848846
- `Stop-Computer`
849847
848
+DCOM is no longer supported for remoting. The cmdlets only support WSMAN remoting.
849
+
850850
### Remove `-ComputerName` from `*-Service` cmdlets
851851
852852
In order to encourage the consistent use of PSRP, the `-ComputerName` parameter was removed from
853
−`*-Service` cmdlets.
853
+`*-Service` cmdlets. Use `Invoke-Command` to run the cmdlets on remote computers instead.
854854
855855
### Fix `Get-Content -Delimiter` to not include the delimiter in the returned lines
856856
⋯ 3 unchanged lines
860860
861861
### Changes to `Format-Hex`
862862
863
−The `-Raw` parameter is now a "no-op" (in that it does nothing). Going forward all output is
864
−displayed with a true representation of numbers that includes all of the bytes for its type. This is
865
−what the `-Raw` parameter was doing prior to this change.
863
+The `-Raw` parameter now does nothing. The `Format-Hex` cmdlet displays a true representation of
864
+numbers that includes all the bytes for its type. This is what the `-Raw` parameter did prior
865
+to this change.
866866
867
−### Typo fix in Get-ComputerInfo property name
867
+### Typo fix in `Get-ComputerInfo` property name
868868
869869
`BiosSerialNumber` was misspelled as `BiosSeralNumber` and has been changed to the correct spelling.
870870
871
−### Add `Get-StringHash` and `Get-FileHash` cmdlets
871
+### Changes to available hash algorithms
872872
873
−This change is that some hash algorithms are not supported by CoreFX, therefore they are no longer
874
−available:
873
+The following hash algorithms have been removed from .NET:
875874
876875
- `MACTripleDES`
877876
- `RIPEMD160`
878877
878
+This change affects the `Get-FileHash` cmdlet.
879
+
879880
### Add validation on `Get-*` cmdlets where passing $null returns all objects instead of error
880881
881882
Passing `$null` to any of the following now throws an error:
⋯ 13 unchanged lines
895896
896897
### Add support for the W3C Extended Log File Format in `Import-Csv`
897898
898
−Previously, the `Import-Csv` cmdlet cannot be used to directly import the log files in W3C extended
899
+Previously, the `Import-Csv` cmdlet can't be used to directly import the log files in W3C extended
899900
log format and additional action would be required. With this change, W3C extended log format is
900901
supported.
901902
902903
### `Import-Csv` applies `pstypenames` upon import when type information is present in the CSV
903904
904905
Previously, objects exported using `Export-Csv` with `TypeInformation` imported with
905
−`ConvertFrom-Csv` were not retaining the type information. This change adds the type information to
906
+`ConvertFrom-Csv` weren't retaining the type information. This change adds the type information to
906907
`pstypenames` member if available from the CSV file.
907908
908909
### `-NoTypeInformation` is the default on `Export-Csv`
⋯ 11 unchanged lines
920921
if the file doesn't exist, it should error. Change is to treat wildcards used with `-Literal` as
921922
literal.
922923
923
−### Group-Object now sorts the groups
924
+### `Group-Object` now sorts the groups
924925
925926
As part of the performance improvement, `Group-Object` now returns a sorted listing of the groups.
926
−Although you should not rely on the order, you could be broken by this change if you wanted the
927
+Although you shouldn't rely on the order, you could be broken by this change if you wanted the
927928
first group. We decided that this performance improvement was worth the change since the impact of
928929
being dependent on previous behavior is low.
929930
⋯ 97 unchanged lines
10271028
- `-MaximumRedirection` now produces a terminating error when redirection attempts exceed the
10281029
provided limit instead of returning the results of the last redirection.
10291030
- In PowerShell 6.2, a change was made to default to UTF-8 encoding for JSON responses. When a
1030
− charset is not supplied for a JSON response, the default encoding should be UTF-8 per RFC 8259.
1031
+ charset isn't supplied for a JSON response, the default encoding should be UTF-8 per RFC 8259.
10311032
- Default encoding set to UTF-8 for `application-json` responses
10321033
- Added `-SkipHeaderValidation` parameter to allow `Content-Type` headers that aren't
10331034
standards-compliant
⋯ 1 unchanged line
10351036
- Compliant, case-insensitive handling of relation keys
10361037
- Added `-Resume` parameter for web cmdlets
10371038
1038
−### Invoke-RestMethod returns useful info when no data is returned
1039
+### `Invoke-RestMethod` returns useful info when no data is returned
10391040
10401041
When an API returns just `null`, `Invoke-RestMethod` was serializing this as the string `"null"`
10411042
instead of `$null`. This change fixes the logic in `Invoke-RestMethod` to properly serialize a valid
⋯ 8 unchanged lines
10501051
### Make `-OutFile` parameter in web cmdlets to work like `-LiteralPath`
10511052
10521053
Beginning in PowerShell 7.1, the **OutFile** parameter of the web cmdlets works like **LiteralPath**
1053
−and does not process wildcards.
1054
+and doesn't process wildcards.
10541055
10551056
## API changes
10561057
10571058
### Remove `AddTypeCommandBase` class
10581059
10591060
The `AddTypeCommandBase` class was removed from `Add-Type` to improve performance. This class is
1060
−only used by the `Add-Type` cmdlet and should not impact users.
1061
+only used by the `Add-Type` cmdlet and shouldn't impact users.
10611062
10621063
### Removed `VisualBasic` as a supported language in Add-Type
10631064
⋯ 12 unchanged lines
10761077
10771078
### Remove `ClrVersion` and `BuildVersion` properties from `$PSVersionTable`
10781079
1079
−The `ClrVersion` property of `$PSVersionTable` is not useful with CoreCLR. End users should not be
1080
+The `ClrVersion` property of `$PSVersionTable` isn't useful with CoreCLR. End users shouldn't be
10801081
using that value to determine compatibility.
10811082
1082
−The `BuildVersion` property was tied to the Windows build version, which is not available on
1083
+The `BuildVersion` property was tied to the Windows build version, which isn't available on
10831084
non-Windows platforms. Use the `GitCommitId` property to retrieve the exact build version of
10841085
PowerShell.
10851086
⋯ 18 unchanged lines
11041105
so it makes sense to not allow people to create `Workflow` instances.
11051106
- Remove the type **System.Management.Automation.DebugSource** since it's only used for workflow
11061107
debugging.
1107
−- Remove the overload of `SetParent` from the abstract class **Debugger** that is only used for
1108
+- Remove the overload of `SetParent` from the abstract class **Debugger** that's only used for
11081109
workflow debugging.
11091110
- Remove the same overload of `SetParent` from the derived class **RemotingJobDebugger**.
11101111
1111
−### Do not wrap return result in `PSObject` when converting a `ScriptBlock` to a delegate
1112
+### Don't wrap return result in `PSObject` when converting a `ScriptBlock` to a delegate
11121113
11131114
When a `ScriptBlock` is converted to a delegate type to be used in C# context, wrapping the result
11141115
in a `PSObject` brings unneeded troubles:
⋯ 7 unchanged lines
11221123
11231124
## Remoting Support
11241125
1125
−PowerShell Remoting (PSRP) using WinRM on Unix platforms requires NTLM/Negotiate or Basic Auth over
1126
−HTTPS. PSRP on macOS only supports Basic Auth over HTTPS. Kerberos-based authentication is not
1127
−supported for non-Windows platforms.
1128
−
1129
−PowerShell also supports PowerShell Remoting (PSRP) over SSH on all platforms (Windows, macOS, and
1130
−Linux). For more information, see [SSH remoting in PowerShell][25].
1126
+PowerShell Remoting (PSRP) using WinRM isn't supported for non-Windows platforms. You can use
1127
+PowerShell Remoting (PSRP) over WinRM from Windows to connect to other Windows machines. PowerShell
1128
+also supports remoting over SSH on all platforms (Windows, macOS, and Linux). For more information,
1129
+see [SSH remoting in PowerShell][25].
11311130
11321131
### PowerShell Direct for Containers tries to use `pwsh` first
11331132
⋯ 73 unchanged lines
12071206
12081207
## Telemetry can only be disabled with an environment variable
12091208
1210
−PowerShell sends basic telemetry data to Microsoft when it is launched. The data includes the OS
1209
+PowerShell sends basic telemetry data to Microsoft when it's launched. The data includes the OS
12111210
name, OS version, and PowerShell version. This data allows us to better understand the environments
12121211
where PowerShell is used and enables us to prioritize new features and fixes.
12131212
⋯ 41 unchanged lines
Microsoft's Markdown source from MicrosoftDocs/PowerShell-Docs, © Microsoft Corporation, under CC BY 4.0. Changed lines with up to 3 unchanged lines around each; ChangeIntel kept this copy 10 Oct 03:16 UTC. The commit date is when the source changed, which can be hours or days before Learn published it.