I want call execution for a myScript1.ps1 script inside a second myScript2.ps1 script inside Powershell ISE.
The following code inside MyScript2.ps1, works fine from
I am calling myScript1.ps1 from myScript2.ps1 .
Assuming both of the script are at the same location, first get the location of the script by using this command :
$PSScriptRoot
And, then, append the script name you want to call like this :
& "$PSScriptRoot\myScript1.ps1"
This should work.
I submit my example for consideration. This is how I call some code from a controller script in the tools I make. The scripts that do the work also need to accept parameters as well, so this example shows how to pass them. It does assume the script being called is in the same directory as the controller script (script making the call).
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string[]]
$Computername,
[Parameter(Mandatory = $true)]
[DateTime]
$StartTime,
[Parameter(Mandatory = $true)]
[DateTime]
$EndTime
)
$ZAEventLogDataSplat = @{
"Computername" = $Computername
"StartTime" = $StartTime
"EndTime" = $EndTime
}
& "$PSScriptRoot\Get-ZAEventLogData.ps1" @ZAEventLogDataSplat
The above is a controller script that accepts 3 parameters. These are defined in the param block. The controller script then calls the script named Get-ZAEventLogData.ps1. For the sake of example, this script also accepts the same 3 parameters. When the controller script calls to the script that does the work, it needs to call it and pass the parameters. The above shows how I do it by splatting.
I had a similar problem and solved it this way.
My working directory is a general script folder and serveral particular script folder in same root, i need to call particular script folder (which call general script with the parameter of the particular problem). So working directory is like this
\Nico\Scripts\Script1.ps1
\Script2.ps1
\Problem1\Solution1.ps1
\ParameterForSolution1.config
\Problem2\Solution2.ps1
\ParameterForSolution2.config
Solutions1 and Solutions2 call the PS1 in Scripts folder loading the parameter stored in ParameterForSolution. So in powershell ISE i run this command
.\Nico\Problem1\Solution1.PS1
And the code inside Solution1.PS1 is:
# This is the path where my script is running
$path = split-path -parent $MyInvocation.MyCommand.Definition
# Change to root dir
cd "$path\..\.."
$script = ".\Script\Script1.PS1"
$parametro = "Problem1\ParameterForSolution1.config"
# Another set of parameter Script1.PS1 can receive for debuggin porpuose
$parametro +=' -verbose'
Invoke-Expression "$script $parametro"
How do you run PowerShell built-in scripts inside of your scripts?
How do you use built-in scripts like
Get-Location
pwd
ls
dir
split-path
::etc...
Those are ran by your computer, automatically checking the path of the script.
Similarly, I can run my custom scripts by just putting the name of the script in the script-block
::sid.ps1 is a PS script I made to find the SID of any user
::it takes one argument, that argument would be the username
echo $(sid.ps1 jowers)
(returns something like)> S-X-X-XXXXXXXX-XXXXXXXXXX-XXX-XXXX
$(sid.ps1 jowers).Replace("S","X")
(returns same as above but with X instead of S)
Go on to the powershell command line and type
> $profile
This will return the path to a file that our PowerShell command line will execute every time you open the app.
It will look like this
C:\Users\jowers\OneDrive\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1
Go to Documents and see if you already have a WindowsPowerShell directory. I didn't, so
> cd \Users\jowers\Documents
> mkdir WindowsPowerShell
> cd WindowsPowerShell
> type file > Microsoft.PowerShellISE_profile.ps1
We've now created the script that will launch every time we open the PowerShell App.
The reason we did that was so that we could add our own folder that holds all of our custom scripts. Let's create that folder and I'll name it "Bin" after the directories that Mac/Linux hold its scripts in.
> mkdir \Users\jowers\Bin
Now we want that directory to be added to our $env:path
variable every time we open the app so go back to the WindowsPowerShell
Directory and
> start Microsoft.PowerShellISE_profile.ps1
Then add this
$env:path += ";\Users\jowers\Bin"
Now the shell will automatically find your commands, as long as you save your scripts in that "Bin" directory.
Relaunch the powershell and it should be one of the first scripts that execute.
Run this on the command line after reloading to see your new directory in your path variable:
> $env:Path
Now we can call our scripts from the command line or from within another script as simply as this:
$(customScript.ps1 arg1 arg2 ...)
As you see we must call them with the .ps1
extension until we make aliases for them. If we want to get fancy.
In order to find the location of a script, use Split-Path $MyInvocation.MyCommand.Path
(make sure you use this in the script context).
The reason you should use that and not anything else can be illustrated with this example script.
## ScriptTest.ps1
Write-Host "InvocationName:" $MyInvocation.InvocationName
Write-Host "Path:" $MyInvocation.MyCommand.Path
Here are some results.
PS C:\Users\JasonAr> .\ScriptTest.ps1 InvocationName: .\ScriptTest.ps1 Path: C:\Users\JasonAr\ScriptTest.ps1 PS C:\Users\JasonAr> . .\ScriptTest.ps1 InvocationName: . Path: C:\Users\JasonAr\ScriptTest.ps1 PS C:\Users\JasonAr> & ".\ScriptTest.ps1" InvocationName: & Path: C:\Users\JasonAr\ScriptTest.ps1
In PowerShell 3.0 and later you can use the automatic variable $PSScriptRoot
:
## ScriptTest.ps1
Write-Host "Script:" $PSCommandPath
Write-Host "Path:" $PSScriptRoot
PS C:\Users\jarcher> .\ScriptTest.ps1 Script: C:\Users\jarcher\ScriptTest.ps1 Path: C:\Users\jarcher
You may have found the answer for it already, but here is what I do.
I usually place this line at the beginning of my installation scripts:
if(!$PSScriptRoot){ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent } #In case if $PSScriptRoot is empty (version of powershell V.2).
Then I can use $PSScriptRoot variable as a location of the current script(path), like in the example bellow:
if(!$PSScriptRoot){ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent } #In case if $PSScriptRoot is empty (version of powershell V.2).
Try {
If (Test-Path 'C:\Program Files (x86)') {
$ChromeInstallArgs= "/i", "$PSScriptRoot\googlechromestandaloneenterprise64_v.57.0.2987.110.msi", "/q", "/norestart", "/L*v `"C:\Windows\Logs\Google_Chrome_57.0.2987.110_Install_x64.log`""
Start-Process -FilePath msiexec -ArgumentList $ChromeInstallArgs -Wait -ErrorAction Stop
$Result= [System.Environment]::ExitCode
} Else {
$ChromeInstallArgs= "/i", "$PSScriptRoot\googlechromestandaloneenterprise_v.57.0.2987.110.msi", "/q", "/norestart", "/L*v `"C:\Windows\Logs\Google_Chrome_57.0.2987.110_Install_x86.log`""
Start-Process -FilePath msiexec -ArgumentList $ChromeInstallArgs -Wait -ErrorAction Stop
$Result= [System.Environment]::ExitCode
}
} ### End Try block
Catch {
$Result = [System.Environment]::Exitcode
[System.Environment]::Exit($Result)
}
[System.Environment]::Exit($Result)
In your case, you can replace
Start-process... line with
Invoke-Expression $PSScriptRoot\ScriptName.ps1
You can read more about $MYINVOCATION and $PSScriptRoot automatic variables on the Microsoft site: https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_automatic_variables