Recently I have been working in Powershell to harness both the automation and development aspects of the platform. I have used Powershell in the past in a limited capacity for automation tasks like build and deployment. I was in unfamiliar territory with my current need to harness its development capabilities. Fortunately a coworker of mine, Doug Finke, is a Powershell Most Valuable Professional (MVP). He was able to provide insight into some of the more sophisticated aspects of Powershell.
My experience has been challenging but rewarding with a few pitfalls along the way. The first obstacle I encountered centered around the use of the Start-Process cmdlet. It can be fairly simple and straightforward to use from the command line but proved to be a bit unwieldy for me to use in the context of a Powershell script.
I found starting an instance of Powershell to execute a script from within another Powershell script fairly difficult. The information I found online was a mixture of fact and fallacy. Weeding through it to find a solution was time-consuming and painful. Hopefully my experience will inform you and expedite your journey. The two pain points revolved around invoking the Powershell executable to run a script from within another script and secondly passing arguments to the script. After a bit of research I figured out the first piece of the puzzle.
Invoking Powershell to execute a script requires the ampersand (&) character. This part was straightforward to implement without too much effort. With a little bit of research and effort I was able to execute a simple script.
##SimpleInvokeScript.ps1 Write-Host "Hello World!"; Read-Host "Press <Enter> key to exit"
##Start the process from the command line or another script Start-Process powershell.exe '& C:\Scripts\SimpleInvokeScript.ps1'
After conquering the first obstacle I needed to expand my solution to pass arguments to the script. This proved to be much more difficult. Previously I had found the -ArgumentList command line switch documentation. I knew this was necessary to provide the input arguments. Unfortunately there was not a good example in the help documents to base my script on. After trying many different variations I was finally able to achieve my goal.
##ParameterizedInvokeScript.ps1 param([string]$argOne, [string]$argTwo, [int]$argThree) Write-Host "ArgumentOne: $argOne, ArgumentTwo: $argTwo, ArgumentThree: $argThree" Read-Host "Press <Enter> key to exit"
##Start the process from the command line or another script passing arguments Start-Process powershell.exe -ArgumentList '& C:\Scripts\ParameterizedInvokeScript.ps1', One, Two, 3
There are nuances associated with passing command-line arguments. In the example above the items in the argument list are comma-separated. The punctuation is required for the command to execute successfully. The position of arguments is also very important. Additional Powershell command line switches need to be placed before the -ArgumentList parameters. Notice the -NoExit switch also needs to be single quoted and comma-separated here.
Start-Process powershell.exe -ArgumentList '-NoExit ', '& C:\Scripts\ParameterizedInvokeScript.ps1', One, Two, 3
Additional Powershell switches can be included preceding the invocation operator and script path. Notice in this example that the first string argument contains spaces and requires surrounding a single quoted (‘) string with double quotes (“) to allow for the white space.
Start-Process powershell.exe -ArgumentList '-NoExit & C:\Scripts\ParameterizedInvokeScript.ps1', "'One With Spaces'", Two, 3
The command line can also be built up dynamically at runtime. Multiple variables can be used to construct the arguments.
##InitiateParameterizedInvokeScript.ps1 ##Use variable(s) to dynamically build up the command line content $scriptPath = 'C:\Scripts\ParameterizedInvokeScript.ps1' $commandLine = "-NoExit & $scriptPath 'One With Spaces' Two 3" ##Start the process building the command line arguments dynamically Start-Process powershell.exe -ArgumentList $commandLine
Notice in the above example when building up the command line dynamically with string variables the commas are omitted. White space within the string separates the arguments and for a string argument with white space single quotes (‘) are required. I hope these examples have been helpful and your experience with the Powershell Start-Process cmdlet is more productive.