invoke-command with a variable path extracted from a service

Welcome Forums General PowerShell Q&A invoke-command with a variable path extracted from a service

Viewing 4 reply threads
  • Author
    Posts
    • #185885
      Participant
      Topics: 1
      Replies: 6
      Points: 62
      Rank: Member

      Hey all,

       

      I'm usually lurking in the background learning from other folks issues, but for once I have to come out of the shadows and ask for some assistance. I'm working on a script that needs to run a particular executable on remote servers with a lot of switches. The executable isn't always in the same location due to various factors outside of my control, but I'm finding it's location through WMI based on where a running service points to, then splitting the string and removing the exe and replacing it with the other one in the same location I'm interested in. So far so good, but then comes the point I need to run that exe using invoke-command and I'm having some issues when I tried to pass the path through a variable instead of hard-coding it. I haven't had a lot of need for invoke-command before, so I did what most people (should) do and I went digging through older posts in various powershell forums looking for answers, and looking for examples and tutorials. I learned a little that helped, but what they seem to indicate should work doesn't seem to for me.

      Since I was having issues with what I was doing, I decided to dumb this down to a local exe and play around to figure things out. So to start simple I pointed to c:\scripts\showmbrs.exe on my local machine.

      Icm  -computername mymachinename -scriptsblock { & “c:\scripts\showmbrs.exe”}

       

      This seems to work getting a response from the exe, but remember the real exe I'll be working with has a variable location so next I tried to pass it via a variable like I would in the actual script.

      $test = “c:\scripts\showmbrs.exe”
      icm  -computername mymachinename -scriptsblock { & $test}

      This gives me an error that after & the pipeline element produced an object that was not valid. Since $test should be a replacement string, this doesn't make sense to me. I've hunted for a couple of days, finding various posts that seem to work the same way I'm doing it. If anyone can show me what I'm missing here, I'd appreciate the help.

      For reference if you have additional input, where I will go from here is with an argument list holding multiple arguments to include other variables (hoping that will work but not there yet). My intended code looks something like:

       

      $myargs = “-rAatuvqe  -N $targethost -m $regManager -u $regID -p $regPass”
      icm  -computername mymachinename -scriptsblock { & $test}  -argumentlist $myargs

      Any insights will be appreciated.

    • #186077
      Senior Moderator
      Topics: 8
      Replies: 1141
      Points: 3,927
      Helping Hand
      Rank: Community Hero

      Thanks for letting us know what all you did, that was a very good explanation.

      coming to the problem,

      variable $myargs is being passed to the scriptblock properly using -ArgumentList, but there should be someone to receive it inside the script block.

      Think about a function/script, whenever we pass an input there will be somebody to receive the input inside the function/script. Those are achieved using Param() blocks. Hence you have to define parmeters for the scriptblock.

      Invoke-Command -ComputerName $ComputerName -ScriptBlock {
          Param($Path,$targethost,$regManager,$regID,$regPass)
          & $Path -rAatuvqe  -N $targethost -m $regManager -u $regID -p $regPass
      } -ArgumentList $ExePath,$targethost,$regManager,$regID,$regPass
      

      variables wont be available inside the scriptblock as they are defined outside and is in a different scope.

      https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-5.1

    • #186083
      Participant
      Topics: 1
      Replies: 6
      Points: 62
      Rank: Member

      You are absolutely spot on, and I thank you for straightening out my thought process. Once you point out that I haven't defined it for icm, it starts to click into place. It now works perfectly.

      So for anyone who comes across this researching in the future, I'll rephrase the answer in laymen s terms to make it easier. My mistake was I was looking at invoke-command as a command, not as another function call. A command works very different than a function call and we have to code a bit different for that. Treating it as a function we have to define both from the caller end and from the called end and this is where param comes into play.

      Sometimes we overthink things and miss the obvious.

      Thank you @kvprasoon

    • #186197
      Senior Moderator
      Topics: 8
      Replies: 1141
      Points: 3,927
      Helping Hand
      Rank: Community Hero

      Invoke command is a cmdlet in PowerShell, but it executes a scriptblock or a script targetting a remote/local system. When we use a script/scriptblock, we use Param() block to accept parameters and values.

    • #186221
      Participant
      Topics: 3
      Replies: 136
      Points: 719
      Helping Hand
      Rank: Major Contributor

      Those are achieved using Param() blocks. Hence you have to define parmeters for the scriptblock.

      Thanks @kvprasoon, this makes sense, but something new to me. So far I have been achieving these scenarios using $using scope modifier to identify the local variable as a remote variable.

       

Viewing 4 reply threads
  • You must be logged in to reply to this topic.