Skip to content

Various corrections to about_Pwsh #6548

@mklement0

Description

@mklement0

Formatting problem:

When the plain-text version of this topic is embedded in https://github.com/PowerShell/PowerShell/blob/master/src/Microsoft.PowerShell.ConsoleHost/resources/ManagedEntranceStrings.resx (for use in pwsh -?),
the ```Output<newline>...<newline>``` block turns into """Output<newline>... - that is, an extraneous """Output is retained.

Content problems:

Explains how to use the pwsh command-line tool

For conceptual clarity, I suggest rephrasing to something like:
"Explains how to use pwsh, PowerShell's command-line interface."

Displays the syntax and describes the command-line switches.

"Switch" in PowerShell parlance is a subtype of parameter; therefore, "parameters" is the better choice.

Re -Command:

A string passed to Command will still be executed as PowerShell,

"as PowerShell" -> "as PowerShell code"

The results are returned to the parent shell as deserialized XML objects, not live objects.

This (a) only applies when the -Command argument is an actual script block and therefore only applies when calling from PowerShell and (b) the CLIXML serialization / deserialization is transparent to the user (the call is internally translated to an -EncodedCommand ... -OutputFormat XML call and the engine automatically deserializes the CLIXML output received).

What matters to the end user is:

  • Using -Command <script-block> allows you to both send and receive objects rather than mere strings,
  • but these objects will undergo XML-based serialized and deserialization (as in remoting and background jobs), and are therefore not live objects and have limited type fidelity.

It's also worth documenting how the process exit code is set with -Command:

It is the success status of the last (executed) command that determines the exit code: 0, if $? is $true, 1 otherwise. Note that this means that if the last command is an external program or a *.ps1 script that deliberately sets an exit code other than 0 or 1, that specific exit code is lost (abstracted to 1); to preserve that specific exit code, add exit $LASTEXITCODE to your command string or script block.

Similarly, 1 is used when a script-terminating (runspace-terminating) error (e.g., with throw or -ErrorAction Stop) occurs and when execution is interrupted with Ctrl-C.

Re -File:

The specified script runs in the local scope ("dot-sourced"), so that the functions and variables that the script creates are available in the current session.

Without context, this is confusing: by far the most common use case for -File is to execute the given script and then exit (which is the default behavior), so there will be no current session in the usual, interactive sense.
That dot-sourcing is technically performed (although it arguably shouldn't) is only of relevance if you explicitly choose to keep the session alive and transition to an interactive experience after script execution, with -NoExit.

It's also worth documenting how the process exit code is set with -File:

If the *.ps1 script invoked terminates with an exit command, the exit code is set to the numeric argument given (e.g., exit 2 or 0 by default (just exit). Otherwise, with normal termination, the exit code is always 0.

Similar to -Command, when a script-terminating (runspace-terminating) error occurs, the exit code is set to 1.

However, unlike with -Command, when the execution is interrupted with Ctrl-C the exit code is 0(!).

Re -EncodedCommand:

Use this parameter to submit commands to PowerShell that require complex quotation marks or curly braces

"require complex quotation marks or curly braces" -> "would otherwise require complex, nested quoting"

Also worth relating that to -Command <script-block>: if you use the latter - available from inside PowerShell only - you also needn't worry about complex quoting, and you can additionally pass and receive - automatically serialized and deserialized - objects.

-EncodedCommand is therefore primarily needed for calling the PowerShell CLI from the outside.

The string must be formatted using UTF-16 character encoding.

I suggest rephrasing this to something like: "The Base64 representation must be based on a UTF-16 encoded string (which PowerShell strings by default are)."

Re -ExecutionPolicy:

Sets the default execution policy for the current session and saves it in the $env:PSExecutionPolicyPreference environment variable.

It should be mentioned that this parameter is ignored on Unix-like platforms, where execution policies aren't supported; similarly, the environment variable isn't set there.

This parameter does not change the PowerShell execution policy that is set in the registry.

Since PowerShell Core on Window doesn't store execution policies in the registry, either mention the fact that it uses .config.json files here as well or - for brevity - just say something like "does not change the persistently configured execution policies".

Re -NoLogo:

Worth noting that this switch is only necessary for hiding the logo when starting an interactive session (e.g., pwsh -nologo; with -File and -Command the logo never prints.

Re -NonInteractive:

(a) Up to at least v7.0, the nonsensical invocation pwsh -Noninteractive is unexpectedly permitted - see PowerShell/PowerShell#13518

(b) Clarify that -NonInteractive means: any attempts to use interactive features in the session - namely Read-Host and confirmation prompts - will result in statement-terminating errors.

Re -NoProfile:

Does not load the PowerShell profile.

"profile" -> "profiles" (plural), given that several profiles exist (CurrentUserCurrentHost, CurrentUserAllHosts, AllUsersCurrentHost, AllUsersAllHosts) and given that the switch suppresses loading of them all.

Re -OutputFormat XML:

Worth mentioning that:

  • From inside PowerShell Import-CliXml can be used to "rehydrate" the serialized objects, but ...
  • ... that isn't necessary if you pass a script block to -Command, because that both implies use of -OutputFormat XML and automatically performs Import-CliXml (in effect) on the output received.

To put it differently:

  • Inside PowerShell, pass a script block to -Command to get deserialized objects rather than mere strings as output.

  • Outside PowerShell, -OutputFormat XML requires you to parse the XML (CLIXML) output yourself.

Re -WindowStyle Hidden:

Worth pointing out that you cannot run PowerShell itself fully hidden this way, because a console window is currently invariably created first, causing an unwanted console window to flash briefly - it only works as intended when starting another PowerShell instance from inside a session - see PowerShell/PowerShell#3028

However, a future PowerShell version may solve this problem: PowerShell/PowerShell#3028 (comment)

Re -Help, -?, /?:

You can use either a hyphen or forward slash in Cmd.exe.

While recommending use of - only is definitely the way to go, note that /? works just fine from inside PowerShell too, even on Unix (and so do all other CLI parameters).


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Metadata

Metadata

Assignees

Labels

area-aboutArea - About_ topics

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions