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 ·

Fix damaged file (#8107)

Microsoft's commit message in MicrosoftDocs/PowerShell-Docs · commit c1e5ad3 · +416 −2 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.
3 −ms.date: 02/03/2020
2 +ms.date: 09/17/2021
43 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
5419 ---
6420 1
7421 ```
⋯ 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