Use a function:
function doOrEcho() {
$cmdLine = $Args
if ($MY_DEBUG_FLAG) { # echo
"$cmdLine"
} else { # execute
# Split into command (excecutable) and arguments
$cmd, $cmdArgs = $cmdLine
if ($cmdArgs) {
& $cmd $cmdArgs
} else {
& $cmd
}
}
}
Then invoke it as follows:
doOrEcho my_dangerous_command args
Limitations:
Only works with calls to external programs, not to PowerShell cmdlets or functions.
- Passing the elements of an array (
$cmdArgs) to an external program as individual arguments is a PowerShell technique called splatting; see this answer for more information, which also notes the general caveat that an empty string cannot be passed as an argument as-is, wether passed directly or as part of an array used for splatting.
As in your Bash solution, the echoed command will not reflect the original and/or necessary quoting for expanded arguments, so argument boundaries may be lost.
To demonstrate it (using a call to the ls Unix utility in PowerShell Core):
# Default behavior: *execute* the command.
PS> doOrEcho ls -1 $HOME
# ... listing of files in $HOME folder, 1 item per line.
# With debug flag set: only *echo* the command, with arguments *expanded*
PS> $MY_DEBUG_FLAG = $true; doOrEcho ls -1 $HOME
ls -1 /home/jdoe # e.g.
Kory Gill points out that PowerShell has the -WhatIf common parameter whose purpose is to preview operations without actually performing them.
However, -WhatIf is not the right solution for the task at hand:
Only cmdlets and advanced functions can implement this parameter (based on functionality provided by PowerShell) - doing so requires quite a bit more effort than the simple function above.
The intent behind -WhatIf is to show what data the command will operate on / what changes it will make to the system, whereas the intent behind the function above is to echo the command itself.
- For instance,
Remove-Item foo.txt -WhatIf would show something like this:
What if: Performing operation "Remove File" on Target "C:\tmp\foo.txt".
While you could technically still use -WhatIf in this use case, you'd then either have to use -WhatIf ad hoc to turn on echoing (doOrEcho -WhatIf ...) or set the $WhatIfPreference preference variable to $true - but doing so would then affect all cmdlets and functions that support -WhatIf while the variable is set; additionally, -WhatIf output is wordy, as shown above.
Arguably, it is Invoke-Command, PowerShell's generic command-invocation cmdlet, that should support -WhatIf as in the function above, but it doesn't.