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