Public mode

No access to your tenant or devices. Every item links to its source. What this means

Some sources or documents need attention: 258/260 feeds/APIs · 416/439 docs · checked 22:55 UTC Customize Public modeDiscuss ChangeIntel on Discord

Windows PowerShell and PowerShell 7 compatibility

This page's changes and edits · All guidance changes

Microsoft's edit ·

Cleanup metadata frontmatter (#8105)

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.

ChangeIntel

An IT change radar: releases, security, known issues, retirements, documentation changes, and service status from public sources. Every item links to supporting evidence; dates and statuses can change after they are read.

Sources read 20 Oct 22:55 UTC · 258 of 260 readable · 256 fully read · documentation 416/439 current