Call PowerShell Script from Another Script

Call PowerShell Script from another Script

1. Introduction to the Problem Statement

PowerShell, a powerful scripting language and command-line shell, is widely used for automation in Windows environments. A common requirement in PowerShell scripting is to call one script from another, enabling modular programming and reusability of code.

Suppose we have two scripts:

  • ChildScript.ps1: This script performs a task and returns a value. For instance, it could check disk space and return true if there’s enough space or false otherwise.
  • MainScript.ps1: This script calls ChildScript.ps1 and takes action based on the returned value from ChildScript.ps1.

2. ChildScript.ps1

Explanation: ChildScript.ps1 defines a function Check-DiskSpace that checks if the free space on the C drive is more than 10GB and returns $true or $false accordingly.

Let’s write different main script based on the different methods which we are going to use.

3. Using the & Operator (Call Operator)

The most straightforward method is to use the & operator, also known as the call operator, in PowerShell.

Explanation:

  • Setting Path to the Child Script: The script sets $childScriptPath with the relative path to ChildScript.ps1.
  • Calling the Child Script: It uses the call operator (&) to execute ChildScript.ps1 and captures its output (expected to be a boolean value) in the variable $isEnoughSpace.
  • Decision Based on Output: An if-else statement checks the value of $isEnoughSpace. If it’s $true, the script prints “Sufficient disk space available.” Otherwise, it prints “Warning: Low disk space.”

This script demonstrates how to call a separate PowerShell script and use its output for conditional logic within the calling script.

Performance:

This method is efficient and has minimal performance overhead. It is a direct call and executes the script in the current PowerShell session.

4. Using Dot Sourcing

Dot sourcing is a technique in PowerShell to run a script in the current scope, allowing the main script to access variables and functions defined in the child script.

 

This script, MainScript.ps1, demonstrates how to use dot sourcing in PowerShell to call a function from another script (ChildScript.ps1) and use its output for decision-making:

  1. Setting the Path to the Child Script: The variable $childScriptPath is assigned the relative path to ChildScript.ps1.
  2. Dot Sourcing the Child Script: The dot sourcing operator (.) is used to execute ChildScript.ps1. This makes all functions and variables from ChildScript.ps1 available in the scope of MainScript.ps1.
  3. Calling the Function Directly: The function Check-DiskSpace from ChildScript.ps1 is called directly, and its output (expected to be a boolean indicating disk space status) is stored in $isEnoughSpace.
  4. Making a Decision Based on the Output: The script uses an if-else statement to check $isEnoughSpace. If it’s $true, it indicates sufficient disk space and prints “Sufficient disk space available.” Otherwise, it prints “Warning: Low disk space.”

This approach is useful when we want to access functions or variables from another script directly within the current script’s scope.

Performance:

Dot sourcing is efficient and particularly useful when the main script needs to access resources defined in the child script. It has similar performance characteristics to the call operator.

5. Using Invoke-Expression

Another method is to use the Invoke-Expression cmdlet, which evaluates a string as PowerShell code and executes it.

Explanation: Invoke-Expression evaluates the script at the specified path as a PowerShell command. The output of the child script is captured into $isEnoughSpace, which is then used to make a decision.

Performance:

Invoke-Expression has a slight overhead of parsing the string expression, but this is generally negligible. It’s as efficient as the call operator for most practical purposes.

6. Using Start Process

For running scripts completely independently, Start-Process can be used. For Start-Process, it’s important to note that it starts a separate process, which makes capturing output directly more complex. To capture output, we would typically redirect the output to a file and then read from that file.

Explanation: Start-Process is used to run ChildScript.ps1 in a separate PowerShell process. The output is redirected to a temporary file (output.txt). The main script then reads the content of this file to capture the output of the child script. After processing the output, the temporary file is deleted for cleanup.

This method is useful for complete isolation of the child script, running it in a separate process. This can be beneficial for resource-intensive scripts or scripts that need to run in a different context.

Performance:

Running a script as a separate process introduces additional overhead compared to other methods. It is slower due to the creation of a new process but provides isolation and is useful when such separation is necessary.

7. Calling PowerShell Script with Parameters from Another Script

In advanced PowerShell scripting, it’s common to not only call one script from another but also to pass parameters to the called script. This approach enhances script flexibility and allows for dynamic execution based on varying inputs.

Scenario: Continuing with our previous example, let’s say ChildScript.ps1 now accepts a parameter to specify the drive for which to check disk space. MainScript.ps1 needs to call ChildScript.ps1 with a specific drive letter as a parameter and then act based on the returned value.

Goal: We will explore methods to call ChildScript.ps1 with a parameter from MainScript.ps1, capture the output, and use it in MainScript.ps1 for further actions.

Explanation: ChildScript.ps1 now accepts a parameter $DriveLetter. The Check-DiskSpace function uses this parameter to check the disk space of the specified drive.

Let’s use different methods to call powerShell script with parameters from another Script:

7.1 Using the Call Operator (&) with Parameters:

7.2 Using Dot Sourcing with Parameters:

7.3 Using Invoke-Expression with Parameters:

7.4 Using Start-Process with Parameters:

8. Passing Complex Objects as Parameter

Passing complex objects as parameters directly between PowerShell scripts is inherently challenging due to the nature of how scripts and processes handle data. However, there are a few methods and workarounds to consider:

8.1. Dot Sourcing

Dot sourcing is a method that can be used when scripts are run in the same context. It doesn’t start a new process, but rather runs the script in the current PowerShell session.

  • Usage: If we dot-source a child script, it runs in the context of the calling script. This allows shared access to complex objects defined in one script to another.
  • Limitation: This only works when scripts are executed in the same PowerShell session. It’s not suitable for scenarios requiring scripts to run in isolated environments.

8.2. Session-Based Variables

In PowerShell, we can create session-based variables that can store complex objects. These variables are accessible in scripts that run in the same session.

  • Usage: Define a session variable in one script and access it in another script.
  • Limitation: Similar to dot sourcing, this method works only within the same PowerShell session.

8.3. Serialization and Deserialization

For passing data between scripts running in different contexts (e.g., different processes), serialization is the most viable method. We serialize an object to a string format like JSON or XML, pass the string to the other script, and then deserialize it back to an object.

  • Usage: Use ConvertTo-Json and ConvertFrom-Json or Export-Clixml and Import-Clixml for converting objects to and from strings.
  • Limitation: Serialization may not perfectly preserve some types of objects, and there is an overhead in serializing and deserializing objects.

8.4. Temporary File Storage

Storing objects in temporary files is another way to share complex data between scripts. This is a more manual approach but can be effective for certain types of objects.

  • Usage: Store the object in a temporary file in one script and read it from the other script.
  • Limitation: Requires managing temporary files and ensuring they are securely created and properly deleted after use.

8.5. Inter-Process Communication (IPC)

For advanced scenarios, IPC mechanisms like named pipes or memory-mapped files can be used to pass complex objects between scripts.

  • Usage: Establish an IPC channel to transmit data between processes.
  • Limitation: This approach is complex and may be overkill for simpler scripting needs.

9. Conclusion

There are multiple ways to call a PowerShell script from another script, each with different use cases and performance implications:

  • Using the Call Operator (&): Best for general-purpose script calling. It’s simple, efficient, and executes the script in the current session.
  • Using Invoke-Expression: Offers flexibility but should be used with caution to avoid security risks.
  • Dot Sourcing (.): Ideal for scenarios where the main script needs to access resources from the child script.
  • Using Start-Process: Suitable for isolating the child script execution from the main script, albeit with some performance overhead.

In choosing the right method, consider the specific requirements of our script, such as whether we need to share variables and functions between scripts, or if we require script execution isolation. For most cases, the call operator or dot sourcing will suffice, offering a balance between efficiency and functionality.

Was this post helpful?

Leave a Reply

Your email address will not be published. Required fields are marked *