Passing arguments to a script run on remote computer

Hello, I have a vendor supplied script that checks the status of an application. It is on all of our servers. to run it locally, it is simply .\ctl.ps1 status -v
Of course I am trying to run this remotely rather than log into 100 servers. It seemed best to put the script on my workstation and do this:
invoke-command computer1 ctrl.ps1 -args status
This works for status, but I cannot figure out how to add the -v to get verbose results as in 'ctl.ps1 status -v`
I have tried using commas and other things but either I get an error or the -v is ignored. Obviously I thought this was simple but after a lot of searching I can find no examples for something like this. Thank you!

Try using -ArgumentList in the way shown at the bottom of this page:
https://ss64.com/ps/invoke-command.html
like "Status", "-v"

So a couple thoughts.

  1. Don’t use Aliases :slight_smile: -V and -args are aliases.
  2. where possible, don’t rely on positional parameters. These are ok for quick one off commands, but seriously, just write the extra characters and you’ll thank yourself later.

Next, because of how the -args, (-argumentlist) works, i don’t know if passing it via that method is going to be doable.

" Supplies the values of parameters for the scriptblock. The parameters in the script block are passed by position from the array value supplied to ArgumentList . This is known as array splatting. For more information about the behavior of ArgumentList , see about_Splatting."

To my knowledge, Verbose doesn’t have a ‘position’. Since it’s a common parameter, I’m not 100% how it would know which position it would be in, because you may or may not include certain common params. Using a script block is a little different as you can specify a param in order, then map those values to whatever command you are using, like in example 11 of the docs.

Have you tried to just add $VerbosePreference = ‘Continue’ at the start of the script? then you shouldn’t have to specify anything else. Then when you invoke it, it should respect it (but it shouldn’t stay for other sessions) and provide verbosity. Not usually a solution I’d go for, but in this case, given your context, I think it’s reasonable

Thanks, but unfortunately tried that and it runs the status but ignores the -v

Hmm ok, thank you. The script I am running is installed with an application we run on all of the servers. It takes commands like ctl.ps1 status -v, or ctl.ps1 restart, etc. So this works fine using a copy of the script on my workstation:
invoke-command -ComputerName SERVER -FilePath D:\scripts\ctl.ps1 -ArgumentList status

But I cannot figure out how to pass the second argument -v or -verbose. So, since the script is located on each remote computer, maybe the solution is to use a script block and run the script on the remote computer. Or actually use PSSession instead of invoke-command. Of course I thought this was going to be simple LOL! Thanks for your thoughts. This all started because I was handed a list of 100 servers to check the status of this application, and I ended up logging onto each one and running the script. So I completed it, but I know it will come up again so I am still trying to work this out.

Thanks all for your input. I can just use PSSession and it beats the heck out of actually logging into each server. I was just thinking with invoke-command I could have a nifty little script and maybe even a list of servers. But it’s beyond my PS user ability at the moment.

Perhaps I’m not understanding what you mean but what i suggested was modifying the script to set the Verbose Preference to continue. Somewhere near the top below the param block you simply add a line $VerbosePreference = 'Continue'. Since your script does verbose output presumably (you never provided a copy of the script file, but I assume it has the CmdletBinding at the top with the param block should should enable common params by default).

By doing so you no longer have to pass -Verbose to the script in anyway shape or form. All -Verbose does is set that switch to true, which basically says ‘give me verbose messages’. When you do it in your script already, by using $VerbosePreference = 'Continue' that means you do not need to pass it. about CommonParameters - PowerShell | Microsoft Learn

Also -V, you are inviting ambiguity into the conversation. What if that script actually had a variable named ‘V’ for some reason? I don’t think you do since you mentioned verbosity, but this is also why I suggest using the full -Verbose. the reason -V works is because it knows enough about it to assume the parameter. Using the full name and proper syntax t makes it easier for you and others to google what it is, and also to ensure you are communicating effectively about it. Less ambiguity is a good thing. Try doing -v on a command that has a parameter that starts with V. it won’t work. It’s just bad practice, which why I suggest not using aliases or -V… can’t recall what the Powershell feature name that does this.

To be very very clear:

This is not necessary with my solution.

As previously mentioned, using Invoke-Command and trying to pass common parameters I don’t think works. See previously linked docs and my previous quote from said doc.

I tested with a test script and what I suggested worked fine against winrm (Which is what is used when you use Invoke-Command).

1 Like

You don’t have to pass in the arguments. Just run the thing like you know it works.

Invoke-Command computer1 -ScriptBlock {
    \path\to\ctl.ps1 status -v
}

Things get trickier if the path to the command/executable contains spaces.

Hmm does this work? I feel like I’ve tried passing a file in the script block and it didn’t work in the past.

Edit:

yeah just ran this on one of my boxes, it just returns the filepath you give it back as a string:

When you surround it in quotes, yes it would. It’s a string at that point. Note my example does not have the path or file quoted

1 Like

Ah good to know. Thanks for the info. I’d say thats arguably a better solution than the one I suggested.

If the path has spaces then you have to use quotes and at that point the call operator & or .. You could also use Start-Process, Invoke-Command, or Invoke-Expression.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.