Pass PsExec flags in variable

When I pass the flags in a variable, as seen below, PsExec outputs the instructions as it does when there is a syntax error.

But, if I replace the $flags variable with “-s -h -d -nobanner” (without the quotes), it works fine. If I put quotes around the flags, it won’t work again. I assume it has a problem with strings. Can I typecast it to another type to get it to work?

$computer = "computer1"

$flags = "-s -h -d -nobanner"

$path = "C:\Windows\SysWOW64\explorer.exe"

$arguments = ""
& .\PsExec.exe \\$computer $flags $path $arguments

Can you update the code snippet with which code is working and not working, little confused here…

I’m wondering why this doesn’t work

Function executePsexec ($computer,$flags,$path,$arguments)
{
& .\PsExec.exe \\$computer $flags $path $arguments
}
executePsExec -computer $env:COMPUTERNAME -flags "-s -h -d -nobanner" -path "C:\Windows\SysWOW64\explorer.exe"

But specifying the flags without putting them in a string works, as seen below. So how can I pass the flags into the function as a variable?

& .\PsExec.exe \\$computer -s -h -d -nobanner $path $arguments #this works

When “-s -h -d -nobanner” is set to a variable $flag and passed to psexec, the whole value of the variable is treated as an input for one of the psexec parameter, which is invalid.

Example

# working code
$r = 'localgroup'
$t = 'administrators'

net $r $t
net localgroup administrators

#not working
$r = 'localgroup administrators'

net $r

#above code will result into
net 'localgroup administrators'

@Crusher2156 As @kvprasoon said you when you send “-s -h -d -nobanner” to a variable, it will take everything as one variable therefore one method which he shows you and they have other approach as well which i have shown in below by taking your code an example which split the value during execution time itself.

Example:

$computer = "computer1"
$flags = "-s -h -d -nobanner"
$path = "C:\Windows\SysWOW64\explorer.exe"
$arguments = ""

Function executePsexec ($computer,$flags,$path,$arguments)
{
& .\PsExec.exe \\$computer $($flags.Split("")[0]) $($flags.Split("")[1]) $($flags.Split("")[2]) $($flags.Split("")[3]) $path $arguments
}

executePsExec -computer $computer -flags $flags -path $path -arguments $arguments

[quote quote=167077]@Crusher2156 As @kvprasoon said you when you send “-s -h -d -nobanner” to a variable, it will take everything as one variable therefore one method which he shows you and they have other approach as well which i have shown in below by taking your code an example which split the value during execution time itself.

Example:

$computer = "computer1"
$flags = "-s -h -d -nobanner"
$path = "C:\Windows\SysWOW64\explorer.exe"
$arguments = ""
Function executePsexec ($computer,$flags,$path,$arguments)
{
& .\PsExec.exe \\$computer $($flags.Split("")[0]) $($flags.Split("")[1]) $($flags.Split("")[2]) $($flags.Split("")[3]) $path $arguments
}
executePsExec -computer $computer -flags $flags -path $path -arguments $arguments
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[/quote] That's a great solution! Is there a way to make it more friendly so that I don't need to add a $flags.Split("") for every additional argument I supply?

It could be simply:

.\psexec \\computer1 -s -h -d -nobanner C:\Windows\SysWOW64\explorer.exe

Or

$computer = 'computer1'
$flags = '-s','-h','-d','-nobanner'
$path = 'C:\Windows\SysWOW64\explorer.exe'
$arguments = ''

.\psexec \\$computer $flags $path $arguments

another,

Invoke-Expression ".\PsExec.exe \\$computer $flags $path $arguments"

[quote quote=167107]another,

Invoke-Expression ".\PsExec.exe \\$computer $flags $path $arguments"
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[/quote] This way is much simpler.

I’m trying to run a one-liner powershell command remotely using PsExec, but when it reaches the “$_.ProcessName”, terminal blows up and acts like it doesn’t see the “$”. It says “the term ‘.ProcessName’ is not recognized”, obviously because it isn’t seeing the dollar sign. I tried escaping it with ` but that didn’t work.

+ ... anner powershell.exe Get-Process | Where-Object {.ProcessName -like " ...

This is the code I’m using:

executePsExec -computer $computer -flags "-s -h -nobanner" -path "powershell.exe" -arguments "Get-Process | Where-Object {$_.ProcessName -like `"*notepad*`" }"

much more to go…

$_ is a variable, which is the current object in the pipeline and you have the whole expression wrapped in double quotes, so just guess what would happen when the value of -argumentlist parameters gets evaluated…

hint: A variable inside double quotes…

[quote quote=167245]much more to go…

$_ is a variable, which is the current object in the pipeline and you have the whole expression wrapped in double quotes, so just guess what would happen when the value of -argumentlist parameters gets evaluated…

hint: A variable inside double quotes…

[/quote]
I think I see what you’re saying. I wouldn’t have $_ variable until the whole expression inside -arguments was executed, since it’s using Invoke-Expression. Is that correct?

Would the solution be to split up each command, between pipes, into an array element, and pass the array to -arguments, like in the example @js gave?

Yep here,

but its not about the Invoke-Expression, but the double quotes. Just make it single quotes for -argumentlist. Variables wont get invoked in single quotes and here you wont have need escape double quotes for notepad.

-arguments 'Get-Process | Where-Object {$_.ProcessName -like "*notepad*" }'

I see now. If you use quotes, your local computer will evaluate the $_ and it will throw an error because it has no member ProcessName. But if you use single quotes, it will pass the variable name plain text to the remote computer where it will see that it’s a variable.

When I do

-arguments 'Get-Process'

It provides the expected result, but PsExec hangs there and won’t move to the next line of the script. I’ve read up on this and heard it’s actually STDIN that’s hanging. If I physically type in terminal anything, it will say the remote powershell process exited.

What’s a simple way of exiting the remote PsExec session while also saving the output of the PsExec command?
EDIT: The argument “-inputformat none” works, but I’m not sure about its repercussions.