How do I pass arguments or variables from one powershell script to another?

39,787

Solution 1

You don't need Start-Process to run one PowerShell script from another PowerShell script. Simply call the second script with whatever parameters you want:

# script1.ps1

$loc = Read-Host 'Enter location'

C:\path\to\script2.ps1 $loc 'other parameter'

In the second script the argument list can be accessed for instance via the $args array:

# script2.ps1

Write-Host $args[0]
Write-Host $args[1]

You could also define named parameters like this:

# script2.ps1

Param($Location, $Foo)

Write-Host $Location
Write-Host $Foo

or (more complete) like this:

# script2.ps1

[CmdletBinding()]
Param(
  [Parameter(Mandatory=$true)]
  [string]$Location,
  [Parameter(Mandatory=$false)]
  [string]$Foo
)

Write-Host $Location
Write-Host $Foo

Defining named parameters allows you to pass arguments without having to worry about their order:

C:\path\to\script2.ps1 -Foo 'other parameter' -Location $loc

or to have parameters automatically validated without having to implement the checks in the function body:

# script2.ps1

Param(
  [ValidateSet('a', 'b', 'c')]
  [string]$Location,
  [ValidatePattern('^[a-z]+$')]
  [string]$Foo
)

Write-Host $Location
Write-Host $Foo

If more arguments are passed than named parameters were defined those additional arguments are stored in the $args array:

PS C:\> cat test.ps1
Param($Foo)

Write-Host $Foo
Write-Host $args[0]
PS C:\> .\test.ps1 'foo' 'bar'
foo
bar

For more information see Get-Help about_Functions_Advanced_Parameters.

Solution 2

The variables declared in Variables.ps1 are at "Script Scope". That is you can not see them outside of the scope of the script that declares them. One way to bring the variables in Variables.ps1 to the scope of main.ps1 is to "dot source" Variables.ps1. This, in effect, runs Variables.ps1 at the scope of main.ps1. To do this, just stick a period and space before your invocation of the script:

. .\Variables.ps1
$var1
$var2

Solution 3

param ($loc)

At the top of a .ps1 script that defines a parameter for the script, so call it as

  PathToMyScript\MyScript.ps1 -loc ValueOfLoc

All the attributes you can apply, including using [CmdletBinding()] on the param statement in a function work on a script as well.

Share:
39,787
user3377627
Author by

user3377627

Updated on March 31, 2020

Comments

  • user3377627
    user3377627 about 4 years

    In cmd I could pass arguments from one bat to another by listing them after the to-be-run bat file was stated. Then the to-be-run bat received them as %1, %2, %3, etc. Can this be done in Powershell?

    I have one ps1 script,script1, that prompts the user for a location. That script has been taken care of. That location is stored as a variable; $loc. In the first script, there is a point that the user can choose an option that will run another ps1 script, script2, that has itself more options. I want to pass $loc to the script2 from script1.

    In script1 I have tried the following:

    param ($loc)
    start-process "\script2.ps1" -ArgumentList $loc
    start-process "\script2.ps1" -$loc
    start-process "\script2.ps1"
    

    Then is script 2

    args[0]
    $loc
    

    I know I'm probably just not understanding passing arguments. Thing is that another options calls a bat script. That one I use -ArgumentList $loc and it passes that fine. I pick that argument up in the bat script using "Set loc = %1"