I'm wondering if there's a way to run a PowerShell script such that both the commands and the output of each line of the script are printed. For example, in Bash you would write bash -x myscript
or place a set -x
at the top of your script. In Batch, you would omit the @echo off
traditionally left at the top of your script. Does PowerShell have an equivalent of these constructs?
Things I've tried: Running powershell -? | sls verbose
, which turned up nothing.
However, if you need to manually write verbose output from your functions, you'll need to manually check that each function is called with the verbose flag. This can be done by checking$PSCmdlet. MyInvocation. BoundParameters["Verbose"] from inside your function.
Typically, the verbose message stream is used to deliver more in depth information about command processing. By default, the verbose message stream is not displayed, but you can display it by changing the value of the $VerbosePreference variable or using the Verbose common parameter in any command.
There are several ways to enable Verbose Mode. During startup, the screen may display which key(s) to press on the keyboard to enable Verbose Mode. Usually, users would press the Esc (escape) key for Linux, or the keyboard shortcut Ctrl + V for Microsoft Windows, and Command + V for macOS.
Press F5 or, on the toolbar, click the Run Script icon, or on the Debug menu, click Run/Continue or, in the Console Pane, type C and then press ENTER . This causes the script to continue running to the next breakpoint or to the end of the script if no further breakpoints are encountered.
Just goes to show, @JamesKo, if you ask the wrong question you get the wrong answer :-(. Several people put forth good-faith answers here based on (a) lack of Linux exposure and (b) your use of the term verbose. In the following I will walk you through how Linux relates to PowerShell on this topic, but feel free to jump to the answer at the end if you are in a hurry. :-)
Background
In PowerShell, verbose has a very specific meaning which the PowerShell man page is even rather vague about:
Displays detailed information about the operation performed by the command. This information resembles the information in a trace or in a transaction log. This parameter works only when the command generates a verbose message.
It even sounds like what you want... but let's compare that to the Linux documentation for set -x
which, depending on your flavor of Linux, could be this (from man-pages project)...
The shell shall write to standard error a trace for each command after it expands the command and before it executes it.
or this (from gnu)...
Print a trace of simple commands, for commands, case commands, select commands, and arithmetic for commands and their arguments or associated word lists after they are expanded and before they are executed.
The very first line of your question clearly and concisely agrees with these. But verbose in PowerShell is different. In a nutshell, turning on verbose mode (be it with the -Verbose
command line switch or the $VerbosePreference
variable) simply enables output from the verbose stream to the console. (Just like Linux offers two streams, stdout and stderr, PowerShell offers multiple streams: output stream, error stream, warning stream, verbose stream, and debug stream. You work with these streams in an identical fashion to that of Linux--you can even use, e.g., commands 4>&1
to merge the verbose stream to stdout, for example. (You can read more about PowerShell's multiple output streams in the Basic Writing Streams section of PowerShell One-Liners: Accessing, Handling and Writing Data and a good quick reference is the Complete Guide to PowerShell Punctuation.)
The Answer
The Set-PSDebug command will give you bash-equivalent tracing. You can even adjust the tracing detail with the -Trace
parameter. First, here's the control, before using Set-PSDebug
:
PS> Get-PSDepth 0
With a value of 1 you get each line of code as it executes, e.g.:
PS> Set-PSDebug -Trace 1 PS> Get-PSDepth DEBUG: 1+ >>>> Get-PSDepth DEBUG: 141+ >>>> { DEBUG: 142+ >>>> $nest = -1 DEBUG: 143+ >>>> $thisId = $pid DEBUG: 144+ while ( >>>> (ps -id $thisId).Name -eq 'powershell') { DEBUG: 145+ >>>> $thisId = (gwmi win32_process -Filter "processid='$thisId'").ParentProcessId DEBUG: 146+ >>>> $nest++ DEBUG: 144+ while ( >>>> (ps -id $thisId).Name -eq 'powershell') { DEBUG: 148+ >>>> $nest 0 DEBUG: 149+ >>>> }
With a value of 2 you also get variable assignments and code paths:
PS> Set-PSDebug -Trace 2 PS> Get-PSDepth DEBUG: 1+ >>>> Get-PSDepth DEBUG: ! CALL function '<ScriptBlock>' DEBUG: 141+ >>>> { DEBUG: ! CALL function 'Get-PSDepth' (defined in file 'C:\Users\msorens\Documents\WindowsPowerShell\profile.ps1') DEBUG: 142+ >>>> $nest = -1 DEBUG: ! SET $nest = '-1'. DEBUG: 143+ >>>> $thisId = $pid DEBUG: ! SET $thisId = '9872'. DEBUG: 144+ while ( >>>> (ps -id $thisId).Name -eq 'powershell') { DEBUG: 145+ >>>> $thisId = (gwmi win32_process -Filter "processid='$thisId'").ParentProcessId DEBUG: ! SET $thisId = '10548'. DEBUG: 146+ >>>> $nest++ DEBUG: ! SET $nest = '0'. DEBUG: 144+ while ( >>>> (ps -id $thisId).Name -eq 'powershell') { DEBUG: 148+ >>>> $nest 0 DEBUG: 149+ >>>> }
Those are traces of a simple cmdlet I wrote called Get-PSDepth
. It prints the commands, assignments, etc. with the DEBUG
prefix, intermixed with the actual output, which in this case is the single line containing just 0
.
You can always use the below in your script.
$VerbosePreference="Continue"
Note: You have to open the shell in elevated mode.
Below screenshot is for reference.
Hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With