Windows PowerShell and PowerShell 7 compatibility
Microsoft's edit ·
Microsoft's commit message in MicrosoftDocs/PowerShell-Docs · commit f6d5658 · +1 −415 lines · also on GitHub
11
---
2
+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.
23
ms.date: 02/03/2020
34
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.
5
−---
6
−# Differences between Windows PowerShell 5.1 and PowerShell 7.x
7
−
8
−Windows PowerShell 5.1 is built on top of the .NET Framework v4.5. With the release of PowerShell
9
−6.0, PowerShell became an open source project built on .NET Core 2.0. PowerShell 7.0 is built on
10
−.NET Core 3.1. And, with the release of PowerShell 7.2, PowerShell will be built on .NET 6.0. Moving
11
−from the .NET Framework to .NET Core allowed PowerShell to become a cross-platform solution.
12
−PowerShell runs on Windows, macOS, and Linux.
13
−
14
−There are few differences in the PowerShell language between Windows PowerShell and PowerShell. The
15
−differences are most notable in the availability and behavior of PowerShell cmdlets between Windows
16
−and non-Windows platforms and the changes that stem from the differences between the .NET Framework
17
−and .NET Core.
18
−
19
−This article summarizes the significant differences and breaking changes between Windows PowerShell
20
−and the current version of PowerShell. This summary does not include new features or cmdlets that
21
−have been added. Nor does this article discuss what changed between versions. The goal of this
22
−article is to present the current state of PowerShell and how that is different from Windows
23
−PowerShell. For a detailed discussion of changes between versions and the addition of new features,
24
−see the **What's New** articles for each version.
25
−
26
−- [What's new in PowerShell 7.x](What-s-New-in-PowerShell-71.md)
27
−- [What's new in PowerShell 6.x](/previous-versions/powershell/scripting/whats-new/what-s-new-in-powershell-core-62?view=powershell-6&preserve-view=true)
28
−
29
−## .NET Framework vs .NET Core
30
−
31
−PowerShell on Linux and macOS uses .NET Core, which is a subset of the full .NET Framework on
32
−Microsoft Windows. This is significant because PowerShell provides direct access to the underlying
33
−framework types and methods. As a result, scripts that run on Windows may not run on non-Windows
34
−platforms because of the differences in the frameworks. For more information about changes in .NET
35
−Core, see
36
−[Breaking changes for migration from .NET Framework to .NET Core](/dotnet/core/compatibility/fx-core).
37
−
38
−With the advent of
39
−[.NET Standard 2.0](https://devblogs.microsoft.com/dotnet/introducing-net-standard/), PowerShell can
40
−load many traditional Windows PowerShell modules without modification. Additionally, PowerShell 7
41
−includes a Windows PowerShell Compatibility feature that allows you to use Windows PowerShell
42
−modules that still require the full framework.
43
−
44
−For more information see:
45
−
46
−- [about_Windows_PowerShell_Compatibility](/powershell/module/microsoft.powershell.core/about/about_windows_powershell_compatibility)
47
−- [PowerShell 7 module compatibility](module-compatibility.md)
48
−
49
−[!INCLUDE [Product terminology](../../includes/product-terms.md)]
50
−
51
−## Modules no longer shipped with PowerShell
52
−
53
−For various compatibility reasons, the following modules are no longer included in PowerShell.
54
−
55
−- ISE
56
−- Microsoft.PowerShell.LocalAccounts
57
−- Microsoft.PowerShell.ODataUtils
58
−- Microsoft.PowerShell.Operation.Validation
59
−- PSScheduledJob
60
−- PSWorkflow
61
−- PSWorkflowUtility
62
−
63
−### PowerShell Workflow
64
−
65
−[PowerShell Workflow][workflow] is a feature in Windows PowerShell that builds on top of
66
−[Windows Workflow Foundation (WF)][workflow-foundation] that enables the creation of robust runbooks
67
−for long-running or parallelized tasks.
68
−
69
−Due to the lack of support for Windows Workflow Foundation in .NET Core, we removed PowerShell
70
−Workflow from PowerShell.
71
−
72
−In the future, we would like to enable native parallelism/concurrency in the PowerShell language
73
−without the need for PowerShell Workflow.
74
−
75
−If there is a need to use checkpoints to resume a script after the OS restarts, we recommend
76
−using Task Scheduler to run a script on OS startup, but the script would need to maintain
77
−its own state (like persisting it to a file).
78
−
79
−[workflow]: /previous-versions/powershell/scripting/components/workflows-guide
80
−[workflow-foundation]: /dotnet/framework/windows-workflow-foundation/
81
−
82
−## Cmdlets removed from PowerShell
83
−
84
−For the modules that are included in PowerShell, the following cmdlets were removed from PowerShell
85
−for various compatibility reasons or the use of unsupported APIs.
86
−
87
−CimCmdlets
88
−
89
−- `Export-BinaryMiLog`
90
−
91
−Microsoft.PowerShell.Core
92
−
93
−- `Add-PSSnapin`
94
−- `Export-Console`
95
−- `Get-PSSnapin`
96
−- `Remove-PSSnapin`
97
−- `Resume-Job`
98
−- `Suspend-Job`
99
−
100
−Microsoft.PowerShell.Diagnostics
101
−
102
−- `Export-Counter`
103
−- `Import-Counter`
104
−
105
−Microsoft.PowerShell.Management
106
−
107
−- `Add-Computer`
108
−- `Checkpoint-Computer`
109
−- `Clear-EventLog`
110
−- `Complete-Transaction`
111
−- `Disable-ComputerRestore`
112
−- `Enable-ComputerRestore`
113
−- `Get-ComputerRestorePoint`
114
−- `Get-ControlPanelItem`
115
−- `Get-EventLog`
116
−- `Get-Transaction`
117
−- `Get-WmiObject`
118
−- `Invoke-WmiMethod`
119
−- `Limit-EventLog`
120
−- `New-EventLog`
121
−- `New-WebServiceProxy`
122
−- `Register-WmiEvent`
123
−- `Remove-Computer`
124
−- `Remove-EventLog`
125
−- `Remove-WmiObject`
126
−- `Reset-ComputerMachinePassword`
127
−- `Restore-Computer`
128
−- `Set-WmiInstance`
129
−- `Show-ControlPanelItem`
130
−- `Show-EventLog`
131
−- `Start-Transaction`
132
−- `Test-ComputerSecureChannel`
133
−- `Undo-Transaction`
134
−- `Use-Transaction`
135
−- `Write-EventLog`
136
−
137
−Microsoft.PowerShell.Utility
138
−
139
−- `Convert-String`
140
−- `ConvertFrom-String`
141
−
142
−PSDesiredStateConfiguration
143
−
144
−- `Disable-DscDebug`
145
−- `Enable-DscDebug`
146
−- `Get-DscConfiguration`
147
−- `Get-DscConfigurationStatus`
148
−- `Get-DscLocalConfigurationManager`
149
−- `Publish-DscConfiguration`
150
−- `Remove-DscConfigurationDocument`
151
−- `Restore-DscConfiguration`
152
−- `Set-DscLocalConfigurationManager`
153
−- `Start-DscConfiguration`
154
−- `Stop-DscConfiguration`
155
−- `Test-DscConfiguration`
156
−- `Update-DscConfiguration`
157
−
158
−### WMI v1 cmdlets
159
−
160
−The following WMI v1 cmdlets were removed from PowerShell:
161
−
162
−- `Register-WmiEvent`
163
−- `Set-WmiInstance`
164
−- `Invoke-WmiMethod`
165
−- `Get-WmiObject`
166
−- `Remove-WmiObject`
167
−
168
−The CimCmdlets module (aka WMI v2) cmdlets perform the same function and provide new functionality
169
−and a redesigned syntax.
170
−
171
−### `New-WebServiceProxy` cmdlet removed
172
−
173
−.NET Core does not support the Windows Communication Framework, which provide services for using the
174
−SOAP protocol. This cmdlet was removed because it requires SOAP.
175
−
176
−### `*-Transaction` cmdlets removed
177
−
178
−These cmdlets had very limited usage. The decision was made to discontinue support for them.
179
−
180
−- `Complete-Transaction`
181
−- `Get-Transaction`
182
−- `Start-Transaction`
183
−- `Undo-Transaction`
184
−- `Use-Transaction`
185
−
186
−### `*-EventLog` cmdlets
187
−
188
−Due to the use of unsupported APIs, the `*-EventLog` cmdlets have been removed from PowerShell.
189
−`Get-WinEvent` and `New-WinEvent` are available to get and create events on Windows.
190
−
191
−### Cmdlets that use the Windows Presentation Framework (WPF)
192
−
193
−.NET Core 3.1 added support for WPF, so the release of PowerShell 7.0 restored the following
194
−Windows-specific features:
195
−
196
−- The `Show-Command` cmdlet
197
−- The `Out-GridView` cmdlet
198
−- The **ShowWindow** parameter of `Get-Help`
199
−
200
−### PowerShell Desired State Configuration (DSC) changes
201
−
202
−`Invoke-DscResource` was restored as an experimental feature in PowerShell 7.0.
203
−
204
−Beginning with PowerShell 7.2, the PSDesiredStateConfiguration module has been removed from
205
−PowerShell and has been published to the PowerShell Gallery. For more information, see the
206
−[announcement](https://devblogs.microsoft.com/powershell/announcing-psdesiredstateconfiguration-on-powershell-gallery/)
207
−in the PowerShell Team blog.
208
−
209
−## Engine/language changes
210
−
211
−### Renamed `powershell.exe` to `pwsh.exe`
212
−
213
−The binary name for PowerShell has been changed from `powershell(.exe)` to `pwsh(.exe)`. This
214
−change provides a deterministic way for users to run PowerShell on machines and support
215
−side-by-side installations of Windows PowerShell and PowerShell.
216
−
217
−Additional changes to `pwsh(.exe)` from `powershell.exe`:
218
−
219
−- Changed the first positional parameter from `-Command` to `-File`. This change fixes the usage of
220
− `#!` (aka as a shebang) in PowerShell scripts that are being executed from non-PowerShell shells
221
− on non-Windows platforms. It also means that you can run commands like `pwsh foo.ps1` or
222
− `pwsh fooScript` without specifying `-File`. However, this change requires that you explicitly
223
− specify `-c` or `-Command` when trying to run commands like `pwsh.exe -Command Get-Command`.
224
−- `pwsh` accepts the `-i` (or `-Interactive`) switch to indicate an interactive shell.
225
− This allows PowerShell to be used as a default shell on Unix platforms.
226
−- Removed parameters `-ImportSystemModules` and `-PSConsoleFile` from `pwsh.exe`.
227
−- Changed `pwsh -version` and built-in help for `pwsh.exe` to align with other native tools.
228
−- Invalid argument error messages for `-File` and `-Command` and exit codes consistent with Unix
229
− standards
230
−- Added `-WindowStyle` parameter on Windows. Similarly, package-based installations updates on
231
− non-Windows platforms are in-place updates.
232
−
233
−The shortened name is also consistent with naming of shells on non-Windows platforms.
234
−
235
−### Support running a PowerShell script with bool parameter
236
−
237
−Previously, using `pwsh.exe` to execute a PowerShell script using `-File` provided no way to pass
238
−`$true`/`$false` as parameter values. Support for `$true`/`$false` as parsed values to parameters
239
−was added. Switch values are also supported.
240
−
241
−### Support PowerShell as a default Unix shell
242
−
243
−On Unix, it is a convention for shells to accept `-i` for an interactive shell and many tools
244
−expect this behavior (`script` for example, and when setting PowerShell as the default shell) and
245
−calls the shell with the `-i` switch. This change is breaking in that `-i` previously could be used
246
−as short hand to match `-inputformat`, which now needs to be `-in`.
247
−
248
−### Custom snap-ins
249
−
250
−[PowerShell snap-ins][snapin] are a predecessor to PowerShell modules that do not have widespread
251
−adoption in the PowerShell community.
252
−
253
−Due to the complexity of supporting snap-ins and their lack of usage in the community, we no longer
254
−support custom snap-ins in PowerShell.
255
−
256
−[snapin]: /powershell/module/microsoft.powershell.core/about/about_pssnapins
257
−
258
−### Experimental feature flags
259
−
260
−We enabled support for [Experimental Features][exp]. This allows PowerShell developers to deliver
261
−new features and get feedback before the design is complete. This way we avoid making breaking
262
−changes as the design evolves.
263
−
264
−Use `Get-ExperimentalFeature` to get a list of available experimental features. You can enable or
265
−disable these features with `Enable-ExperimentalFeature` and `Disable-ExperimentalFeature`.
266
−
267
−[exp]: /powershell/module/Microsoft.PowerShell.Core/About/about_Experimental_Features
268
−
269
−### Load assembly from module base path before trying to load from the GAC
270
−
271
−Previously, when a binary module has the module assembly in GAC, we loaded the assembly from GAC
272
−before trying to load it from module base path.
273
−
274
−### Skip null-element check for collections with a value-type element type
275
−
276
−For the `Mandatory` parameter and `ValidateNotNull` and `ValidateNotNullOrEmpty` attributes, skip
277
−the null-element check if the collection's element type is value type.
278
−
279
−### Preserve `$?` for **ParenExpression**, **SubExpression** and **ArrayExpression**
280
−
281
−This PR alters the way we compile subpipelines `(...)`, subexpressions `$(...)` and array
282
−expressions `@()` so that `$?` is not automatically **true**. Instead the value of `$?` depends on
283
−the result of the pipeline or statements executed.
284
−
285
−### Fix `$?` to not be `$false` when native command writes to `stderr`
286
−
287
−`$?` is not set to `$false` when native command writes to `stderr`. It is common for native
288
−commands to write to `stderr` without intending to indicate a failure. `$?` is set to `$false` only
289
−when the native command has a non-zero exit code.
290
−
291
−### Make `$ErrorActionPreference` not affect `stderr` output of native commands
292
−
293
−It is common for native commands to write to `stderr` without intending to indicate a failure. With
294
−this change, `stderr` output is still captured in **ErrorRecord** objects, but the runtime no longer
295
−applies `$ErrorActionPreference` if the **ErrorRecord** comes from a native command.
296
−
297
−### Change `$OutputEncoding` to use `UTF-8 NoBOM` encoding rather than ASCII
298
−
299
−The previous encoding, ASCII (7-bit), would result in incorrect alteration of the output in some
300
−cases. Making `UTF-8 NoBOM` the default preserves Unicode output with an encoding supported by most
301
−tools and operating systems.
302
−
303
−### Unify cmdlets with parameter `-Encoding` to be of type `System.Text.Encoding`
304
−
305
−The `-Encoding` value `Byte` has been removed from the filesystem provider cmdlets. A new
306
−parameter, `-AsByteStream`, is now used to specify that a byte stream is required as input or that
307
−the output is a stream of bytes.
308
−
309
−### Change `New-ModuleManifest` encoding to `UTF8NoBOM` on non-Windows platforms
310
−
311
−Previously, `New-ModuleManifest` creates `psd1` manifests in UTF-16 with BOM, creating a problem for
312
−Linux tools. This breaking change changes the encoding of `New-ModuleManifest` to be UTF (no BOM) in
313
−non-Windows platforms.
314
−
315
−### Remove `AllScope` from most default aliases
316
−
317
−To speed up scope creation, `AllScope` was removed from most default aliases. `AllScope` was left
318
−for a few frequently used aliases where the lookup was faster.
319
−
320
−### `-Verbose` and `-Debug` no longer overrides `$ErrorActionPreference`
321
−
322
−Previously, if `-Verbose` or `-Debug` were specified, it overrode the behavior of
323
−`$ErrorActionPreference`. With this change, `-Verbose` and `-Debug` no longer affect the behavior
324
−of `$ErrorActionPreference`.
325
−
326
−Also, the `-Debug` parameter sets `$DebugPreference` to **Continue** instead of **Inquire**.
327
−
328
−### Make `$PSCulture` consistently reflect in-session culture changes
329
−
330
−In Windows PowerShell, the current culture value is cached, which can allow the value to get out of
331
−sync with the culture is change after session-startup. This caching behavior is fixed in PowerShell
332
−core.
333
−
334
−### Allow explicitly specified named parameter to supersede the same one from hashtable splatting
335
−
336
−With this change, the named parameters from splatting are moved to the end of the parameter list so
337
−that they are bound after all explicitly specified named parameters are bound. Parameter binding for
338
−simple functions doesn't throw an error when a specified named parameter cannot be found. Unknown
339
−named parameters are bound to the `$args` parameter of the simple function. Moving splatting to the
340
−end of the argument list changes the order the parameters appears in `$args`.
341
−
342
−For example:
343
−
344
−```powershell
345
−function SimpleTest {
346
− param(
347
− $Name,
348
− $Path
349
− )
350
− "Name: $Name; Path: $Path; Args: $args"
351
−}
352
−```
353
−
354
−In the previous behavior, **MyPath** is not bound to `-Path` because it's the third argument in the
355
−argument list. ## So it ends up being stuffed into '$args' along with `Blah = "World"`
356
−
357
−```powershell
358
−PS> $hash = @{ Name = "Hello"; Blah = "World" }
359
−PS> SimpleTest @hash "MyPath"
360
−Name: Hello; Path: ; Args: -Blah: World MyPath
361
−```
362
−
363
−With this change, the arguments from `@hash` are moved to the end of the argument list. **MyPath**
364
−becomes the first argument in the list, so it is bound to `-Path`.
365
−
366
−```powershell
367
−PS> SimpleTest @hash "MyPath"
368
−Name: Hello; Path: MyPath; Args: -Blah: World
369
−```
370
−
371
−### Added `&` operator for job control
372
−
373
−Putting `&` at the end of a pipeline causes the pipeline to be run as a PowerShell job. When a
374
−pipeline is backgrounded, a job object is returned. Once the pipeline is running as a job, all of
375
−the standard `*-Job` cmdlets can be used to manage the job. Variables (ignoring process-specific
376
−variables) used in the pipeline are automatically copied to the job so `Copy-Item $foo $bar &` just
377
−works. The job is also run in the current directory instead of the user's home directory.
378
−
379
−### New methods/properties on `PSCustomObject`
380
−
381
−We've added new methods and properties to `PSCustomObject`. `PSCustomObject` now includes a
382
−`Count`/`Length` property like other objects.
383
−
384
−```powershell
385
−$PSCustomObject = [pscustomobject]@{foo = 1}
386
−
387
−$PSCustomObject.Length
388
−```
389
−
390
−```Output
391
−1
392
−```
393
−
394
−```powershell
395
−$PSCustomObject.Count
396
−```
397
−
398
−```Output
399
−1
400
−```
401
−
402
−This work also includes `ForEach` and `Where` methods that allow you to operate and filter on
403
−`PSCustomObject` items:
404
−
405
−```powershell
406
−$PSCustomObject.ForEach({$_.foo + 1})
407
−```
408
−
409
−```Output
410
−2
411
−```
412
−
413
−```powershell
414
−$PSCustomObject.Where({$_.foo -gt 0})
415
−```
416
−
417
−```Output
418
−foo
4195
---
4206
1
4217
```
⋯ 430 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.