简体   繁体   中英

Pass multiple parameter to Powershell function from command line?

I am editing a script function to add a function called CloneGitPackage . This is the function I wrote:

function CloneGitPackage {
    $PACKAGE_URL = $args[1]
    $PACKAGE_NAME = $args[2]

    write-verbose "Downloading package: $PACKAGE_URL $PACKAGE_NAME"
    git clone --depth 1 $PACKAGE_URL $PACKAGE_NAME 2>$null
    write-verbose ""
}

But the original script has some more other functions:

[CmdletBinding()]
param(
    [Parameter(Mandatory = $false, Position = 0)]
    [string]$command,
    [Parameter(Mandatory = $false)]
    [switch] $coverage
)

...

try{
    switch ($command){
        "bootstrap" { Bootstrap }
        "install" { Install }
        "run_tests" { RunTests }
        "clone_git_package" { CloneGitPackage }
    }
}catch {
    throw $_
}

I am calling the script like this:

 .\script.ps1 "clone_git_package" "https://github.com" "Folder" -verbose

But it is complaining:

script.ps1 : A positional parameter cannot be found that accepts argument 'https://github.com'.
At line:1 char:19
+ ... .\script.ps1 "clone_git_package" "https://github.com/ ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [script.ps1], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,script.ps1

Command executed with exception: A positional parameter cannot be found that accepts argument 'https://github.com'.

I supposed the problem is that stranger header the original script already have:

[CmdletBinding()]
param(
    [Parameter(Mandatory = $false, Position = 0)]
    [string]$command,
    [Parameter(Mandatory = $false)]
    [switch] $coverage
)

These are some valid calls to the script accordingly to its header:

  1. .\\script.ps1 "bootstrap" -verbose
  2. .\\script.ps1 "install" -verbose
  3. .\\script.ps1 "run_tests" -coverage -verbose

I need to be able to call the script passing the new function name, on this case clone_git_package and give its arguments, a string git URL and another string directory name .

How can I fix this, without breaking backward compatibility with the other stuff on the script which already uses this stuff?

In order to be able to pass parameters to your function you will need to update the script's parameters to accommodate your additional parameters. So let's start with your parameters on your function. Right now you reference:

$PACKAGE_URL = $args[1]
$PACKAGE_NAME = $args[2]

This is not particularly good scripting. A better option would be to create actual parameters for your function:

function CloneGitPackage {
Param(
    $PACKAGE_URL,
    $PACKAGE_NAME
)

This essentially does the same thing you were doing before, since parameters are positional based on the order they are listed. We could get fancier, but really there's no need. So if we apply that same logic to the script's parameters it comes out like (keeping the switch at the bottom so that it's the last expected parameter):

param(
    [Parameter(Mandatory = $false, Position = 0)]
    [string]$command,
    $PACKAGE_URL,
    $PACKAGE_NAME,
    [Parameter(Mandatory = $false)]
    [switch] $coverage
)

Now the script knows what to do with your parameters when you give it the additional info! After that you just need to update how the script calls your function to include those parameters when it calls it, and you should be all set.

switch ($command){
    "bootstrap" { Bootstrap }
    "install" { Install }
    "run_tests" { RunTests }
    "clone_git_package" { CloneGitPackage $PACKAGE_URL $PACKAGE_NAME }
}

I did this, and it seemed to be working fine:

[CmdletBinding()]
param(
    [Parameter(Mandatory = $false, Position = 0)]
    [string]$command,
    [Parameter(Mandatory = $false, Position = 1)]
    [string]$package_url,
    [Parameter(Mandatory = $false, Position = 2)]
    [string]$package_name,
    [Parameter(Mandatory = $false)]
    [switch] $coverage
)

...

function CloneGitPackage {
    $PACKAGE_PATH = "$TARGET_FOLDER\$package_name"

    write-verbose "Downloading package: $package_url $PACKAGE_PATH"
    git clone --depth 1 $package_url $PACKAGE_PATH 2>$null
    write-verbose ""
}

try{
    switch ($command){
        "bootstrap" { Bootstrap }
        "install" { Install }
        "run_tests" { RunTests }
        "clone_git_package" { CloneGitPackage }
    }
}catch {
    throw $_
}

When calling it as:

  1. .\\script.ps1 "bootstrap" -verbose
  2. .\\script.ps1 "install" -verbose
  3. .\\script.ps1 "run_tests" -coverage -verbose
  4. .\\script.ps1 "clone_git_package" "https://github.com" "Folder" -verbose

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM