Pass PsExec flags in variable

Welcome Forums General PowerShell Q&A Pass PsExec flags in variable

This topic contains 13 replies, has 4 voices, and was last updated by

 
Participant
1 month, 4 weeks ago.

  • Author
    Posts
  • #166993

    Participant
    Topics: 13
    Replies: 42
    Points: 243
    Rank: Participant

    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
  • #166999

    Senior Moderator
    Topics: 8
    Replies: 1041
    Points: 3,438
    Helping Hand
    Rank: Community Hero

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

    • #167002

      Participant
      Topics: 13
      Replies: 42
      Points: 243
      Rank: Participant

      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
  • #167038

    Senior Moderator
    Topics: 8
    Replies: 1041
    Points: 3,438
    Helping Hand
    Rank: Community Hero

    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'
    
  • #167077

    Participant
    Topics: 0
    Replies: 44
    Points: 235
    Helping Hand
    Rank: Participant

    @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
    • #167095

      Participant
      Topics: 13
      Replies: 42
      Points: 243
      Rank: Participant

      @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

      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?

  • #167098
    js

    Participant
    Topics: 25
    Replies: 677
    Points: 1,623
    Helping Hand
    Rank: Community Hero

    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
    
  • #167107

    Senior Moderator
    Topics: 8
    Replies: 1041
    Points: 3,438
    Helping Hand
    Rank: Community Hero

    another,

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

    Participant
    Topics: 13
    Replies: 42
    Points: 243
    Rank: Participant

    another,

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

    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*`" }"
  • #167245

    Senior Moderator
    Topics: 8
    Replies: 1041
    Points: 3,438
    Helping Hand
    Rank: Community Hero

    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...

  • #167266

    Participant
    Topics: 13
    Replies: 42
    Points: 243
    Rank: Participant

    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...

    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?

  • #167293

    Senior Moderator
    Topics: 8
    Replies: 1041
    Points: 3,438
    Helping Hand
    Rank: Community Hero

    I think I see what you're saying. I wouldn't have $_ variable until the whole expression inside -arguments was executed

    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*" }'
    
  • #167338

    Participant
    Topics: 13
    Replies: 42
    Points: 243
    Rank: Participant

    I think I see what you're saying. I wouldn't have $_ variable until the whole expression inside -arguments was executed

    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*" }'
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    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.

  • #167359

    Participant
    Topics: 13
    Replies: 42
    Points: 243
    Rank: Participant

    I think I see what you're saying. I wouldn't have $_ variable until the whole expression inside -arguments was executed

    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*" }'
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    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.

You must be logged in to reply to this topic.