13

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"

2
  • I forgot to add, I am running it with start-process, because I want to run it in a separate window. Is there a better way, that passes variables, that starts the script in a window separate from the one already running. Commented Nov 8, 2014 at 5:44
  • 1
    Possible duplicate of Load variables from another powershell script Commented Feb 4, 2016 at 20:12

3 Answers 3

19

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.

Sign up to request clarification or add additional context in comments.

Comments

4

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

Comments

1
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.