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

Viewing 11 reply threads
  • 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: 1160
      Points: 4,056
      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: 1160
      Points: 4,056
      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: 45
      Points: 243
      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: 28
      Replies: 751
      Points: 2,096
      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: 1160
      Points: 4,056
      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: 1160
      Points: 4,056
      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: 1160
      Points: 4,056
      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.

Viewing 11 reply threads
  • The topic ‘Pass PsExec flags in variable’ is closed to new replies.