Parameters with multiple arguments

Hello,

I'm trying to create a script which has parameters that can pass through multiple arguments.

For example, I have;

param ( [string]$variable
)

I want to be able to use $variable as an argument for multiple commands, if possible by running this command through the script;

Examples:

Script.ps1 -variable command start server
Script.ps1 -variable command stop server
Script.ps1 -variable command restart server

The 'command' part can also change, so could this be another argument as well?

I've delt with parameters before but always used them on a more basic approach, for example;

Script.ps1 -variable true -servername name

But the issue is that I have a variable which I want the user to be able to supply with multiple arguments depending on what they want to do.

Hope this makes sense!

Thanks in advance!

August 25th, 2015 4:40am

Hi Jonathan,

that's where the automatic variable $args comes into play. Example:

function Get-Test
{
	$args[0]
	$args[1]
}

Get-Test "foo" "bar"

Cheers,
Fred

Free Windows Admin Tool Kit Click here and download it now
August 25th, 2015 4:55am

I cannot image such a scenario but that does not mean it doesn't make sense to anyone :)

You can try to use a string array for example

param(    
    [string[]]$stringArray
)

and call it like this

$stringArray=@("command","start","server") 
Script.ps1 -arg (,$stringArray)

hope it helps,

best regards

August 25th, 2015 4:56am

Hmmm,

Thanks for these... however not sure this is what I'm trying to get to.

Is there a way of the user simply stating an argument enables it in part of the script?.. Maybe that'd be a better way to do this.

So if a user runs Script.ps1 -command -server start (or stop) as an example?

Or does a -command always need to have something given to it? (Basically, if I can get the script setting -command to true without having the user to actually type -command true that's what I'd prefer).
Free Windows Admin Tool Kit Click here and download it now
August 25th, 2015 5:25am

I think I've found what I was looking for (at least partly) by changing [string] in param to [switch] !
August 25th, 2015 5:39am

Hi Jonathan,

just out of curiosity: How does using $args not work for you? (Just to be sure: You can iterate over each item in $args without specifying numbers and no matter how many, by using a foreach loop or cmdlet).

Cheers,
Fred

Free Windows Admin Tool Kit Click here and download it now
August 25th, 2015 5:46am

Hi Fred,

I think I need to be a bit clearer what I'm trying to achieve here for your understanding.

I'm trying to make a very user-friendly script that can control one of our programs and pass through commands to it. The programs commands are;

program.bat -command start cluster clustername
program.bat -command start member membername
program.bat -command stop cluster clustername
program.bat -command stop member membername

This is why I need to be able to run a single (initial command), for example -command (which I've now tried to a switch as a possible work-around). Then followed by arguments such as start/stop cluster clustername or start/stop member membername

We do currently have batch files which do this, they use the %1 %2 %3 %4 to pass the arguments through to the script which seems quite easy, however powershell's params seem a little more tricky to get this sort of thing working.

I tried the function method you suggested, but it didn't seem to pass the arguments when I ran script.ps1 Function-Name argument1 argument2 argument3

I hope this makes a little more sense!


August 25th, 2015 5:52am

Hi Jonathan,

just an example then with actual files.

Let's assume this is the file "D:\temp\test.ps1":

Param (

)

foreach ($a in $args)
{
    $a
}
Read-Host "press Enter to exit"

Then let's call it from a simple cmd prompt:

@powershell.exe -File "D:\temp\test.ps1" abc def ghi jkl mno pqr

Works quite well for me.

How would you imagine to call this?

Cheers,
Fred

Free Windows Admin Tool Kit Click here and download it now
August 25th, 2015 6:03am

Hi Fred,

Appreciating the help here - To be a little more clear again, the script is actually used for multiple things not just this one piece of functionaility. This is why I want only this part to activate if I specify the -command switch (So, ideally script.ps1 -command (activates this part of the script as I can say If $command -eq $true) and then that is followed by the arguments you've given.

Can this work?

August 25th, 2015 6:14am

Hi Jonathan,

sure it can, let's update this script a little:

Param (
	[switch]
	$Command
)

function Start-Command
{
	foreach ($a in $args)
	{
		$a
	}
}

if ($Command)
{
	Start-Command $args
}
Read-Host "press Enter to exit"

Now call it like this:

@powershell.exe -File "D:\temp\test.ps1" -Command abc def ghi jkl mno pqr

Cheers,
Fred

Free Windows Admin Tool Kit Click here and download it now
August 25th, 2015 6:20am

Hi Fred, thanks it feels like I'm getting somewhere finally.

A quick question, when I call the Start-Command with certain arguments, would you expect that I could output these to verify the arguments are being passed ?

When putting Write-Host "$Command" I get the expected True result.

But when putting down Write-Host "$args" I don't get anything back, am I missing something here?
August 25th, 2015 6:49am

Hi Jonathan,

glad to be of assistance. Write-Host $args should return the arguments as intended (it sure does, if I add it to my copy of the script, both inside Start-Command as well as outside).

Check your spelling and how you call the script (I'm literally using what I posted above, so if you just copied it, all should be well).

Cheers,
Fred

Free Windows Admin Tool Kit Click here and download it now
August 25th, 2015 8:03am

Hi Fred, thanks it feels like I'm getting somewhere finally.

A quick question, when I call the Start-Command with certain arguments, would you expect that I could output these to verify the arguments are being passed ?

When putting Write-Host "$Command" I get the expected True result.

But when putting down Write-Host "$args" I don't get anything back, am I missing something here?

args is an array, you can do

foreach ($a in $args)
	{
		Write-Host $a
	}

which will go through every string in $args and print it out.

August 25th, 2015 8:29am


args is an array, you can do

foreach ($a in $args)
	{
		Write-Host $a
	}

which will go through every string in $args and print it out.

Actually, that's already in the Example up there. You don't really need the Write-Host Cmdlet and using it is generally not recommended, though there may be some justification for using it in interactive scripts. Entrusting it to the output works just fine here.

It's curious why Jonathan's $args variable does not print out though, but without looking into it directly there is little we can recommend from afar but to check it's a clean copy.

Cheers,
Fred

Free Windows Admin Tool Kit Click here and download it now
August 25th, 2015 8:39am

So, I've gone over it and run again, here is my code;

 param (
    [string]$server,
    [switch]$Command
 )


function Start-Command
{
	foreach ($a in $args)
	{
		$a
	}
}

if ($Command)
{
 Start-Command $args
 }
 
 Write-Host $args[0]
 Write-Host $args[1]
 Write-Host $args[2]
 Write-Host $args[3]

Read-Host "Press ENTER to start the script..."

And here is the output from it;

PS L:\> .\Script.ps1 -Command Test1 Test 2 Test 3
Test2
Test3
Test2
Test3

Press ENTER to start the script...:

I'm only doing a write-host to verify arguments are being passed correctly in this instance. (Write-Host will be removed once I've clarified).

August 25th, 2015 10:01am

Hi Jonathan,

looks like it's working well. "Test1" is being bound to $Server though (PowerShell will first bind all defined parameters that it can and only throw the rest into $args).

Cheers,
Fred

Free Windows Admin Tool Kit Click here and download it now
August 25th, 2015 10:05am

Thanks Frank, is there any way around that?... (I have the requirement for multiple parameters), I'd have thought $server would only be bound if I specified -server xxxx ?
August 25th, 2015 10:15am

Hi Jonathan,

sorry, but there is no way around this. You either need to teach the users to specify the server each time (even if the function wouldn't use it), or you build a proper module for your set of functions, and give your users direct access to the individual functions on a powershell console (recommended).

Cheers,
Fred

Free Windows Admin Tool Kit Click here and download it now
August 25th, 2015 11:02am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics