RedirectStandardOutput works as when not added as a variable

Viewed 28

I'm trying to add the following as a parameter to Start-Process -RedirectStandardOutput $ENV:Temp\debugintune.log

If I literally type -RedirectStandardOutput $ENV:Temp\debugintune.log at the end of Start-Process, it works. If I instead use the variable $DebugRedir, I get:

Start-Process : A positional parameter cannot be found that accepts argument ' -RedirectStandardOutput C:\Users\myaccount\AppData\Local\Temp\debugintune.log'.

I've been pulling my hair out trying to find one works and one doesn't, when they appear to be the exact same thing. Any ideas?

# If running in a 32bit PowerShell session, restart in a 64bit session.
$ArgsString = ""
if ($ScriptDebug -eq $true){
    $DebugRedir = " -RedirectStandardOutput $ENV:Temp\debugintune.log"
    #Set-PSDebug -Trace 2
}
If ($ENV:PROCESSOR_ARCHITEW6432 -eq "AMD64") {
#    Try {
        foreach($k in $MyInvocation.BoundParameters.keys)
        {
            switch($MyInvocation.BoundParameters[$k].GetType().Name)
            {
                "SwitchParameter" {if($MyInvocation.BoundParameters[$k].IsPresent) { $argsString += "-$k " } }
                "String"          { $argsString += "-$k `"$($MyInvocation.BoundParameters[$k])`" " }
                "Uri"             { $argsString += "-$k `"$($MyInvocation.BoundParameters[$k])`" " }
                "Int32"           { $argsString += "-$k $($MyInvocation.BoundParameters[$k]) " }
                "Boolean"         { $argsString += "-$k `$$($MyInvocation.BoundParameters[$k]) " }
            }
        }`
       #This doesn't work 
       Start-Process -FilePath "$ENV:WINDIR\SysNative\WindowsPowershell\v1.0\PowerShell.exe" -ArgumentList "-File `"$($PSScriptRoot)\$($MyInvocation.MyCommand.Name)`" $($ArgsString)" -Wait $DebugRedir
       #This works - Start-Process -FilePath "$ENV:WINDIR\SysNative\WindowsPowershell\v1.0\PowerShell.exe" -ArgumentList "-File `"$($PSScriptRoot)\$($MyInvocation.MyCommand.Name)`" $($ArgsString)" -Wait -RedirectStandardOutput $ENV:Temp\debugintune.log
 #     }
  #  Catch {
   #     Throw "Failed to start 64-bit PowerShell"
    #}
    Exit
}
1 Answers

$DebugRedir = " -RedirectStandardOutput $ENV:Temp\debugintune.log"

You cannot pass a named argument (a target parameter name plus its value) using a single string variable; that only works for positional (value-only) arguments.

Passing (one or more) named arguments requires a hashtable-based technique called splatting:

# Define the named argument(s) to pass as the entries of a hashtable.
# Note that the key name does *not* include the leading "-"
$DebugRedir = @{ RedirectStandardOutput = "$ENV:Temp\debugintune.log" }

# ...

# To achieve splatting, pass the hashtable variable with sigil "@" instead of "$"
Start-Process @DebugRedir -FilePath "$ENV:WINDIR\SysNative\WindowsPowershell\v1.0\PowerShell.exe" -ArgumentList "-File `"$($PSScriptRoot)\$($MyInvocation.MyCommand.Name)`" $($ArgsString)" -Wait

As for what you tried:

Your string value in $DebugDir is invariably treated as a positional argument by Start-Process, and since there were no remaining unbound parameters in your call that accept a positional argument, a syntax error to that effect occurred.

Related