<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Keith Hill&#039;s Blog</title>
	<atom:link href="http://rkeithhill.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://rkeithhill.wordpress.com</link>
	<description>Just another WordPress.com site</description>
	<lastBuildDate>Fri, 17 Feb 2012 15:40:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='rkeithhill.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Keith Hill&#039;s Blog</title>
		<link>http://rkeithhill.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://rkeithhill.wordpress.com/osd.xml" title="Keith Hill&#039;s Blog" />
	<atom:link rel='hub' href='http://rkeithhill.wordpress.com/?pushpress=hub'/>
		<item>
		<title>PowerShell V3 CTP2 Provides Better Argument Passing to EXEs</title>
		<link>http://rkeithhill.wordpress.com/2012/01/02/powershell-v3-ctp2-provides-better-argument-passing-to-exes/</link>
		<comments>http://rkeithhill.wordpress.com/2012/01/02/powershell-v3-ctp2-provides-better-argument-passing-to-exes/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 19:56:23 +0000</pubDate>
		<dc:creator>rkeithhill</dc:creator>
				<category><![CDATA[PowerShell 3.0]]></category>
		<category><![CDATA[Parsing]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[V3]]></category>

		<guid isPermaLink="false">https://rkeithhill.wordpress.com/?p=241</guid>
		<description><![CDATA[Within PowerShell it has always been easy to pass “simple” arguments to an EXE e.g.: C:\PS&#62; ipconfig -all However passing arguments to certain exes can become surprising difficult when their command line parameter syntax is complex i.e. they require quotes &#8230; <a href="http://rkeithhill.wordpress.com/2012/01/02/powershell-v3-ctp2-provides-better-argument-passing-to-exes/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=241&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Within PowerShell it has always been easy to pass “simple” arguments to an EXE e.g.:</p>
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; ipconfig -all</pre>
</div>
<p>However passing arguments to certain exes can become surprising difficult when their command line parameter syntax is complex i.e. they require quotes and use special PowerShell characters such as @ $ ;.  A lot of these problems can be solved by placing single or double quotes in the right places or by escaping PowerShell’s special characters e.g.:</p>
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; tf.exe status . /workspace:HILLR1;hillr /r
There are no pending changes.
The term 'hillr' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:35
+ tf.exe status . /workspace:HILLR1;hillr /r
+                                   ~~~~~
    + CategoryInfo          : ObjectNotFound: (hillr:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException</pre>
</div>
<div></div>
<p>Note that in the command line above the “/workspace” parameter value is specified using a special syntax that TF.exe recognizes i.e. &lt;workspace_name&gt;;&lt;username&gt;.  Unfortunately the semicolon is a statement separator in PowerShell which means that TF.exe only sees the parameters before the semicolon.  We can use the ECHOARGS.exe utility from the <a href="http://pscx.codeplex.com/">PowerShell Community Extensions</a> to verify this:</p>
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; echoargs.exe status . /workspace:HILLR1;hillr /r
Arg 0 is &lt;status&gt;
Arg 1 is &lt;.&gt;
Arg 2 is &lt;/workspace:HILLR1&gt;</pre>
</div>
<p>In this case, the solution is simple – just escape the semicolon e.g.:</p>
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; tf.exe status . /r /workspace:HILLR1`;hillr
File name     Change Local path
------------- ------ -----------------------------------------
$/Foo/Trunk/Tools/Bin
TfsTools.psm1 edit   C:\Tfs\Foo\Trunk\Tools\Bin\TfsTools.psm1

1 change(s)</pre>
</div>
<p>This works up to the point where you get quite frustrated figuring out which characters to escape and which parameter/argument pairs need to be quoted and whether you should use single quotes or double quotes.  Fortunately, it looks like we will get a way to tell the PowerShell argument parser to stop doing so much work for us and just pass the args through “as-is”.  In other words, you can tell PowerShell to become a “dumber” command line parser.  This mode is invoked using the character sequence: –% and it works from the point it appears on the command line to the end of that line.  Note that the character sequence may change or the feature could be completely removed before V3 ships.</p>
<p>Given this new feature, here’s how you use it.  Take this example of a problematic set of command line parameters:</p>
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; sqlcmd -S .\SQLEXPRESS -v lname="Gates" -Q "SELECT FirstName,LastName FROM
AdventureWorks.Person.Contact WHERE LastName = '$(lname)'"
The term 'lname' is not recognized as the name of a cmdlet, function, script
file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
At line:1 char:126
+ ...  LastName = '$(lname)'"
+                    ~~~~~
    + CategoryInfo          : ObjectNotFound: (lname:String) [], CommandNotFou
   ndException
    + FullyQualifiedErrorId : CommandNotFoundException</pre>
<p>In this case the V2 solution is to escape the $ character in the last part of the command line e.g.: &#8216;`$(lname)&#8217; but if you don’t want to spend the time to figure this out you can easily use &#8211;% like so:</p>
</div>
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; sqlcmd --% -S .\SQLEXPRESS -v lname="Gates" -Q "SELECT FirstName,LastName F
ROM AdventureWorks.Person.Contact WHERE LastName = '$(lname)'"
FirstName                                          LastName

---------------------------------- -----------------------------------
Janet                              Gates

(1 rows affected)</pre>
</div>
<p>You can put the &#8211;% later in the parameter list if you want.  You might want to do this if you need to use PowerShell variable expansion in some of the arguments.  Just note that once you specify &#8211;% the rest of the command line will be parsed “dumbly”.  You will get no PowerShell variable expansion or grouping expressions and you won’t be able to escape newlines.  One thing you can do in this special parsing mode is expand environment variables using the batch syntax of %ENV_VAR% e.g.:</p>
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; $env:colname = "LastName"
C:\PS&gt; sqlcmd -S .\SQLEXPRESS -v lname="Gates" --% -Q "SELECT FirstName,LastName F
ROM AdventureWorks.Person.Contact WHERE %colname% = '$(lname)'"
FirstName                                          LastName

---------------------------------- -----------------------------------
Janet                              Gates

(1 rows affected)</pre>
<p>I believe this new command line parsing feature will greatly simplify interacting with exes that have a complex command line parameter syntax.  Thanks to the PowerShell team for listening to the <a href="https://connect.microsoft.com/PowerShell/feedback/details/376207/executing-commands-which-require-quotes-and-variables-is-practically-impossible">community feedback on this issue</a> and providing a solution.</p>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rkeithhill.wordpress.com/241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rkeithhill.wordpress.com/241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rkeithhill.wordpress.com/241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rkeithhill.wordpress.com/241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rkeithhill.wordpress.com/241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rkeithhill.wordpress.com/241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rkeithhill.wordpress.com/241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rkeithhill.wordpress.com/241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rkeithhill.wordpress.com/241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rkeithhill.wordpress.com/241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rkeithhill.wordpress.com/241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rkeithhill.wordpress.com/241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rkeithhill.wordpress.com/241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rkeithhill.wordpress.com/241/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=241&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rkeithhill.wordpress.com/2012/01/02/powershell-v3-ctp2-provides-better-argument-passing-to-exes/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/bcc517cd604f90500c5dcef5a6ed7f81?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rkeithhill</media:title>
		</media:content>
	</item>
		<item>
		<title>Microsoft Windows PowerShell V3 CTP2 Available for Download</title>
		<link>http://rkeithhill.wordpress.com/2011/12/05/microsoft-windows-powershell-v3-ctp2-available-for-download/</link>
		<comments>http://rkeithhill.wordpress.com/2011/12/05/microsoft-windows-powershell-v3-ctp2-available-for-download/#comments</comments>
		<pubDate>Mon, 05 Dec 2011 17:40:24 +0000</pubDate>
		<dc:creator>rkeithhill</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[PowerShell 3.0]]></category>

		<guid isPermaLink="false">https://rkeithhill.wordpress.com/?p=238</guid>
		<description><![CDATA[You can grab the bits from here. If you have V3 CTP1 installed, please uninstall it first or you can get your machine into a bad state. So far my favorite two features new to this drop are both in &#8230; <a href="http://rkeithhill.wordpress.com/2011/12/05/microsoft-windows-powershell-v3-ctp2-available-for-download/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=238&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>You can grab the bits from <a href="http://www.microsoft.com/download/en/details.aspx?id=27548">here</a>. <font>If you have V3 CTP1 installed,</font><font> </font><font>please uninstall it first or you can get your machine into a bad state</font>. </p>
<p>So far my favorite two features new to this drop are both in the Integrated Scripting Editor (ISE). The first is the “most recently opened files list” on the File menu and second is the switch to a two pane ISE (combines the output and command panes into one). Oh yeah, there isn’t much in the help system until you run Update-Help from an elevated prompt.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rkeithhill.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rkeithhill.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rkeithhill.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rkeithhill.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rkeithhill.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rkeithhill.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rkeithhill.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rkeithhill.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rkeithhill.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rkeithhill.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rkeithhill.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rkeithhill.wordpress.com/238/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rkeithhill.wordpress.com/238/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rkeithhill.wordpress.com/238/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=238&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rkeithhill.wordpress.com/2011/12/05/microsoft-windows-powershell-v3-ctp2-available-for-download/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/bcc517cd604f90500c5dcef5a6ed7f81?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rkeithhill</media:title>
		</media:content>
	</item>
		<item>
		<title>Windows PowerShell Version 3 Simplified Syntax</title>
		<link>http://rkeithhill.wordpress.com/2011/10/19/windows-powershell-version-3-simplified-syntax/</link>
		<comments>http://rkeithhill.wordpress.com/2011/10/19/windows-powershell-version-3-simplified-syntax/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 00:44:42 +0000</pubDate>
		<dc:creator>rkeithhill</dc:creator>
				<category><![CDATA[PowerShell 3.0]]></category>

		<guid isPermaLink="false">https://rkeithhill.wordpress.com/2011/10/19/windows-powershell-version-3-simplified-syntax/</guid>
		<description><![CDATA[Windows PowerShell version 3 introduces a simplified syntax for the Where-Object and Foreach-Object cmdlets.&#160; The simplified syntax shown below, eliminates the curly braces as well as the need for the special variable $_. C:\PS&#62; Get-Process &#124; Where PM -gt 100MB &#8230; <a href="http://rkeithhill.wordpress.com/2011/10/19/windows-powershell-version-3-simplified-syntax/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=233&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Windows PowerShell version 3 introduces a simplified syntax for the Where-Object and Foreach-Object cmdlets.&nbsp; The simplified syntax shown below, eliminates the curly braces as well as the need for the special variable <font face="Consolas">$_</font>.</p>
<div id="codeSnippetWrapper">
<div id="codeSnippetWrapper">
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; Get-Process | Where PM -gt 100MB
...
C:\PS&gt; Get-Process | Foreach Name
...</pre>
</div>
<p></div>
</div>
<p>The intent of this “syntax” is to make it easier for folks get started with PowerShell.&nbsp; Compared to the commands below, I can see the value of the simplified syntax:</p>
<div id="codeSnippetWrapper">
<div id="codeSnippetWrapper">
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; Get-Process | Where {$_.PM -gt 100MB}
...
C:\PS&gt; Get-Process | Foreach {$_.Name}
...</pre>
</div>
<p></div>
</div>
<p>When folks are first learning PowerShell, the special variable <font face="Consolas">$_</font> is one of those mental model hurdles they have to get over.&nbsp; The simplified syntax feature of V3 seems to generate a fair amount of controversy (is it really necessary, doesn’t this just complicate things more, etc).&nbsp; Regardless of where you stand on the simplified syntax it is useful to understand how it works.</p>
<p>Given that it appears to be a simplified expression syntax you might think this required a change to the PowerShell parser’s grammar but you would be wrong.&nbsp; It turns out that the simplified syntax is implemented by additional parameter sets – lots of additional parameter sets. In fact, for every operator supported, there is an additional parameter set to support that operator.&nbsp; Let’s see this with the Where-Object cmdlet by listing out all of its parameter set names:</p>
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; Get-Command Where-Object | Select -Expand ParameterSets | Format-Table Name

Name
----
EqualSet
ScriptBlockSet
CaseSensitiveGreaterThanSet
CaseSensitiveNotEqualSet
LessThanSet
CaseSensitiveEqualSet
NotEqualSet
GreaterThanSet
CaseSensitiveLessThanSet
GreaterOrEqualSet
CaseSensitiveGreaterOrEqualSet
LessOrEqualSet
CaseSensitiveLessOrEqualSet
LikeSet
CaseSensitiveLikeSet
NotLikeSet
CaseSensitiveNotLikeSet
MatchSet
CaseSensitiveMatchSet
NotMatchSet
CaseSensitiveNotMatchSet
ContainsSet
CaseSensitiveContainsSet
NotContainsSet
CaseSensitiveNotContainsSet
InSet
CaseSensitiveInSet
NotInSet
CaseSensitiveNotInSet
IsSet
IsNotSet</pre>
</div>
<div id="codeSnippetWrapper">
<div id="codeSnippetWrapper">
<div>&nbsp;</div>
</div>
</div>
<p>Most of these correspond to the operators you are already familiar with such as: –GT, –LT, –GE, –LE, –LIKE, –MATCH, –NOTMATCH, –CONTAINS, –NOTCONTAINS, etc.&nbsp; Note however there are two new operators in PowerShell V3: –In and –NotIn which you can use like so:</p>
<div id="codeSnippetWrapper">
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; 1 -In 1..10
True
C:\PS&gt; 20 -NotIn 1..10
True</pre>
</div>
<p></div>
<p>Let’s look at the interesting parameters on these operator specific parameter sets.&nbsp; Let’s look at the EqualsSet parameter set:</p>
<div id="codeSnippetWrapper">
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; Get-Command Where-Object | Select -Expand ParameterSets | Where Name -eq EqualSet |
           Select -Expand Parameters | Where Position -ge 0 |
           Format-Table Name,Position,IsMandatory -AutoSize

Name     Position IsMandatory
----     -------- -----------
Property        0        True
Value           1       False</pre>
</div>
<p></div>
<p>As it turns out, these results are the same for all the <em>operator</em> oriented parameter sets.&nbsp; At the very minimum, the Property parameter is required and is always the first positional parameter.&nbsp; And as you would expect, if you don’t provide it, you get prompted for a value:</p>
<div id="codeSnippetWrapper">
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; Get-Process | Where -eq

cmdlet Where-Object at command pipeline position 2
Supply values for the following parameters:
Property:</pre>
</div>
<p></div>
<p>Now even though Value parameter is specified as not mandatory, in many cases if you don’t provide it you will get a terminating error e.g.:</p>
<div id="codeSnippetWrapper">
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; Get-Process | Where Name -eq
Where-Object : The specified operator requires both the -Property and -Value parameters. Supply both parameters and
retry.
At line:1 char:15
+ Get-Process | Where Name -eq
+               ~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Where-Object], PSArgumentException
    + FullyQualifiedErrorId : ValueNotSpecifiedForWhereObject,Microsoft.PowerShell.Commands.WhereObjectCommand</pre>
</div>
<p></div>
<p>There are some cases where you don’t have to provide the value nor the operator e.g.:</p>
<div id="codeSnippetWrapper">
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; Get-Process | Where Responding

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    216      10     3560       2896    73            4000 atieclxx
    130       7     2380       1028    33            1020 atiesrxx
    157      11    17288      13344    49            7876 audiodg
     28       6     1256        420    42     0.06   2752 BluetoothHeadsetProxy
...</pre>
</div>
<p></div>
<p>This works because A) the EqualsSet parameter set is the default parameter set and B) the Where-Object implementation appears to coerce the property specified (<em>Responding</em> in this case) to Boolean. If the result is $true then the object is output by Where-Object and sent on its way down the pipeline.</p>
<p>So all this simplified syntax really is, is a bunch of operator specific parameter sets on Where-Object that have a positional and mandatory Property parameter of type [string] and a positional Value parameter of type [object].&nbsp; In the case of Foreach-Object it is one extra parameter set called PropertyAndMethodSet which has one mandatory, positional parameter called MemberName.&nbsp; And as with any cmdlet, you provide the parameter values and the cmdlet determines how to interpret them.&nbsp; In fact, given standard parameter parsing behavior the below is as valid as the conventional notation:</p>
<div id="codeSnippetWrapper">
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; Get-Process | Where -GT PM 100MB
...
C:\PS&gt; Get-Process | Where PM 100MB -GT
...
C:\PS&gt; Get-Process | Where -Value 100MB -Property PM -GT
...</pre>
</div>
<p></div>
<div>Now where this syntax can lead you astray if you don’t understand how it works, is if you make the assumption that this is a parsed expression.&nbsp; In that case, folks might expect this to work:</div>
<div>&nbsp;</div>
<div id="codeSnippetWrapper">
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; Get-Process | Where Threads.Count -GT 100</pre>
</div>
<p></div>
<div>There <em>is</em> a Threads collection on each Process object.&nbsp; We might think that we can access a property on that collection but in effect, what happens is that the Where-Object Property parameter gets the value “Threads.Count” and there is no property on a Process object called “Threads.Count”. This silently fails which might lead you to believe there are no processes with greater than 100 threads.&nbsp; But reverting back to the standard syntax we see that isn’t the case:</div>
<div>&nbsp;</div>
<div id="codeSnippetWrapper">
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; Get-Process | Where {$_.Threads.Count -GT 100}

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
   2080     126   155680     139928   531   113.68   4920 msnmsgr
   1087       0      312       8800    15               4 System</pre>
</div>
<p></div>
<div>So when you are using the simplified syntax be sure to keep in mind that you can <strong>only </strong>specify property names and you cannot access sub-properties.&nbsp; Keep your property names simple and you should be copasetic with the new, simplified syntax.&nbsp; While I’m a little unsure about the new simplified syntax given how quickly you can fall off the “simple” path into the sharp rocks and lava below, I will say this.&nbsp; As I wrote this blog post, I used the simplified syntax quite a bit and I have to say that it is growing on me.</div>
<div>&nbsp;</div>
<div>One final item to mention about simplified syntax.&nbsp; It turns out that some folks have a hard time grokking <font face="Consolas">$_</font> but when they’re presented with <font face="Consolas"><strong>$PSItem</strong></font> it apparently makes more sense to them.&nbsp; So in PowerShell v3, wherever you can use <font face="Consolas">$_</font> you can also use <font face="Consolas">$PSItem</font>.&nbsp; <font face="Consolas">$PSItem</font> is not an alias. It seems to be a duplicate variable defined in all the same scopes as <font face="Consolas">$_</font> and its value tracks that of <font face="Consolas">$_</font> e.g.:</div>
<div>&nbsp;</div>
<div>
<pre style="text-align:left;line-height:14pt;background-color:#000080;width:100%;font-family:Consolas, courier, monospace;direction:ltr;color:white;font-size:10pt;overflow:visible;border-style:none;margin:0;padding:5px;">C:\PS&gt; 1 | Foreach {Get-Variable _,psitem; $_ = 4; Get-Variable _,psitem}

Name                           Value
----                           -----
_                              1
PSItem                         1
_                              4
PSItem                         4</pre>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rkeithhill.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rkeithhill.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rkeithhill.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rkeithhill.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rkeithhill.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rkeithhill.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rkeithhill.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rkeithhill.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rkeithhill.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rkeithhill.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rkeithhill.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rkeithhill.wordpress.com/233/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rkeithhill.wordpress.com/233/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rkeithhill.wordpress.com/233/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=233&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rkeithhill.wordpress.com/2011/10/19/windows-powershell-version-3-simplified-syntax/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/bcc517cd604f90500c5dcef5a6ed7f81?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rkeithhill</media:title>
		</media:content>
	</item>
		<item>
		<title>PSCX 2.1 Beta 1 Available for Download</title>
		<link>http://rkeithhill.wordpress.com/2011/09/18/pscx-2-1-beta-1-available-for-download/</link>
		<comments>http://rkeithhill.wordpress.com/2011/09/18/pscx-2-1-beta-1-available-for-download/#comments</comments>
		<pubDate>Mon, 19 Sep 2011 04:17:17 +0000</pubDate>
		<dc:creator>rkeithhill</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[PowerShell 3.0]]></category>
		<category><![CDATA[PSCX]]></category>

		<guid isPermaLink="false">https://rkeithhill.wordpress.com/2011/09/18/pscx-2-1-beta-1-available-for-download/</guid>
		<description><![CDATA[I just uploaded beta 1 for the PowerShell Community Extensions version 2.1.&#160; This beta drop adds better support for Windows PowerShell V3 that is in the Windows 8 Developer Preview.&#160; There are a number of bug fixes in this drop: &#8230; <a href="http://rkeithhill.wordpress.com/2011/09/18/pscx-2-1-beta-1-available-for-download/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=232&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I just uploaded beta 1 for the PowerShell Community Extensions version 2.1.&nbsp; This beta drop adds better support for Windows PowerShell V3 that is in the Windows 8 Developer Preview.&nbsp; There are a number of bug fixes in this drop:</p>
<ul>
<li>28023 Read-Archive : Cannot bind parameter &#8216;Path&#8217;. Cannot convert the &#8230; value of type &#8220;System.String&#8221; to type &#8220;Pscx.IO.PscxPathInfo&#8221;.
<li>28198 Test-XML not validating xml against schema correctly
<li>28964 Get-FileTail access conflict
<li>29255 Get-HttpResource Timeout Bug
<li>29598 String &#8211; PscxPathInfo ParameterBindingException
<li>30169 Invoke-Ternary example doesn&#8217;t work
<li>30921 Invoke-Elevated demands arguments</li>
</ul>
<p>You can download the beta from <a href="http://pscx.codeplex.com/releases/view/73566">here</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rkeithhill.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rkeithhill.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rkeithhill.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rkeithhill.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rkeithhill.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rkeithhill.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rkeithhill.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rkeithhill.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rkeithhill.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rkeithhill.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rkeithhill.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rkeithhill.wordpress.com/232/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rkeithhill.wordpress.com/232/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rkeithhill.wordpress.com/232/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=232&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rkeithhill.wordpress.com/2011/09/18/pscx-2-1-beta-1-available-for-download/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/bcc517cd604f90500c5dcef5a6ed7f81?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rkeithhill</media:title>
		</media:content>
	</item>
		<item>
		<title>MVP Summit 2011</title>
		<link>http://rkeithhill.wordpress.com/2011/03/09/mvp-summit-2011/</link>
		<comments>http://rkeithhill.wordpress.com/2011/03/09/mvp-summit-2011/#comments</comments>
		<pubDate>Thu, 10 Mar 2011 05:43:57 +0000</pubDate>
		<dc:creator>rkeithhill</dc:creator>
				<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">https://rkeithhill.wordpress.com/2011/03/09/mvp-summit-2011/</guid>
		<description><![CDATA[Testing out my first WordPress blog post after the switch from Windows Live Spaces (sniff, I will miss you) to WordPress.  Regarding the MVP Summit last week, I can’t really talk about much due to just about everything being NDA, NDA, &#8230; <a href="http://rkeithhill.wordpress.com/2011/03/09/mvp-summit-2011/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=209&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Testing out my first WordPress blog post after the switch from Windows Live Spaces (sniff, I will miss you) to WordPress.  Regarding the MVP Summit last week, I can’t really talk about much due to just about everything being NDA, NDA, NDA!  I will say that I’m excited about the future of PowerShell!  Probably the most fun part was hanging out with the other PowerShell MVPs for a week.</p>
<p>It seems to me that Microsoft still values their relationship with the MVPs as evidenced by the party they arranged for MVPs last Wednesday:</p>
<p><a href="http://rkeithhill.files.wordpress.com/2011/03/mvp-summit-20110302-dsc_0052.jpg"><img style="background-image:none;padding-left:0;padding-right:0;display:inline;padding-top:0;border:0;" title="MVP Summit 20110302-DSC_0052" src="http://rkeithhill.files.wordpress.com/2011/03/mvp-summit-20110302-dsc_0052_thumb.jpg?w=644&#038;h=429" border="0" alt="MVP Summit 20110302-DSC_0052" width="644" height="429" /></a></p>
<p>Yep, that is SafeCo field in Seattle where the Mariners play.  They rented the whole stadium out for the evening!  There where a couple of bands – one called <a href="http://www.thebeatniks.com/im/index.php">The Beatniks</a> played out near centerfield.  You could run the bases, bat some balls up into the stands. Yeah, it was an awesome party.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rkeithhill.wordpress.com/209/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rkeithhill.wordpress.com/209/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rkeithhill.wordpress.com/209/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rkeithhill.wordpress.com/209/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rkeithhill.wordpress.com/209/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rkeithhill.wordpress.com/209/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rkeithhill.wordpress.com/209/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rkeithhill.wordpress.com/209/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rkeithhill.wordpress.com/209/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rkeithhill.wordpress.com/209/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rkeithhill.wordpress.com/209/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rkeithhill.wordpress.com/209/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rkeithhill.wordpress.com/209/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rkeithhill.wordpress.com/209/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=209&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rkeithhill.wordpress.com/2011/03/09/mvp-summit-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/bcc517cd604f90500c5dcef5a6ed7f81?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rkeithhill</media:title>
		</media:content>

		<media:content url="http://rkeithhill.files.wordpress.com/2011/03/mvp-summit-20110302-dsc_0052_thumb.jpg" medium="image">
			<media:title type="html">MVP Summit 20110302-DSC_0052</media:title>
		</media:content>
	</item>
		<item>
		<title>Make-PS1ExeWrapper</title>
		<link>http://rkeithhill.wordpress.com/2010/09/21/make-ps1exewrapper/</link>
		<comments>http://rkeithhill.wordpress.com/2010/09/21/make-ps1exewrapper/#comments</comments>
		<pubDate>Tue, 21 Sep 2010 17:39:16 +0000</pubDate>
		<dc:creator>rkeithhill</dc:creator>
				<category><![CDATA[PowerShell 2.0]]></category>

		<guid isPermaLink="false">http://rkeithhill.wordpress.com/2010/09/21/make-ps1exewrapper</guid>
		<description><![CDATA[Occasionally folks want to be able to create an EXE from PoweShell.  PowerShell can’t do this by itself but this can be done with PowerShell script.  Essentially what you can do is create a simple console EXE program that embeds &#8230; <a href="http://rkeithhill.wordpress.com/2010/09/21/make-ps1exewrapper/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=4&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div id="msgcns!5A8D2641E0963A97!7227" class="bvMsg">
<div>
<p>Occasionally folks want to be able to create an EXE from PoweShell.  PowerShell can’t do this by itself but this can be done with PowerShell script.  Essentially what you can do is create a simple console EXE program that embeds the script as a resource and the EXE, upon loading retrieves the script and throws it at a PowerShell runspace to execute.  Here’s the script for a feasibility test of doing this very thing.</p>
<p>Note that this script depends on Write-GZip from the <a href="http://pscx.codeplex.com/">PowerShell Community Extensions</a>.</p>
<p><strong>Update 6-21-2011:</strong> The migration from Windows Live Spaces to WordPress seems to have messed with the formatting of the script.  You can now <a href="https://skydrive.live.com/?cid=5a8d2641e0963a97&amp;sc=documents&amp;uc=2&amp;id=5A8D2641E0963A97%217251#">download the script from my SkyDrive</a>.</p>
<p><span style="font-family:Courier New;font-size:x-small;">#requires -version 2.0<br />
&lt;#<br />
.SYNOPSIS<br />
Creates an EXE wrapper from a PowerShell script by compressing the script and embedding into<br />
a newly generated assembly.<br />
.DESCRIPTION<br />
Creates an EXE wrapper from a PowerShell script by compressing the script and embedding into<br />
a newly generated assembly.<br />
.PARAMETER Path<br />
The path to the .<br />
.PARAMETER LiteralPath<br />
Specifies a path to one or more locations. Unlike Path, the value of LiteralPath is used exactly as it<br />
is typed. No characters are interpreted as wildcards. If the path includes escape characters, enclose<br />
it in single quotation marks. Single quotation marks tell Windows PowerShell not to interpret any<br />
characters as escape sequences.<br />
.PARAMETER OutputAssembly<br />
The name (including path) of the EXE to generate.<br />
.PARAMETER IconPath<br />
The path to an optional icon to be embedded as the application icon for the EXE.<br />
.EXAMPLE<br />
C:\PS&gt; .\Make-PS1ExeWrapper.ps1 .\MyScript.ps1 .\MyScript.exe .\app.ico<br />
This creates an console application called MyScript.exe that internally hosts the PowerShell<br />
engine and runs the script specified by MyScript.ps1.  Optionally the file app.ico is<br />
embedded into the EXE as the application&#8217;s icon.<br />
.NOTES<br />
Author: Keith Hill<br />
Date:   Aug 7, 2010<br />
Issues: This implementation is more of a feasibility test and isn&#8217;t fully functional.  It doesn&#8217;t<br />
support an number of PSHostUserInterface members as well as a number of PSHostRawUserInterface<br />
members.  This approach also suffers from the same problem of running script &#8220;interactively&#8221;<br />
and not loading it from a file. That is, the entire script output is run through Out-Default<br />
and PowerShell gets confused.  It formats the first types it sees correctly but after that the<br />
formatting is off.  To correct this, you have to append | Out-Default where you script outputs<br />
to the host without using a Write-* cmdlet e.g.:</span></p>
<p>MyScript.ps1:<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />
Get-Process svchost<br />
Get-Date | Out-Default<br />
Dir C:\  | Out-Default<br />
Dir c:\idontexist | Out-Default<br />
$DebugPreference = &#8216;Continue&#8217;<br />
$VerbosePreference = &#8216;Continue&#8217;<br />
Write-Host    &#8220;host&#8221;<br />
Write-Warning &#8220;warning&#8221;<br />
Write-Verbose &#8220;verbose&#8221;<br />
Write-Debug   &#8220;debug&#8221;<br />
Write-Error   &#8220;error&#8221;<br />
#&gt;<br />
[CmdletBinding(DefaultParameterSetName="Path")]<br />
param(<br />
[Parameter(Mandatory=$true, Position=0, ParameterSetName="Path",<br />
ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true,<br />
HelpMessage="Path to bitmap file")]<br />
[ValidateNotNullOrEmpty()]<br />
[string[]]<br />
$Path,</p>
<p>[Alias("PSPath")]<br />
[Parameter(Mandatory=$true, Position=0, ParameterSetName="LiteralPath",<br />
ValueFromPipelineByPropertyName=$true,<br />
HelpMessage="Path to bitmap file")]<br />
[ValidateNotNullOrEmpty()]<br />
[string[]]<br />
$LiteralPath,</p>
<p><span style="font-family:Courier New;font-size:x-small;">    [Parameter(Mandatory = $true, Position = 1)]<br />
[string]<br />
$OutputAssembly,</span></p>
<p>[Parameter(Position = 2)]<br />
[string]<br />
$IconPath<br />
)</p>
<p><span style="font-family:Courier New;font-size:x-small;">Begin {<br />
Set-StrictMode -Version latest</span></p>
<p>$src = @&#8217;<br />
using System;<br />
using System.Collections.Generic;<br />
using System.Collections.ObjectModel;<br />
using System.Globalization;<br />
using System.IO;<br />
using System.IO.Compression;<br />
using System.Management.Automation;<br />
using System.Management.Automation.Host;<br />
using System.Management.Automation.Runspaces;<br />
using System.Reflection;<br />
using System.Security;<br />
using System.Text;<br />
using System.Threading;</p>
<p><span style="font-family:Courier New;font-size:x-small;">namespace PS1ToExeTemplate<br />
{<br />
class Program<br />
{<br />
private static object _powerShellLock = new object();<br />
private static readonly Host _host = new Host();<br />
private static PowerShell _powerShellEngine;</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        static void Main(string[] args)<br />
{<br />
Console.CancelKeyPress += Console_CancelKeyPress;<br />
Console.TreatControlCAsInput = false;</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            string script = GetScript();<br />
RunScript(script, args, null);<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        private static string GetScript()<br />
{<br />
string script = String.Empty;</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            Assembly assembly = Assembly.GetExecutingAssembly();<br />
using (Stream stream = assembly.GetManifestResourceStream(&#8220;Resources.Script.ps1.gz&#8221;))<br />
{<br />
var gZipStream = new GZipStream(stream, CompressionMode.Decompress, true);<br />
var streamReader = new StreamReader(gZipStream);<br />
script = streamReader.ReadToEnd();<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            return script;<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        private static void RunScript(string script, string[] args, object input)<br />
{<br />
lock (_powerShellLock)<br />
{<br />
_powerShellEngine = PowerShell.Create();<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            try<br />
{<br />
_powerShellEngine.Runspace = RunspaceFactory.CreateRunspace(_host);<br />
_powerShellEngine.Runspace.Open();<br />
_powerShellEngine.AddScript(script);<br />
_powerShellEngine.AddCommand(&#8220;Out-Default&#8221;);<br />
_powerShellEngine.Commands.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">                if (input != null)<br />
{<br />
_powerShellEngine.Invoke(new[] { input });<br />
}<br />
else<br />
{<br />
_powerShellEngine.Invoke();<br />
}<br />
}<br />
finally<br />
{<br />
lock (_powerShellLock)<br />
{<br />
_powerShellEngine.Dispose();<br />
_powerShellEngine = null;<br />
}<br />
}<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)<br />
{<br />
try<br />
{<br />
lock (_powerShellLock)<br />
{<br />
if (_powerShellEngine != null &amp;&amp; _powerShellEngine.InvocationStateInfo.State == PSInvocationState.Running)<br />
{<br />
_powerShellEngine.Stop();<br />
}<br />
}<br />
e.Cancel = true;<br />
}<br />
catch (Exception ex)<br />
{<br />
_host.UI.WriteErrorLine(ex.ToString());<br />
}<br />
}<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">    class Host : PSHost<br />
{<br />
private PSHostUserInterface _psHostUserInterface = new HostUserInterface();</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void SetShouldExit(int exitCode)<br />
{<br />
Environment.Exit(exitCode);<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void EnterNestedPrompt()<br />
{<br />
throw new NotImplementedException();<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void ExitNestedPrompt()<br />
{<br />
throw new NotImplementedException();<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void NotifyBeginApplication()<br />
{<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void NotifyEndApplication()<br />
{<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override string Name<br />
{<br />
get { return &#8220;PSCX-PS1ToExeHost&#8221;; }<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override Version Version<br />
{<br />
get { return new Version(1, 0); }<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override Guid InstanceId<br />
{<br />
get { return new Guid(&#8220;E4673B42-84B6-4C43-9589-95FAB8E00EB2&#8243;); }<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override PSHostUserInterface UI<br />
{<br />
get { return _psHostUserInterface; }<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override CultureInfo CurrentCulture<br />
{<br />
get { return Thread.CurrentThread.CurrentCulture; }<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override CultureInfo CurrentUICulture<br />
{<br />
get { return Thread.CurrentThread.CurrentUICulture; }<br />
}<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">    class HostUserInterface : PSHostUserInterface, IHostUISupportsMultipleChoiceSelection<br />
{<br />
private PSHostRawUserInterface _psRawUserInterface = new HostRawUserInterface();</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override PSHostRawUserInterface RawUI<br />
{<br />
get { return _psRawUserInterface; }<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override string ReadLine()<br />
{<br />
return Console.ReadLine();<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override SecureString ReadLineAsSecureString()<br />
{<br />
throw new NotImplementedException();<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void Write(string value)<br />
{<br />
string output = value ?? &#8220;null&#8221;;<br />
Console.Write(output);<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void Write(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string value)<br />
{<br />
string output = value ?? &#8220;null&#8221;;<br />
var origFgColor = Console.ForegroundColor;<br />
var origBgColor = Console.BackgroundColor;<br />
Console.ForegroundColor = foregroundColor;<br />
Console.BackgroundColor = backgroundColor;<br />
Console.Write(output);<br />
Console.ForegroundColor = origFgColor;<br />
Console.BackgroundColor = origBgColor;<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void WriteLine(string value)<br />
{<br />
string output = value ?? &#8220;null&#8221;;<br />
Console.WriteLine(output);<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void WriteErrorLine(string value)<br />
{<br />
string output = value ?? &#8220;null&#8221;;<br />
var origFgColor = Console.ForegroundColor;<br />
Console.ForegroundColor = ConsoleColor.Red;<br />
Console.WriteLine(output);<br />
Console.ForegroundColor = origFgColor;<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void WriteDebugLine(string message)<br />
{<br />
WriteYellowAnnotatedLine(message, &#8220;DEBUG&#8221;);<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void WriteVerboseLine(string message)<br />
{<br />
WriteYellowAnnotatedLine(message, &#8220;VERBOSE&#8221;);<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void WriteWarningLine(string message)<br />
{<br />
WriteYellowAnnotatedLine(message, &#8220;WARNING&#8221;);<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        private void WriteYellowAnnotatedLine(string message, string annotation)<br />
{<br />
string output = message ?? &#8220;null&#8221;;<br />
var origFgColor = Console.ForegroundColor;<br />
var origBgColor = Console.BackgroundColor;<br />
Console.ForegroundColor = ConsoleColor.Yellow;<br />
Console.BackgroundColor = ConsoleColor.Black;<br />
WriteLine(String.Format(CultureInfo.CurrentCulture, &#8220;{0}: {1}&#8221;, annotation, output));<br />
Console.ForegroundColor = origFgColor;<br />
Console.BackgroundColor = origBgColor;<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void WriteProgress(long sourceId, ProgressRecord record)<br />
{<br />
throw new NotImplementedException();<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override Dictionary&lt;string, PSObject&gt; Prompt(string caption, string message, Collection&lt;FieldDescription&gt; descriptions)<br />
{<br />
if (String.IsNullOrEmpty(caption) &amp;&amp; String.IsNullOrEmpty(message) &amp;&amp; descriptions.Count &gt; 0)<br />
{<br />
Console.Write(descriptions[0].Name + &#8220;: &#8220;);<br />
}<br />
else<br />
{<br />
this.Write(ConsoleColor.DarkCyan, ConsoleColor.Black, caption + &#8220;\n&#8221; + message + &#8221; &#8220;);<br />
}<br />
var results = new Dictionary&lt;string, PSObject&gt;();<br />
foreach (FieldDescription fd in descriptions)<br />
{<br />
string[] label = GetHotkeyAndLabel(fd.Label);<br />
this.WriteLine(label[1]);<br />
string userData = Console.ReadLine();<br />
if (userData == null)<br />
{<br />
return null;<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">                results[fd.Name] = PSObject.AsPSObject(userData);<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            return results;<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override PSCredential PromptForCredential(string caption, string message, string userName, string targetName)<br />
{<br />
throw new NotImplementedException();<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override PSCredential PromptForCredential(string caption, string message, string userName, string targetName, PSCredentialTypes allowedCredentialTypes, PSCredentialUIOptions options)<br />
{<br />
throw new NotImplementedException();<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override int PromptForChoice(string caption, string message, Collection&lt;ChoiceDescription&gt; choices, int defaultChoice)<br />
{<br />
// Write the caption and message strings in Blue.<br />
this.WriteLine(ConsoleColor.Blue, ConsoleColor.Black, caption + &#8220;\n&#8221; + message + &#8220;\n&#8221;);</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            // Convert the choice collection into something that is<br />
// easier to work with. See the BuildHotkeysAndPlainLabels<br />
// method for details.<br />
string[,] promptData = BuildHotkeysAndPlainLabels(choices);</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            // Format the overall choice prompt string to display.<br />
var sb = new StringBuilder();<br />
for (int element = 0; element &lt; choices.Count; element++)<br />
{<br />
sb.Append(String.Format(CultureInfo.CurrentCulture, &#8220;|{0}&gt; {1} &#8220;, promptData[0, element], promptData[1, element]));<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            sb.Append(String.Format(CultureInfo.CurrentCulture, &#8220;[Default is ({0}]&#8220;, promptData[0, defaultChoice]));</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            // Read prompts until a match is made, the default is<br />
// chosen, or the loop is interrupted with ctrl-C.<br />
while (true)<br />
{<br />
this.WriteLine(sb.ToString());<br />
string data = Console.ReadLine().Trim().ToUpper(CultureInfo.CurrentCulture);</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">                // If the choice string was empty, use the default selection.<br />
if (data.Length == 0)<br />
{<br />
return defaultChoice;<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">                // See if the selection matched and return the<br />
// corresponding index if it did.<br />
for (int i = 0; i &lt; choices.Count; i++)<br />
{<br />
if (promptData[0, i] == data)<br />
{<br />
return i;<br />
}<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">                this.WriteErrorLine(&#8220;Invalid choice: &#8221; + data);<br />
}<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        #region IHostUISupportsMultipleChoiceSelection Members</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public Collection&lt;int&gt; PromptForChoice(string caption, string message, Collection&lt;ChoiceDescription&gt; choices, IEnumerable&lt;int&gt; defaultChoices)<br />
{<br />
this.WriteLine(ConsoleColor.Blue, ConsoleColor.Black, caption + &#8220;\n&#8221; + message + &#8220;\n&#8221;);</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            string[,] promptData = BuildHotkeysAndPlainLabels(choices);</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            var sb = new StringBuilder();<br />
for (int element = 0; element &lt; choices.Count; element++)<br />
{<br />
sb.Append(String.Format(CultureInfo.CurrentCulture, &#8220;|{0}&gt; {1} &#8220;, promptData[0, element], promptData[1, element]));<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            var defaultResults = new Collection&lt;int&gt;();<br />
if (defaultChoices != null)<br />
{<br />
int countDefaults = 0;<br />
foreach (int defaultChoice in defaultChoices)<br />
{<br />
++countDefaults;<br />
defaultResults.Add(defaultChoice);<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">                if (countDefaults != 0)<br />
{<br />
sb.Append(countDefaults == 1 ? &#8220;[Default choice is " : "[Default choices are ");<br />
foreach (int defaultChoice in defaultChoices)<br />
{<br />
sb.AppendFormat(CultureInfo.CurrentCulture, "\"{0}\",", promptData[0, defaultChoice]);<br />
}<br />
sb.Remove(sb.Length &#8211; 1, 1);<br />
sb.Append(&#8220;]&#8221;);<br />
}<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            this.WriteLine(ConsoleColor.Cyan, ConsoleColor.Black, sb.ToString());</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            var results = new Collection&lt;int&gt;();<br />
while (true)<br />
{<br />
ReadNext:<br />
string prompt = string.Format(CultureInfo.CurrentCulture, &#8220;Choice[{0}]:&#8221;, results.Count);<br />
this.Write(ConsoleColor.Cyan, ConsoleColor.Black, prompt);<br />
string data = Console.ReadLine().Trim().ToUpper(CultureInfo.CurrentCulture);</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">                if (data.Length == 0)<br />
{<br />
return (results.Count == 0) ? defaultResults : results;<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">                for (int i = 0; i &lt; choices.Count; i++)<br />
{<br />
if (promptData[0, i] == data)<br />
{<br />
results.Add(i);<br />
goto ReadNext;<br />
}<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">                this.WriteErrorLine(&#8220;Invalid choice: &#8221; + data);<br />
}<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        #endregion</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        private static string[,] BuildHotkeysAndPlainLabels(Collection&lt;ChoiceDescription&gt; choices)<br />
{<br />
// Allocate the result array<br />
string[,] hotkeysAndPlainLabels = new string[2, choices.Count];</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            for (int i = 0; i &lt; choices.Count; ++i)<br />
{<br />
string[] hotkeyAndLabel = GetHotkeyAndLabel(choices[i].Label);<br />
hotkeysAndPlainLabels[0, i] = hotkeyAndLabel[0];<br />
hotkeysAndPlainLabels[1, i] = hotkeyAndLabel[1];<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            return hotkeysAndPlainLabels;<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        private static string[] GetHotkeyAndLabel(string input)<br />
{<br />
string[] result = new string[] { String.Empty, String.Empty };<br />
string[] fragments = input.Split(&#8216;&amp;&#8217;);<br />
if (fragments.Length == 2)<br />
{<br />
if (fragments[1].Length &gt; 0)<br />
{<br />
result[0] = fragments[1][0].ToString().<br />
ToUpper(CultureInfo.CurrentCulture);<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">                result[1] = (fragments[0] + fragments[1]).Trim();<br />
}<br />
else<br />
{<br />
result[1] = input;<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">            return result;<br />
}<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">    class HostRawUserInterface : PSHostRawUserInterface<br />
{<br />
public override KeyInfo ReadKey(ReadKeyOptions options)<br />
{<br />
throw new NotImplementedException();<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void FlushInputBuffer()<br />
{<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void SetBufferContents(Coordinates origin, BufferCell[,] contents)<br />
{<br />
throw new NotImplementedException();<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void SetBufferContents(Rectangle rectangle, BufferCell fill)<br />
{<br />
throw new NotImplementedException();<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override BufferCell[,] GetBufferContents(Rectangle rectangle)<br />
{<br />
throw new NotImplementedException();<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override void ScrollBufferContents(Rectangle source, Coordinates destination, Rectangle clip, BufferCell fill)<br />
{<br />
throw new NotImplementedException();<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override ConsoleColor ForegroundColor<br />
{<br />
get { return Console.ForegroundColor; }<br />
set { Console.ForegroundColor = value; }<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override ConsoleColor BackgroundColor<br />
{<br />
get { return Console.BackgroundColor; }<br />
set { Console.BackgroundColor = value; }<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override Coordinates CursorPosition<br />
{<br />
get { return new Coordinates(Console.CursorLeft, Console.CursorTop); }<br />
set { Console.SetCursorPosition(value.X, value.Y); }<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override Coordinates WindowPosition<br />
{<br />
get { return new Coordinates(Console.WindowLeft, Console.WindowTop); }<br />
set { Console.SetWindowPosition(value.X, value.Y); }<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override int CursorSize<br />
{<br />
get { return Console.CursorSize; }<br />
set { Console.CursorSize = value; }<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override Size BufferSize<br />
{<br />
get { return new Size(Console.BufferWidth, Console.BufferHeight); }<br />
set { Console.SetBufferSize(value.Width, value.Height); }<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override Size WindowSize<br />
{<br />
get { return new Size(Console.WindowWidth, Console.WindowHeight); }<br />
set { Console.SetWindowSize(value.Width, value.Height); }<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override Size MaxWindowSize<br />
{<br />
get { return new Size(Console.LargestWindowWidth, Console.LargestWindowHeight); }<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override Size MaxPhysicalWindowSize<br />
{<br />
get { return new Size(Console.LargestWindowWidth, Console.LargestWindowHeight); }<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override bool KeyAvailable<br />
{<br />
get { return Console.KeyAvailable; }<br />
}</span></p>
<p><span style="font-family:Courier New;font-size:x-small;">        public override string WindowTitle<br />
{<br />
get { return Console.Title; }<br />
set { Console.Title = value; }<br />
}<br />
}<br />
}<br />
&#8216;@<br />
}    </span></p>
<p><span style="font-family:Courier New;font-size:x-small;">Process {<br />
if ($psCmdlet.ParameterSetName -eq &#8220;Path&#8221;)<br />
{<br />
# In the -Path (non-literal) case we may need to resolve a wildcarded path<br />
$resolvedPaths = @($Path | Resolve-Path | Convert-Path)<br />
}<br />
else<br />
{<br />
# Must be -LiteralPath<br />
$resolvedPaths = @($LiteralPath | Convert-Path)<br />
}</span></p>
<p>foreach ($rpath in $resolvedPaths)<br />
{<br />
Write-Verbose &#8220;Processing $rpath&#8221;</p>
<p><span style="font-family:Courier New;font-size:x-small;">        $gzItem = Get-ChildItem $rpath | Write-GZip -Quiet<br />
$resourcePath = &#8220;$($gzItem.Directory)\Resources.Script.ps1.gz&#8221;<br />
if (Test-Path $resourcePath) { Remove-Item $resourcePath }<br />
Rename-Item $gzItem $resourcePath</span></p>
<p># Configure the compiler parameters<br />
$referenceAssemblies = &#8216;System.dll&#8217;,([psobject].Assembly.Location)<br />
$outputPath = $OutputAssembly<br />
if (![IO.Path]::IsPathRooted($outputPath))<br />
{<br />
$outputPath = [io.path]::GetFullPath((Join-Path $pwd $outputPath))<br />
}<br />
if ($rpath -eq $outputPath)<br />
{<br />
throw &#8216;Oops, you don&#8221;t really want to overwrite your script with an EXE.&#8217;<br />
}</p>
<p><span style="font-family:Courier New;font-size:x-small;">        $cp = new-object System.CodeDom.Compiler.CompilerParameters $referenceAssemblies,$outputPath,$true<br />
$cp.TempFiles = new-object System.CodeDom.Compiler.TempFileCollection ([IO.Path]::GetTempPath())<br />
$cp.GenerateExecutable = $true<br />
$cp.GenerateInMemory   = $false<br />
$cp.IncludeDebugInformation = $true<br />
if ($IconPath)<br />
{<br />
$rIconPath = Resolve-Path $IconPath<br />
$cp.CompilerOptions = &#8221; /win32icon:$rIconPath&#8221;<br />
}<br />
[void]$cp.EmbeddedResources.Add($resourcePath)</span></p>
<p># Create the C# codedom compiler<br />
$dict = new-object &#8216;System.Collections.Generic.Dictionary[string,string]&#8216;<br />
$dict.Add(&#8216;CompilerVersion&#8217;,'v3.5&#8242;)<br />
$provider = new-object Microsoft.CSharp.CSharpCodeProvider $dict</p>
<p># Compile the source and report errors<br />
$results = $provider.CompileAssemblyFromSource($cp, $src)<br />
if ($results.Errors.Count)<br />
{<br />
$errorLines = &#8220;&#8221;<br />
foreach ($error in $results.Errors)<br />
{<br />
$errorLines += &#8220;`n`t&#8221; + $error.Line + &#8220;:`t&#8221; + $error.ErrorText<br />
}<br />
Write-Error $errorLines<br />
}<br />
}<br />
}</p>
</div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rkeithhill.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rkeithhill.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rkeithhill.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rkeithhill.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rkeithhill.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rkeithhill.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rkeithhill.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rkeithhill.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rkeithhill.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rkeithhill.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rkeithhill.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rkeithhill.wordpress.com/4/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rkeithhill.wordpress.com/4/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rkeithhill.wordpress.com/4/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=4&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rkeithhill.wordpress.com/2010/09/21/make-ps1exewrapper/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/bcc517cd604f90500c5dcef5a6ed7f81?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rkeithhill</media:title>
		</media:content>
	</item>
		<item>
		<title>Determining $ScriptDir Safely</title>
		<link>http://rkeithhill.wordpress.com/2010/09/19/determining-scriptdir-safely/</link>
		<comments>http://rkeithhill.wordpress.com/2010/09/19/determining-scriptdir-safely/#comments</comments>
		<pubDate>Sun, 19 Sep 2010 06:47:37 +0000</pubDate>
		<dc:creator>rkeithhill</dc:creator>
				<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://rkeithhill.wordpress.com/2010/09/19/determining-scriptdir-safely</guid>
		<description><![CDATA[We had some boiler plate code that we always put into our scripts to set strict mode and to compute $ScriptDir so the script can load other scripts relatively to its location.  This boiler plate code is simple: #requires –Version &#8230; <a href="http://rkeithhill.wordpress.com/2010/09/19/determining-scriptdir-safely/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=5&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div id="msgcns!5A8D2641E0963A97!7226" class="bvMsg">
<p>We had some boiler plate code that we always put into our scripts to set strict mode and to compute $ScriptDir so the script can load other scripts relatively to its location.  This boiler plate code is simple:</p>
<p><font face="Consolas">#requires –Version 2.0<br />Set-StrictMode –Version 2.0<br />$ScriptDir = Split-Path $MyInvocation.MyCommand.Path –Parent</font></p>
<p>However lets say you do this in all your scripts and one script (Parent.ps1) dot-sources another script (PoshLib.ps1) that does the same trick e.g.:</p>
<p><strong>Parent.ps1:<br /></strong><font face="Consolas">$ScriptDir = Split-Path $MyInvocation.MyCommand.Path –Parent<br />&quot;PARENT:  Before dot-sourcing libary ScriptDir is $ScriptDir&quot;<br />. $ScriptDir\Bin\PoshLib.ps1<br />&quot;PARENT:  After dot-sourcing libary ScriptDir is $ScriptDir&quot;</font></p>
<p><strong>PoshLib.ps1<br /></strong><font face="Consolas">$ScriptDir = Split-Path $MyInvocation.MyCommand.Path –Parent<br />&quot;POSHLIB: ScriptDir is $ScriptDir&quot;</font></p>
<p>Seems innocent enough but check out the output of running Parent.ps1:</p>
<p><font face="Consolas">PS C:\Users\Keith&gt; C:\Users\Keith\Parent.ps1<br />PARENT:  Before dot-sourcing libary ScriptDir is C:\Users\Keith<br />POSHLIB: ScriptDir is C:\Users\Keith\Bin<br />PARENT:  After dot-sourcing libary ScriptDir is C:\Users\Keith\Bin</font></p>
<p>What happens here is that because we are “dot sourcing” PoshLib.ps1 into Parent.ps1, its definition of the $ScriptDir variable stomps the one created in Parent.ps1.  Obviously this won’t do.  You could try to create unique variable names for each script but that isn’t ideal and not very maintainable.  </p>
<p>The best answer if you are on PowerShell 2.0 is to just use modules for your libraries.  Modules can have “private” variables that don’t get exported so the variable “stomping” issue never arises.  However, for various reasons, folks can’t always upgrade to PowerShell 2.0.  So here is how you can fix this issue on PowerShell 1.0.  </p>
<p>Essentially what you want to do is to dynamically evaluate the script’s location every time without having to use the longhand:</p>
<p><font face="Consolas">Split-Path $MyInvocation.MyCommand.Path –Parent</font></p>
<p>PowerShell allows us to create a shorthand for this using an anonymous scriptblock assigned to a variable like so:</p>
<p><strong>Parent.ps1:<br /></strong><font face="Consolas">$ScriptDir = &#123; Split-Path $MyInvocation.ScriptName –Parent &#125;<br />&quot;PARENT:  Before dot-sourcing libary ScriptDir is $(&amp;$ScriptDir)&quot;<br />. &quot;$(&amp;$ScriptDir)\Bin\PoshLib.ps1&quot;<br />&quot;PARENT:  After dot-sourcing libary ScriptDir is $(&amp;$ScriptDir)&quot;</font></p>
<p><strong>PoshLib.ps1<br /></strong><font face="Consolas">$ScriptDir = &#123; Split-Path $MyInvocation.ScriptName –Parent &#125;<br />&quot;POSHLIB: ScriptDir is $(&amp;$ScriptDir)&quot;</font></p>
<p>Note: that once we put the code within the scriptblock we need to switch from $MyInvocation.MyCommand.Path to $MyInvocation.ScriptName.  These changes yield the desired results:</p>
<p><font face="Consolas">PS C:\Users\Keith&gt; C:\Users\Keith\Parent.ps1<br />PARENT:  Before dot-sourcing libary ScriptDir is C:\Users\Keith<br />POSHLIB: ScriptDir is C:\Users\Keith\Bin<br />PARENT:  After dot-sourcing libary ScriptDir is C:\Users\Keith</font></p>
</p></div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rkeithhill.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rkeithhill.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rkeithhill.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rkeithhill.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rkeithhill.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rkeithhill.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rkeithhill.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rkeithhill.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rkeithhill.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rkeithhill.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rkeithhill.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rkeithhill.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rkeithhill.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rkeithhill.wordpress.com/5/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=5&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rkeithhill.wordpress.com/2010/09/19/determining-scriptdir-safely/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/bcc517cd604f90500c5dcef5a6ed7f81?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rkeithhill</media:title>
		</media:content>
	</item>
		<item>
		<title>Quickly checking if a problem is a PowerShell problem or a module/snapin/proxy-function problem.</title>
		<link>http://rkeithhill.wordpress.com/2010/09/18/quickly-checking-if-a-problem-is-a-powershell-problem-or-a-modulesnapinproxy-function-problem/</link>
		<comments>http://rkeithhill.wordpress.com/2010/09/18/quickly-checking-if-a-problem-is-a-powershell-problem-or-a-modulesnapinproxy-function-problem/#comments</comments>
		<pubDate>Sun, 19 Sep 2010 01:51:24 +0000</pubDate>
		<dc:creator>rkeithhill</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://rkeithhill.wordpress.com/2010/09/18/quickly-checking-if-a-problem-is-a-powershell-problem-or-a-modulesnapinproxy-function-problem</guid>
		<description><![CDATA[We all tend to customize our PowerShell environment via our Profile.ps1 script.  Whether we load up snapins, modules, our own functions, etc.  And with PowerShell 2.0, you can even “proxy” cmdlets such that you get to intercept calls to cmdlets &#8230; <a href="http://rkeithhill.wordpress.com/2010/09/18/quickly-checking-if-a-problem-is-a-powershell-problem-or-a-modulesnapinproxy-function-problem/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=6&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div id="msgcns!5A8D2641E0963A97!7225" class="bvMsg">
<p>We all tend to customize our PowerShell environment via our Profile.ps1 script.  Whether we load up snapins, modules, our own functions, etc.  And with PowerShell 2.0, you can even “proxy” cmdlets such that you get to intercept calls to cmdlets like Get-Help and add parameters and augment its functionality. Sometimes though this can cause problems.  And it isn’t always easy to determine if the problem is with PowerShell or one of these add-ins.  When I run into these situations I fire up a PowerShell with no profile to help determine where the problem actually lies.  This is what I execute:</p>
<p><font size="2" face="Consolas">C:\PS&gt; PowerShell –noprofile</font></p>
<p>Often I prefer to have PowerShell fire up in a different window so I use Start-Process.  And because I do this so often (testing PSCX), I’ve created a function that I put in my profile to provide a convenient shortcut to fire up PowerShell with no profile:</p>
<p><font size="2" face="Consolas">function psnp &#123; Start-Process PowerShell.exe -Arg -noprofile &#125;</font><font size="2" face="Consolas"></font></p>
</p></div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rkeithhill.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rkeithhill.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rkeithhill.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rkeithhill.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rkeithhill.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rkeithhill.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rkeithhill.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rkeithhill.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rkeithhill.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rkeithhill.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rkeithhill.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rkeithhill.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rkeithhill.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rkeithhill.wordpress.com/6/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=6&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rkeithhill.wordpress.com/2010/09/18/quickly-checking-if-a-problem-is-a-powershell-problem-or-a-modulesnapinproxy-function-problem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/bcc517cd604f90500c5dcef5a6ed7f81?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rkeithhill</media:title>
		</media:content>
	</item>
		<item>
		<title>Get-TfsPermssion–Missing command from Team Foundation Power Tools PowerShell Snapin</title>
		<link>http://rkeithhill.wordpress.com/2010/07/06/get-tfspermssion%e2%80%93missing-command-from-team-foundation-power-tools-powershell-snapin/</link>
		<comments>http://rkeithhill.wordpress.com/2010/07/06/get-tfspermssion%e2%80%93missing-command-from-team-foundation-power-tools-powershell-snapin/#comments</comments>
		<pubDate>Tue, 06 Jul 2010 20:01:02 +0000</pubDate>
		<dc:creator>rkeithhill</dc:creator>
				<category><![CDATA[PowerShell 2.0]]></category>

		<guid isPermaLink="false">http://rkeithhill.wordpress.com/2010/07/06/get-tfspermssion%e2%80%93missing-command-from-team-foundation-power-tools-powershell-snapin</guid>
		<description><![CDATA[The TFPT PowerShell snapin is a nice start but it is missing a key cmdlet IMO and that is Get-TfsPermission.  Since TFS allows you to add individual users all over your directory structure, it can be quite hard rationalizing exactly &#8230; <a href="http://rkeithhill.wordpress.com/2010/07/06/get-tfspermssion%e2%80%93missing-command-from-team-foundation-power-tools-powershell-snapin/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=7&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div id="msgcns!5A8D2641E0963A97!7223" class="bvMsg">
<p>The TFPT PowerShell snapin is a nice start but it is missing a key cmdlet IMO and that is Get-TfsPermission.  Since TFS allows you to add individual users all over your directory structure, it can be quite hard rationalizing exactly who has access to what without traversing a bunch of directories in the Team Foundation client’s Source Control window, opening the Properties dialog and inspecting the Security settings.  Fortunately there is also a command line way to do this via TFS’s tf.exe utility.  Unfortunately the output of this command is just text and what’s worse is that this text is a pain to query over using PowerShell’s built-in querying cmdlets.  So I wrote the following function to convert this text into objects which enables easier querying:</p>
<p><font face="Consolas">&lt;#<br />.SYNOPSIS<br />    Gets the Team Foundation server permissions for items based on the specified paths.<br />.DESCRIPTION<br />    Gets the Team Foundation server permissions for items based on the specified paths and outputs rich<br />    objects as opposed to text.<br />.PARAMETER Path<br />    The path to the Team Foundation server item.<br />.PARAMETER LiteralPath<br />    Specifies a path to one or more locations. Unlike Path, the value of LiteralPath is used exactly as it <br />    is typed. No characters are interpreted as wildcards. If the path includes escape characters, enclose <br />    it in single quotation marks. Single quotation marks tell Windows PowerShell not to interpret any <br />    characters as escape sequences.<br />.PARAMETER Recurse<br />    Gets permissions for the items at the specified location and in all child locations.<br />.EXAMPLE<br />    C:\PS&gt; Get-TfsPermission C:\Tfs\Acme\Branches\Release\3.7 | Select ServerItem -exp Identities<br />    Get the permissions for the specified folder and expands the Identities array to show each identity.<br />    The server item corresponding to each identity object is tagged onto the object.<br />.EXAMPLE<br />    C:\PS&gt; Get-TfsPermission C:\Tfs\Acme | Select ServerItem -expand Identities | Where &#123;$_.Allow -match &#8216;Checkin&#8217; &#125; | Format-List ServerItem,Identity,Allow,Deny    <br />    This command looks for items where the &#8216;checkin&#8217; privilege has been granted locally.<br />.NOTES<br />    Author: Keith Hill<br />    Date:   June 28, 2010    <br />#&gt;<br />function Get-TfsPermission<br />&#123;<br />    [CmdletBinding(DefaultParameterSetName=&quot;Path&quot;)]<br />    param(<br />        [Parameter(Mandatory=$true, Position=0, ParameterSetName=&quot;Path&quot;, <br />                   ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true,<br />                   HelpMessage=&quot;Path to workspace item&quot;)]<br />        [ValidateNotNullOrEmpty()]<br />        [string[]]<br />        $Path,<br />        <br />        [Alias(&quot;PSPath&quot;)]<br />        [Parameter(Mandatory=$true, Position=0, ParameterSetName=&quot;LiteralPath&quot;, <br />                   ValueFromPipelineByPropertyName=$true,<br />                   HelpMessage=&quot;Path to workspace item&quot;)]<br />        [ValidateNotNullOrEmpty()]<br />        [string[]]<br />        $LiteralPath,<br />        <br />        [Parameter()]<br />        [switch]<br />        $Recurse<br />    )</font></p>
<p><font face="Consolas">    Begin <br />    &#123;<br />        Set-StrictMode -Version Latest <br />        $item = $null<br />    &#125;</font></p>
<p><font face="Consolas">    Process<br />    &#123;<br />        if ($psCmdlet.ParameterSetName -eq &quot;Path&quot;)<br />        &#123;<br />            # In the -Path (non-literal) case we may need to resolve a wildcarded path<br />            $resolvedPaths = @($Path | Resolve-Path | Convert-Path)<br />        &#125;<br />        else <br />        &#123;<br />            # Must be -LiteralPath<br />            $resolvedPaths = @($LiteralPath | Convert-Path)<br />        &#125;<br />     <br />        foreach ($rpath in $resolvedPaths) <br />        &#123;<br />            Write-Verbose &quot;Processing $rpath&quot;<br />            <br />            $tfargs = &#8221;<br />            $tfargs += if ($Recurse) &#123; &#8216;/r&#8217; &#125;<br />            <br />            # Look at each line of TF PERMISSION output and use a regex to determine <br />            # what the data for the line is.<br />            switch -regex (tf permission $rpath $tfargs)<br />            &#123;<br />                &#8216;^Server item:\s+(\S+)\s+\(Inherit:\s+(\w+)\)&#8217; <br />                &#123; <br />                    # If previous object exists, output it before creating a new one<br />                    if ($item) &#123; $item &#125;<br />                    $item = new-object psobject  -property @&#123;<br />                        ServerItem = $matches[1]<br />                        Inherits   = $matches[2] -eq &#8216;yes&#8217;<br />                        Identities = @()<br />                    &#125;<br />                    $item.psobject.TypeNames[0] = &quot;TfsTools.VersionControl.ItemPermissions&quot;   <br />                &#125;<br />                <br />                &#8216;\bIdentity:\s+(.*)$&#8217;   <br />                &#123;<br />                    $identityName = $matches[1] <br />                    $currentIdentity = new-object psobject -property @&#123;<br />                        Identity = $identityName<br />                        Allow = &#8221;<br />                        Deny = &#8221;<br />                        InheritedAllow = &#8221;<br />                        InheritedDeny = &#8221;<br />                    &#125;<br />                    $item.Identities += $currentIdentity<br />                &#125;<br />                <br />                &#8216;\bAllow:\s*(.*)$&#8217;      <br />                &#123; <br />                    $currentIdentity.Allow = $matches[1]<br />                &#125;<br />                <br />                &#8216;\bDeny:\s*(.*)$&#8217;       <br />                &#123; <br />                    $currentIdentity.Deny = $matches[1]<br />                &#125;<br />                <br />                &#8216;\bAllow\s+\(Inherited\)\s*:\s*(.*)$&#8217;      <br />                &#123; <br />                    $currentIdentity.InheritedAllow = $matches[1]<br />                &#125;<br />                <br />                &#8216;\bDeny\s+\(Inherited\)\s*:\s*(.*)$&#8217;       <br />                &#123; <br />                    $currentIdentity.InheritedDeny = $matches[1]<br />                &#125;            <br />            &#125;<br />        &#125;<br />    &#125;</font></p>
<p><font face="Consolas">    End<br />    &#123;<br />        # Output the very last object<br />        if ($item) &#123; $item &#125;<br />    &#125;<br />&#125;</font></p>
<p>The output of this function isn’t great for viewing since it is primarily intended to enable querying of the permission info on each server item.  Note to the Team Foundation Power Tools devs, it sure would be nice to get this functionality into a future TFPT drop.</p>
</p></div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rkeithhill.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rkeithhill.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rkeithhill.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rkeithhill.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rkeithhill.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rkeithhill.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rkeithhill.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rkeithhill.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rkeithhill.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rkeithhill.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rkeithhill.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rkeithhill.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rkeithhill.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rkeithhill.wordpress.com/7/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=7&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rkeithhill.wordpress.com/2010/07/06/get-tfspermssion%e2%80%93missing-command-from-team-foundation-power-tools-powershell-snapin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/bcc517cd604f90500c5dcef5a6ed7f81?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rkeithhill</media:title>
		</media:content>
	</item>
		<item>
		<title>Handling Native EXE Output Encoding in UTF8 with No BOM</title>
		<link>http://rkeithhill.wordpress.com/2010/05/26/handling-native-exe-output-encoding-in-utf8-with-no-bom/</link>
		<comments>http://rkeithhill.wordpress.com/2010/05/26/handling-native-exe-output-encoding-in-utf8-with-no-bom/#comments</comments>
		<pubDate>Thu, 27 May 2010 01:27:55 +0000</pubDate>
		<dc:creator>rkeithhill</dc:creator>
				<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://rkeithhill.wordpress.com/2010/05/26/handling-native-exe-output-encoding-in-utf8-with-no-bom</guid>
		<description><![CDATA[If you are dealing with an native executable that outputs UTF8 with no BOM (byte order marker) you will find that PowerShell garbles the input.  This is most likely an issue with how the .NET console code interprets the incoming &#8230; <a href="http://rkeithhill.wordpress.com/2010/05/26/handling-native-exe-output-encoding-in-utf8-with-no-bom/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=8&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div id="msgcns!5A8D2641E0963A97!7212" class="bvMsg">
<div>If you are dealing with an native executable that outputs UTF8 with no <a href="http://en.wikipedia.org/wiki/Byte-order_mark">BOM</a> (byte order marker) you will find that PowerShell garbles the input.  This is most likely an issue with how the .NET console code interprets the incoming byte stream.  Without a BOM it isn’t exactly easy to <a href="http://blogs.msdn.com/b/oldnewthing/archive/2007/04/17/2158334.aspx">determine the proper encoding for a stream of bytes</a>.  For example take the following simple native exe source code that is supposed to output this (BTW ignore the fact that the text says ‘ASCII’ – it is really UTF8):</div>
<pre>ASCII outputᾹ</pre>
<div>Contents of stdout.cpp:</div>
<pre>#include &lt;stdio.h&gt;

main()
{
    bytes[] = { 0x41, 0x53, 0x43, 0x49,
                0x49, 0x20, 0x6F, 0x75,
                0xE1, 0xBE, 0xB9};

    for (int i = 0; i &lt; 15; i++)
    {
        printf("%c", bytes[i]);
    }
}</pre>
<div>If you pipe the output of this program into a <a href="http://pscx.codeplex.com">PSCX</a> utility called Format-Hex (alias is fhex), you can see the actual unicode byte stream that was created by .NET’s interpretation of the incoming byte stream.</div>
<pre><strong><span style="color:gray;">PS&gt;</span></strong><span style="color:black;"> .\stdout.exe | fhex</span>

Address:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F ASCII
-------- ----------------------------------------------- ----------------
00000000 41 00 53 00 43 00 49 00 49 00 20 00 6F 00 75 00 A.S.C.I.I. .o.u.
00000010 74 00 70 00 75 00 74 00 DF 00 5B 25 63 25       t.p.u.t...[%c%</pre>
<div>You might think you could pipe the output to Out-File –Encoding Utf8 but by the time the .NET strings hit the Out-File cmdlet the damage is already done.  As can be seen if you view the subsequent output in Notepad.exe:</div>
<pre>ASCII outputß╛╣</pre>
<div>The solution to this problem is to provide a hint to the .NET console functionality about the encoding of the incoming bytes.  You can do this very simply:</div>
<pre><strong><span style="color:gray;">PS&gt;</span></strong><span style="color:black;"><em> </em>[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8</span></pre>
<div>And it works:</div>
<pre><strong><span style="color:gray;">6&gt;</span></strong><span style="color:black;"><em> </em>.\stdout.exe | fhex</span>

Address:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F ASCII
-------- ----------------------------------------------- ----------------
00000000 41 00 53 00 43 00 49 00 49 00 20 00 6F 00 75 00 A.S.C.I.I. .o.u.
00000010 74 00 70 00 75 00 74 00 B9 1F                   t.p.u.t...

<strong><span style="color:gray;">7&gt;</span></strong><span style="color:black;"><em> </em>.\stdout.exe | Out-File good.txt -Encoding UTF8</span></pre>
<div>If you open good.txt in notepad you get:</div>
<pre>ASCII outputᾹ</pre>
<div>And is as it should be.  However this may seem somewhat counter-intuitive (it did to me) since the problem is with PowerShell/.NET “reading” console input and not writing it.  Well one of the good folks on the PowerShell team pointed out to me that the Console OutputEncoding is probably inherited by child processes and a quick little experiment reveals this to be true.  So by setting the OutputEncoding this determines how .NET encodes console output which helps PowerShell/.NET determine the correct encoding when reading in this information via console input.</div>
<div>One last point on this approach is that you should stash the original value of [Console]::OutputEncoding and restore it after you’ve run a problematic exe like in this example.  I’ve found that the C# compiler will crash if you run it in PowerShell with the [Console]::OutputEncoding set to UTF8.</div>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/rkeithhill.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rkeithhill.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/rkeithhill.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rkeithhill.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/rkeithhill.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/rkeithhill.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/rkeithhill.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/rkeithhill.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/rkeithhill.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rkeithhill.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/rkeithhill.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rkeithhill.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/rkeithhill.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rkeithhill.wordpress.com/8/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rkeithhill.wordpress.com&amp;blog=18780344&amp;post=8&amp;subd=rkeithhill&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://rkeithhill.wordpress.com/2010/05/26/handling-native-exe-output-encoding-in-utf8-with-no-bom/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/bcc517cd604f90500c5dcef5a6ed7f81?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">rkeithhill</media:title>
		</media:content>
	</item>
	</channel>
</rss>
