Passing parameters containing blanks

Tagged: 

This topic contains 3 replies, has 2 voices, and was last updated by Profile photo of Don Jones Don Jones 2 weeks, 1 day ago.

  • Author
    Posts
  • #74787
    Profile photo of marius
    marius
    Participant

    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

  • #74806
    Profile photo of Don Jones
    Don Jones
    Keymaster
    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.

  • #74823
    Profile photo of marius
    marius
    Participant

    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

  • #74824
    Profile photo of Don Jones
    Don Jones
    Keymaster

    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.

You must be logged in to reply to this topic.