<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PowerShell.nu &#187; Scripting</title>
	<atom:link href="http://www.powershell.nu/category/scripting/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.powershell.nu</link>
	<description></description>
	<lastBuildDate>Wed, 14 Jul 2010 22:17:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Running Scripts with arguments in PowerShell</title>
		<link>http://www.powershell.nu/2009/12/16/running-scripts-with-arguments-in-powershell/</link>
		<comments>http://www.powershell.nu/2009/12/16/running-scripts-with-arguments-in-powershell/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 16:34:19 +0000</pubDate>
		<dc:creator>Niklas Goude</dc:creator>
				<category><![CDATA[Basics]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://www.powershell.nu/?p=924</guid>
		<description><![CDATA[Here&#8217;s a short guide on running scripts in powershell. The guide is divided into three parts: Running Scripts from the Console Running Scripts from Start/Run Running Scripts as Backgournd Jobs in PowerShell First, let&#8217;s look at the script examples that we want to run. Here&#8217;s the first script: ################## # # Script 1 # ################## [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a short guide on running scripts in powershell. </p>
<p />
The guide is divided into three parts:</p>
<ul>
<li>Running Scripts from the Console</li>
<li>Running Scripts from Start/Run</li>
<li>Running Scripts as Backgournd Jobs in PowerShell</li>
</ul>
<p />
First, let&#8217;s look at the script examples that we want to run.</p>
<p />
Here&#8217;s the first script:</p>
<p />
<pre>
##################
#
# Script 1
#
##################

"Arguments: $($args.count)"
$args
</pre>
<p />
And here&#8217;s the second script:</p>
<p />
<pre>
##################
#
# Script 2
#
##################

param($Argument1,$Argument2)

"Argument1 is: $Argument1"
"Argument2 is: $Argument2"
</pre>
<p />
Script 1 uses $args variable to handle arguments. This is a automatic Variable created by PowerShell. It will handle any arguments that are passed to the script.<br />
<br />
Script 2 uses a param statement. the param statement let&#8217;s us define variables that hold our arguments. The variables are available throughout the script.</p>
<p />
<h2>Running Scripts from the Console</h2>
<p />
Now, let&#8217;s look at a couple of different ways of running scripts from the PowerShell console.</p>
<p />
<pre>
<strong>
PS > C:\temp\Scripts\script1.ps1 Hello World
</strong>
Arguments: 2
Hello
World
</pre>
<p />
In the example, we triggered the script with two arguments, Hello and World. If we instead want Hello World to pass as a single argument, we can use quotation marks:</p>
<p />
<strong><br />
PS > C:\temp\Scripts\script1.ps1 &#8220;Hello World&#8221;<br />
</strong><br />
Arguments: 1<br />
Hello World
</pre>
<p />
In this example, There's only one argument passed to the script since "Hello World" is within quotation marks.</p>
<p />
Obviously, we can use variables as arguments.</p>
<p />
<pre>
<strong>
PS > $HelloWorld = "Hello World"
PS > $Hello = "Hello"
PS > $World = "World"

PS > C:\temp\Scripts\script1.ps1 $HelloWorld
</strong>
Arguments: 1
Hello World
</pre>
<p />
When we enter $HelloWorld, the value of the $HelloWorld variable is passed on as one argument to the script.</p>
<p />
If we instead use the Variables $Hello and $World, they will be handled as two different arguments.</p>
<pre>
<strong>
PS > C:\temp\Scripts\script1.ps1 $Hello $World
</strong>
Arguments: 2
Hello
World
</pre>
<p />
If we put the variables within quotation marks, they will be passed on to the script as one single argument.</p>
<pre>
<strong>
PS > C:\temp\Scripts\script1.ps1 "$Hello $World"
</strong>
Arguments: 1
Hello World
</pre>
<p />
Using Single Quotation takes passes the argument exactly as written, in other words, the Argument will be $Hello $World and not the values of the variables.</p>
<p />
<pre>
<strong>
PS > C:\temp\Scripts\script1.ps1 '$Hello $World'
</strong>
Arguments: 1
$Hello $World
</pre>
<p />
It's possible to achieve this when using Double Quotation marks. Just add a backtrick character in front of the variables.</p>
<p />
<pre>
<strong>
PS > C:\temp\Scripts\script1.ps1 "`$Hello `$World"
</strong>
Arguments: 1
$Hello $World
</pre>
<p />
Let's look at a few examples on running Script 2 from the console. Script 2 uses the param statement.</p>
<p />
<pre>
<strong>
PS > C:\temp\Scripts\script2.ps1 Hello World
</strong>
Argument1 is: Hello
Argument2 is: World
</pre>
<p />
In this example, Hello is assigned to $Argument1 and World is Assigned to $Argument2</p>
<p />
<pre>
<strong>
PS > C:\temp\Scripts\script2.ps1 "Hello World"
</strong>
Argument1 is: Hello World
Argument2 is:
</pre>
<p />
If we put Hello World in double quotation marks, both Hello and World are assigned to $Argument1. $Argument2 is empty.</p>
<p />
It's also possible to use the param variables as parameters to the script as the examples below show.</p>
<p />
<pre>
<strong>
PS > C:\temp\Scripts\script2.ps1 -Argument1 Hello -Argument2 World
</strong>
Argument1 is: Hello
Argument2 is: World
</pre>
<p />
If we only specify one parameter the second will automatically be assigned to the first variable in the param that doesn't have a value.</p>
<p />
<pre>
<strong>
PS > C:\temp\Scripts\script2.ps1 -Argument1 Hello World
</strong>
Argument1 is: Hello
Argument2 is: World
<strong>
PS > C:\temp\Scripts\script2.ps1 -Argument2 World Hello
</strong>
Argument1 is: Hello
Argument2 is: World
</pre>
<p />
You can, of course, use quotation marks here as well.</p>
<p />
<pre>
<strong>
PS > C:\temp\Scripts\script2.ps1 -Argument1 "Hello World"
</strong>
Argument1 is: Hello World
Argument2 is:
</pre>
<p />
What if the Path to the script contains spaces ?. Let's see what happens. in these examples I've changed the path to the scripts to C:\Temp\Example Scripts\</p>
<p />
<pre>
<strong>
PS > C:\temp\Example Scripts\script1.ps1 "Hello World"
</strong>
The term 'C:\temp\Example' is not recognized as the name..
</pre>
<p />
so this didn't work. It's because PowerShell separates commands with a space, so it tries to run the command C:\Temp\Example. You can solve this by using quotation marks and a Call Operator. without the Call Operator, PowerShell will handle the script path as a string value.</p>
<p />
<pre>
<strong>
PS > &#038; "C:\temp\Example Scripts\script1.ps1" "Hello World"
</strong>
Arguments: 1
Hello World
</pre>
<p />
Script2 can be triggered in the same way, note that the arguments are after the scriptpath and not within quotation marks.</p>
<p />
<pre>
<strong>
PS > &#038; "C:\temp\Example Scripts\script2.ps1" -Argument1 Hello -Argument2 World
</strong>
Argument1 is: Hello
Argument2 is: World
</pre>
<p />
Another way of running scripts is if you're in the same directory as the scripts are located. Then you can simply use the .\ notation in front of the script.</p>
<p />
<pre>
<strong>
PS > cd 'C:\temp\Example Scripts\'
PS > .\script1.ps1 "Hello World"
</strong>
Arguments: 1
Hello World
</pre>
<p />
The easist way to run scripts is if you include the scriptpath in the environment PATH.</p>
<p />
<pre>
<strong>
$Env:PATH = $Env:PATH + ";C:\Temp\Example Scripts"
</strong>
</pre>
<p />
Now we can simply type the name of the script to run it.</p>
<p />
<pre>
<strong>
PS > script2.ps1 -Argument1 Hello -Argument2 World
</strong>
Argument1 is: Hello
Argument2 is: World
</pre>
<p />
You don't even have to type the script extension when running the scripts.</p>
<p />
<pre>
<strong>
PS > script2 -Argument1 Hello -Argument2 World
</strong>
Argument1 is: Hello
Argument2 is: World
</pre>
<p />
<h2>Running Scripts from Start/Run</h2>
<p />
You can also trigger scripts from Start / Run in Windows. Here are a couple of examples on how we can run our scripts from Start / Run. The NoExit switch is used in these examples so that we can check the result easily. </p>
<p />
<pre>
<strong>
powershell.exe -noexit C:\temp\Scripts\script1.ps1 Hello World
</strong>
</pre>
<p />
When running Scripts that are in a path that doesn't include spaces you can simply type the scripts FullPath followed by the arguments as shown in the example above. But what if you want "Hello World" to be handled as just one argument?</p>
<p />
<pre>
<strong>
powershell.exe -noexit C:\temp\Scripts\script1.ps1 "Hello World"
</strong>
</pre>
<p />
If we type "Hello World" inside double quotation marks it's still handled as two different arguments. We can solve this by using Single Quotation Marks.</p>
<p />
<pre>
<strong>
powershell.exe -noexit C:\temp\Scripts\script1.ps1 'Hello World'
</strong>
</pre>
<p />
Let's see how this works with the script that uses a param.</p>
<p />
<pre>
<strong>
powershell.exe -noexit C:\temp\Scripts\script2.ps1 Hello World
</strong>
</pre>
<p />
This works just fine, lets specify the parameters in the script as well.</p>
<p />
<pre>
<strong>
powershell.exe -noexit C:\temp\Scripts\script2.ps1 -Argument1 Hello -Argument2 World
</strong>
</pre>
<p />
And, as you can see, this works fine as well. Now let's see what happens if we double quote on of the arguments.</p>
<p />
<pre>
<strong>
powershell.exe -noexit C:\temp\Scripts\script2.ps1 -Argument1 "Hello World" -Argument2 Monkey
</strong>
</pre>
<p />
This returns Hello as Argument1 and Monkey as Argument2. World is not in the script ouput. Now let's do the same example with single quotation marks.</p>
<p />
<pre>
<strong>
powershell.exe -noexit C:\temp\Scripts\script2.ps1 -Argument1 'Hello World' -Argument2 Monkey
</strong>
</pre>
<p />
Now we got the result that we wanted. So lesson learned from this is: use single quotation marks when passing arguments containing spaces.</p>
<p />
Now let's test this with the scripts containing spaces in the script path.</p>
<p />
<pre>
<strong>
powershell.exe -noexit C:\temp\Example Scripts\script1.ps1 "Hello World"
</strong>
</pre>
<p />
This didn't work since the path contains spaces, now let's try it with double quotes at first.</p>
<p />
<pre>
<strong>
powershell.exe -noexit "C:\temp\Example Scripts\script1.ps1" "Hello World"
</strong>
</pre>
<p />
Still no luck, lets try adding the Call Operator.</p>
<p />
<pre>
<strong>
powershell.exe -noexit &#038; "C:\temp\Example Scripts\script1.ps1" "Hello World"
</strong>
</pre>
<p />
In order to get it right, we have to use single quotation marks.</p>
<p />
<pre>
<strong>
powershell.exe -noexit &#038; 'C:\temp\Example Scripts\script1.ps1' "Hello World"
</strong>
</pre>
<p />
Note that Hello World is handled as two different arguments. Whe can solve this by typing Hello World within single quotation marks.</p>
<p />
<pre>
<strong>
powershell.exe -noexit &#038; 'C:\temp\Example Scripts\script1.ps1' 'Hello World'
</strong>
</pre>
<p />
Script 2, that uses the param statement works in the same way.</p>
<p />
<pre>
<strong>
powershell.exe -noexit &#038; 'C:\temp\Example Scripts\script2.ps1' -Argument1 Hello -Argument2 World

powershell.exe -noexit &#038; 'C:\temp\Example Scripts\script2.ps1' -Argument1 'Hello World'  -Argument2 Monkey
</strong>
</pre>
<p />
Finally, let's see what happens if we run scripts included in the $Env:PATH variable.</p>
<p />
First, we should add the script path to our profile so that it's loaded when powershell starts. Just Add $Env:PATH = $Env:PATH + ";C:\Temp\Example Scripts" into your profile.ps1 file.</p>
<p />
<pre>
<strong>
powershell.exe -noexit script1.ps1 'Hello World'

powershell.exe -noexit script2.ps1 -Argument1 Hello -Argument2 World
</strong>
</pre>
<p />
We can even run the scripts without the extension.</p>
<p />
<pre>
<strong>
powershell.exe -noexit script1 'Hello World'

powershell.exe -noexit script2 -Argument1 Hello -Argument2 World
</strong>
</pre>
<p />
Adding a script path to the $Env:PATH variable makes it alot more simple to run scripts in PowerShell.</p>
<p />
<h2>Running Scripts as Backgournd Jobs in PowerShell</h2>
<p />
Let's take a look on how to run scripts as background Jobs. PowerShell v2 includes a great cmdlet callet Start-Job. It let's us run Jobs in the background. We can use this to run our scripts as background jobs.</p>
<p />
Let's take a look on How to Run Scripts witth Start-Job.</p>
<pre>
<strong>
PS > $Job1 = Start-Job .\script1.ps1 -ArgumentList Hello,World
</strong>
</pre>
<p />
By placing the command in a variable, we can easily access the Job informationm, check for status and use it to retrieve the output of the command. Start-Job Doesn't return the Job Result when completed so we have to use Receive-Job to get the Result from the Script.</p>
<p />
<pre>
<strong>
PS > Receive-Job $Job1.ID
Arguments: 2
Hello
World
PS > Receive-Job $Job1.ID
PS >
</strong>
</pre>
<p />
When we run the Receive-Job CmdLet and use the Jobs ID as argument, we get the Result from the Job Returned. Note that if we run the same command again, we don't get anything returned. This is becauese Receive-Job, by default, deletes the Returned information after it's accessed. We can bypass this with the -Keep switch.</p>
<p />
<pre>
<strong>
PS > $Job1 = Start-Job .\script1.ps1 -ArgumentList Hello,World
PS > Receive-Job $Job1.ID -Keep
Arguments: 2
Hello
World
PS > Receive-Job $Job1.ID -Keep
Arguments: 2
Hello
World
</strong>
</pre>
<p />
To Close the Session, run the Receive-Job command without the -Keep switch or use the Remove-Job CmdLet as shown below.</p>
<p />
<pre>
<strong>
PS > Remove-Job $Job1.ID
</strong>
</pre>
<p />
So how to solve this without PowerShell V2 installed ? well, we could always use Wscript.Shell. Here's an example on running backgroundjobs with wscript.shell.</p>
<p />
<pre>
<strong>
PS > $Wscript = New-Object -Com Wscript.Shell
PS > $Command = "powershell.exe &#038; 'C:\temp\Example Scripts\script2.ps1' -Argument1 'Hello' -Argument2 'World'"
PS > $Wscript.Run($command,0,$False)
0
</strong>
</pre>
<p />
So how do we varify that the script actually runs ? Well, we can solve this with a simple pipeline.</p>
<p />
<pre>
<strong>
PS > $Wscript = New-Object -Com Wscript.Shell
PS > $OutFile = "C:\temp\output.txt"
PS > $Command = "powershell.exe &#038; 'C:\temp\Example Scripts\script2.ps1' -Argument1 'Hello' -Argument2 'World' | Out-File $OutFile"
PS > $Wscript.Run($command,0,$False)
</strong>
0
<strong>
PS > Get-Content $OutFile
</strong>
Argument1 is: Hello
Argument2 is: World
</pre>
<p />
Hope you find this guide useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.powershell.nu/2009/12/16/running-scripts-with-arguments-in-powershell/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
