How Can You Use PowerShell to Run Another PowerShell Script?
In the world of automation and scripting, PowerShell stands out as a powerful tool that empowers IT professionals and developers alike. One common task that often arises is the need to run one PowerShell script from within another. Whether you’re orchestrating complex workflows, modularizing your code for better maintenance, or simply streamlining repetitive tasks, understanding how to execute a secondary script seamlessly is essential. This capability not only enhances script organization but also boosts efficiency and scalability in your automation projects.
Running another PowerShell script from a primary script might seem straightforward at first glance, but there are nuances and best practices that can make a significant difference in how your scripts interact and perform. From handling parameters and execution policies to managing output and error streams, the process involves more than just calling a file. Grasping these concepts can help you avoid common pitfalls and ensure your scripts run smoothly in diverse environments.
As you delve deeper, you’ll discover various methods and techniques to invoke secondary scripts, each with its own advantages and ideal use cases. Whether you’re a beginner looking to expand your scripting toolkit or a seasoned professional aiming to refine your automation strategies, mastering how to run another PowerShell script will open new doors to more dynamic and modular script development.
Using the Call Operator to Run Scripts
The call operator `&` is a straightforward way to run another PowerShell script from within a script or the command line. It allows you to execute a script as if you typed its path directly in the console. This method is particularly useful when the script path contains spaces or special characters, as enclosing the path in quotes ensures correct parsing.
When using the call operator, you can pass arguments to the target script by listing them after the script path. The target script will receive these arguments as its `$args` array or defined parameters.
Example usage:
“`powershell
& “C:\Scripts\MyScript.ps1” -Param1 “Value1” -Param2 “Value2”
“`
Key points about the call operator:
- It executes the script in the current session, so any variables or functions defined in the called script become available after execution.
- It respects the PowerShell execution policy.
- It is ideal for running scripts with parameters and capturing output.
Invoking Scripts with the `Start-Process` Cmdlet
`Start-Process` is a versatile cmdlet that launches a new process, which can be a PowerShell script running in a separate session. This approach is beneficial when you want to run a script asynchronously or isolate its execution environment.
Using `Start-Process` to run a PowerShell script involves calling `powershell.exe` with appropriate arguments:
“`powershell
Start-Process powershell.exe -ArgumentList ‘-NoProfile’, ‘-File’, ‘C:\Scripts\MyScript.ps1’, ‘-Param1’, ‘Value1’
“`
Advantages of `Start-Process`:
- Runs the script in a new PowerShell process, ensuring isolation.
- Can run scripts asynchronously without blocking the parent script.
- Allows you to specify window style, working directory, and credentials.
Considerations:
- Output from the script runs in the new process and does not directly return to the calling script.
- Requires handling for output capture if needed (e.g., redirecting output to a file).
Dot Sourcing Scripts to Import Functions and Variables
Dot sourcing is a technique to run another script in the current scope, making its functions, variables, and aliases available in the calling script or session. This differs from the call operator, which runs the script in the current session but does not import definitions unless explicitly declared.
To dot source a script, prefix the script path with a dot and a space:
“`powershell
. “C:\Scripts\MyFunctions.ps1”
“`
Benefits of dot sourcing:
- Imports all functions and variables from the sourced script into the current scope.
- Useful for modularizing code and sharing functions across scripts.
- Avoids the overhead of starting a new process.
Important notes:
- Dot sourcing affects the current scope and can overwrite variables or functions.
- Use carefully to prevent unintended side effects.
Comparison of Methods to Run PowerShell Scripts
Method | Execution Context | Parameter Passing | Output Handling | Use Case |
---|---|---|---|---|
Call Operator (&) | Current session | Supports named and positional parameters | Output returned to caller | Run scripts with parameters and capture output |
Start-Process | New PowerShell process | Pass as argument list | Does not return output directly; requires redirection | Run scripts asynchronously or isolated |
Dot Sourcing (.) | Current scope | Parameters not directly supported; variables/functions imported | Output runs inline | Import functions/variables from a script |
Handling Script Execution Policy and Permissions
When running one PowerShell script from another, it is essential to consider the execution policy and permissions. The execution policy restricts script execution to protect against running malicious code.
To check the current policy, use:
“`powershell
Get-ExecutionPolicy
“`
If the policy is restrictive (e.g., `Restricted` or `AllSigned`), scripts may not run as expected. To bypass this for a single run, you can add the `-ExecutionPolicy Bypass` parameter with `powershell.exe` when using `Start-Process`:
“`powershell
Start-Process powershell.exe -ArgumentList ‘-NoProfile’, ‘-ExecutionPolicy’, ‘Bypass’, ‘-File’, ‘C:\Scripts\MyScript.ps1’
“`
Alternatively, you can temporarily set the execution policy in the current session:
“`powershell
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
“`
Ensure you have the necessary permissions to modify execution policies, and always follow organizational security guidelines.
Passing Arguments Between Scripts
Passing arguments to another PowerShell script is a common requirement. Both the call operator and `Start-Process` support passing parameters, but the methods differ.
For the call operator:
- Pass parameters by name or position directly after the script path.
- Example:
“`powershell
& “C:\Scripts\MyScript.ps1” -UserName “admin” -Verbose
“`
- Inside the called script, define parameters using the `param` block:
“`powershell
param (
[string]$UserName,
[switch]$Verbose
)
“`
For `Start-Process`:
- Pass arguments as strings in an array to the `-ArgumentList` parameter.
- Example:
Executing One PowerShell Script from Another
Running a PowerShell script from within another script is a common task that can simplify automation workflows and modularize code. Several methods are available depending on the context and requirements such as parameter passing, scope control, and output handling.
Here are the primary techniques to execute another PowerShell script:
- Call the script directly by path
- Use the
.&
(call operator) - Invoke with
Invoke-Command
- Start a new PowerShell process
Method | Description | Example | Use Case |
---|---|---|---|
Direct Invocation | Run the script by specifying its path. Variables inside run in their own scope. | C:\Scripts\AnotherScript.ps1 |
Simple execution without needing to pass parameters or capture output. |
Call Operator . <script> |
Runs the script in the current scope, allowing sharing of variables and functions. | . C:\Scripts\AnotherScript.ps1 |
When you want to modify or access variables/functions from the called script in the caller. |
Invoke-Command |
Executes the script block or script on local or remote computers. | Invoke-Command -FilePath C:\Scripts\AnotherScript.ps1 |
Remote execution or advanced session control. |
Start-Process |
Launches a new PowerShell process running the script independently. | Start-Process powershell -ArgumentList '-File C:\Scripts\AnotherScript.ps1' |
When parallel execution or isolation is required. |
Using the Call Operator for Script Execution
The call operator `.&` is the most common and flexible method to run another PowerShell script from within a script or interactive session. It ensures that the called script executes in the current scope, which means:
- Variables defined in the caller are accessible to the called script.
- Changes to variables or functions in the called script affect the caller’s environment.
- Functions declared in the called script become available after execution.
Usage syntax:
. <PathToScript> [<arguments>]
Example with parameters:
. C:\Scripts\AnotherScript.ps1 -Param1 "Value1" -Param2 42
Key points to remember when using the call operator:
- The script path can be relative or absolute.
- If the path contains spaces, enclose it in quotes:
. "C:\My Scripts\AnotherScript.ps1"
. - Parameters passed are forwarded directly to the called script’s param block.
- Errors in the called script propagate to the caller unless handled explicitly.
Passing Parameters Between Scripts
To effectively pass data between scripts, the called script must define parameters using a param block. For example:
param (
[string]$Param1,
[int]$Param2
)
Write-Host "Param1 is $Param1"
Write-Host "Param2 is $Param2"
The caller script invokes it with:
. C:\Scripts\AnotherScript.ps1 -Param1 "Test" -Param2 10
This method provides clear and maintainable parameter passing, and is preferred over using global variables or environment variables.
Capturing Output from a Called Script
When a script produces output (objects, strings, etc.), the caller can capture this output for further processing. This is done by assigning the execution result to a variable:
$result = . C:\Scripts\AnotherScript.ps1 -Param1 "Example"
The variable $result
contains all output objects generated by the called script, which can be enumerated, filtered, or piped as needed.
- Output includes anything written to the standard output stream.
- Write-Host output is generally not captured, as it writes directly to the console.
- To capture verbose, warning, or error streams, additional redirection or parameter handling may be necessary.
Executing Scripts in a New PowerShell Process
To run a script independently and isolated from the current session, use `Start-Process` or `powershell.exe` directly:
Start-Process powershell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\AnotherScript.ps1"'
Parameter | Purpose |
---|