Invoke-Expression cannot run a terminal statement that runs fine in a batch file

I created a PowerShell (PS) script that accomplishes the same objectives as a VBScript I used for many years. The VBScript enabled me to right-click on files selected in Windows Explorer, use the SendTo menu, and use WinRAR to archive (i.e., save a copy of) the selected files to a file named “Archive_Nu.rar” in the same directory.

The PS script (which I uploaded to Pastebin) creates a WinRAR Windows terminal command that is saved to a var, $rar_cmd, and is printed to the console. The contents of $rar_cmd run fine if I copy the Windows terminal command (in $rar_cmd) from the console and run it in a Windows terminal.

The PS script also saves $rar_cmd’s content to a batch file (i.e., a .cmd file), the full path of which batch file is in a var, $Tmp_rar_cmd_fullN. If I double-click on the Windows Explorer file, it also runs perfectly,

So my PS script runs the batch file using the statement,

Invoke-Expression $rar_cmd

on line 66 of the PS script because I was unable to get the $rar_cmd to run as follows:

Invoke-Expression $rar_cmd

If I try to run directly from PS using

Invoke-Expression $rar_cmd

I get the following error message:

Invoke-Expression: E:\Apps\UtilPS\FileS_selected_to_Archive_Nu_rar.ps1:66
Line |
66 | Invoke-Expression $rar_cmd
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
| Unexpected token ‘a’ in expression or statement.
Press Enter to continue…:

The statement:

write-host “$rar_cmd = $($rar_cmd)n”
generates the following output to the console:

$rar_cmd = “C:\Program Files\WinRAR\Rar.exe” a -av -dh -ep2 -wE:\Zmani\Logging -ilogE:\Zmani\Logging\Archive_Nu_rarbackup_log_2025-03-03_11-19.log -kb -m5 -r -rr3%%%% -t -ver -y -ri1:10 “E:\Apps\NirSoft\Archive_Nu.rar” @“E:\Zmani\Logging\TMP_args_ls_4_rar_2025-03-03_11-19_PmRpqnewM3.txt”

I would like to know why I get the error message shown above when I run the statement:

Invoke-Expression $rar_cmd

Any insights you could give me would be appreciated.

Thank you,
Marc

It gets a little tricky when trying to run executables via Powershell that have parameters. Because the first argument for rar.exe (‘a’) is not quoted Powershell interprets it as a command, can’t find it, and errors.
You would likely need to get your entire executable statement in quotes.

Or you may try Start-Process instead

Read here for warnings about Invoke-Expression: https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/avoid-using-invoke-expression

I had to work around command line injection security issues in a module. I ended up creating a function that I could use to run an executable from PowerShell. Maybe something like this would be useful.

function Invoke-Executable {
    param(
        [Parameter()]
        [string]$Executable,

        [Parameter(ValueFromRemainingArguments = $true)]
        [string[]]$ArgumentList = @()
    )

    $WorkingDirectory = (Get-Location).Path
    $Executable = (Get-Command $Executable).Source

    $StartInfo = New-Object System.Diagnostics.ProcessStartInfo
    $StartInfo.FileName = $Executable
    $StartInfo.RedirectStandardOutput = $true
    $StartInfo.RedirectStandardError = $true
    $StartInfo.UseShellExecute = $false
    $StartInfo.WorkingDirectory = $WorkingDirectory
    $StartInfo.Arguments = $ArgumentList -join ' '

    $Process = New-Object System.Diagnostics.Process
    $Process.StartInfo = $StartInfo
    $Process.Start() | Out-Null
    $Process.WaitForExit()

    Write-Output $($Process.StandardOutput.ReadToEnd())
    if ($Process.ExitCode -ne 0) {
        Write-Error $($Process.StandardError.ReadToEnd())
    }
}
1 Like