0

Here are my scripts

Parent.ps1

[CmdletBinding(SupportsShouldProcess=$true)]
Param()
Write-Verbose 'Triggering Child Process...'
Start-Process PowerShell.exe '.\Child.ps1'

Child.ps1

[CmdletBinding(SupportsShouldProcess=$true)]
Param()
Write-Verbose 'Child Process Triggered.'    # I want output from this line to be displayed
Write-Output 'Child Process Triggered.'
Start-Sleep 10

I'm calling the parent script as below

powershell Parent.ps1 -Verbose

Actual outpt:

VERBOSE: Triggering Child Process...
Child Process Triggered.

Desired Output:

VERBOSE: Triggering Child Process...
VERBOSE: Child Process Triggered.
Child Process Triggered.
Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
tzman
  • 174
  • 1
  • 1
  • 11

1 Answers1

3

If you really want to run .\Child.ps1 via another PowerShell instance, in a new window, asynchronously:

Start-Process PowerShell.exe "-c .\Child.ps1 -Verbose:`$$($VerbosePreference -eq 'Continue')"

Note the use of -c (-Command) to signal what PowerShell CLI parameter the command string is passed to, to distinguish it from -f (-File). While not strictly necessary, because -c is the default in Windows PowerShell (powershell.exe), it helps to clarify, especially given that PowerShell (Core) 7+ (pwsh) now defaults to -f.

  • When you invoke your Parent.ps1 script with -Verbose (-vb), PowerShell translates this switch to a script-scoped $VerbosePreference variable with value Continue.

  • To propagate a switch value - on or off - programmatically, you can follow the switch name with : and a Boolean, e.g. -Verbose:$true.

    • Caveat: While something like -Verbose:$false is typically the same as not passing the switch at all, there are exceptions, and this is one of them: -Verbose:$false explicitly overrides a caller's $VerbosePreference preference variable to deactivate verbose output - see this answer.
    • That said, this isn't a concern in your case, given that you're launching a new PowerShell instance, and there's no session-internal caller.
  • The above uses an expandable string to translate the value of $VerbosePreference into the appropriate Boolean; note that the subexpression ($(...)) is prefixed with `$, i.e. an escaped $ character to be retained verbatim, because stringifying a Boolean results in either True or False, so the $ prefix is needed to turn it back into a Boolean the way it needs to be represented as a literal in source code.

Note that if you were to invoke .\Child.ps1 directly from your parent script, it would automatically "inherit" the parent's $VerbosePreference value (it would see the same value by default, due to PowerShell's dynamic scoping).


A note on -c (-Command) vs. -f (-File) and PowerShell (Core) 7+:

For invoking a PowerShell script file (.ps1) via the CLI, it is generally sufficient and preferable for robust passing of verbatim arguments to use the -f (-File) parameter; -c (-Command) is only needed if you need the command string to be evaluated as PowerShell code.

In Windows PowerShell (powershell.exe), the -f parameter doesn't recognize Boolean argument values, unfortunately, which is why -c is used in the solution above. This limitation has been fixed in PowerShell (Core) 7+ (pwsh.exe).

See also:

mklement0
  • 382,024
  • 64
  • 607
  • 775