Author Posts

July 12, 2017 at 3:16 pm

I need to start a PowerShell script by passing strings that can (or cannot) contain blanks, as in the following samples:

start powershell.exe -noexit C:\my_dir\my_script.ps1 "Mary" "John Doe" "Janet F. Doe" "John Q. Public Sr."
start powershell.exe -noexit C:\my_dir\my_script.ps1 "Dr. Ordinary Joe Jr." "Steve" "Janet F. Doe" "Jane Smith"

My script looks like the following:

param($user1, $user2, $user3, $user4)
$user1
$user2
$user3
$user4
...
...

What is the right way to pass parameters so that each parameter is passed in the right way including blanks (if any)?
Regards
marius

July 12, 2017 at 5:44 pm

Param(
 [string[]]$users
)

MyScript -Users @("one","","three")

you would then enumerate $users by using a ForEach construct. This is a much better pattern than what you're doing, as it allows for 0-infinite number of inputs. This is also how virtually every native command accepts collections of input.

July 12, 2017 at 7:57 pm

Many thanks for your answer.
To be honest my real problem is a little bit more complex, as parameters can be different from each other, let's say:

start powershell.exe -noexit C:\my_dir\my_script.ps1 "c:\data\US companies\xyz\report" "XYZ" "217, South River St." "New York, NY" "USA" "2134" 
start powershell.exe -noexit C:\my_dir\my_script.ps1 "e:\data\EU companies\Rossi Trasporti Internazionali\report" "Rossi Trasporti Internazionali S.p.A." "Via Londra 19" "Verona" "Italy" "345"
param($folder, $company, $address, $city, $country, $employees)
$folder
$company
$address
$city
$country
$employees

Do yout think that the suggested solution should work anyway?
Regards
Marius
PS: companies are fictional

July 12, 2017 at 9:43 pm

I'd take a hash table. They're better at variable data.

MyScript.ps1 -data @{'Name'='Joe';'Country'='whatever'}

param(
$data
)

It's easy enough to enumerate through $data, then. If each run of the script represents a single user, then $data will contain keys for $data.Name, $data.Country, and whatever else exists. You can use $data.KeyExists('Name') to determine if a key exists or not.

If $data contains more than one user's worth of info:

MyScript.ps1 -data @(@{'Name'='Joe';'Country'='whatever'},@{'Name'='Doug';'Department'='IT'})

You'd then ForEach through each element in $data

ForEach ($thing in $data) {}

And $thing would be a hash table, with keys, the KeyExists() method, etc.

This way, each element has a name – you're not just relying on positional input, which is hard to maintain and read. Each element can have variable keys, so not every element needs to be defined.

Part of your original problem, incidentally, is this whole positional thing. You're coding this like it's C#. Even if you had:

Param(
$name,
$city,
$state,
$department
)

You don't have "blanks" per se. You're only thinking that because you're using positional input rather than named input.

MyScript.ps1 -name Don -city Vegas -department "Info tech"

That approach – which is how PowerShell's really meant to work – means I can safely omit State. I'm explicitly naming each piece of input, so PowerShell knows what goes where. So you could go that approach as well, if you like.