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

<channel>
	<title>Huddled Masses &#187; PowerShell</title>
	<atom:link href="http://huddledmasses.org/tag/powershell/feed/" rel="self" type="application/rss+xml" />
	<link>http://huddledmasses.org</link>
	<description>You can do more than breathe for free...</description>
	<lastBuildDate>Tue, 31 Aug 2010 04:13:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
<cloud domain='huddledmasses.org' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
		<item>
		<title>RFC: Information in PoshCode Module Manifests</title>
		<link>http://huddledmasses.org/rfc-information-in-poshcode-module-manifests/</link>
		<comments>http://huddledmasses.org/rfc-information-in-poshcode-module-manifests/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 03:31:25 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Module Manifest]]></category>
		<category><![CDATA[PoshCode]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://huddledmasses.org/?p=1530</guid>
		<description><![CDATA[OK, I&#8217;m putting this out there to see if I&#8217;ve missed anything that would be useful. This is the list of metadata that we&#8217;ll be storing about Modules in the PoshCode repository. It duplicates most of the information in the PowerShell Manifests, but it adds more of information that we feel is important for searching, [...]]]></description>
			<content:encoded><![CDATA[	<p>OK, I&#8217;m putting this out there to see if I&#8217;ve missed anything that would be useful.  This is the list of metadata that we&#8217;ll be storing about Modules in the PoshCode repository. It duplicates most of the information in the PowerShell Manifests, but it adds more of information that we feel is important for searching, sorting and organizing &#8230; and in the PoshCode Module manifests, wildcards are not allowed for any of the &#8220;export&#8221; values.  The export information in the module is intended to represent the initial state of the module after import: listing all the cmdlets, functions, variables and aliases &#8230;</p>

	<h2>PoshCode Module Manifest Format:</h2>

	<h4><span class="caps">GUID</span></h4>

	<p>The globally unique identifier for this module. Helps us tell modules apart  <img src='http://huddledmasses.org/wordpress/wp-includes/images/smilies/../../../wp-content/plugins/smilingmasses/smile.gif' alt=':)' class='wp-smiley' /> </p>

	<h4>Name</h4>

	<p>The name of this module. Helps us find modules, and helps you guess what they&#8217;re for.</p>

	<h4>ModuleVersion</h4>

	<p>The version of this module.  Together with the <span class="caps">GUID</span>, this is the unique key for the module. It should be incremented whenever you release it.</p>

	<h4>Description</h4>

	<p>A short description of the module. What it is, what it does, what it&#8217;s for.</p>

	<h4>ModuleType</h4>

	<p>Tells whether the module is a Script module or a Binary module (if they are both, then they are Binary).</p>

	<h4>Author</h4>

	<p>The <strong>person(s)</strong> who created this module. No organizations here, just people.</p>

	<h4>Company</h4>

	<p>A company (if there is one) that created this module or provides support for it.</p>

	<h4>Copyright</h4>

	<p>The copyright statement. You should always fill this out and assign copyright to the correct author, group or corporation.</p>

	<h4>License</h4>

	<p>The software license(s) that this module can be licensed under. It&#8217;s enough to use an acronym like &#8220;<span class="caps">GPL</span> v2&#8221; or &#8220;MIT&#8221; or &#8220;Ms-PL&#8221; ... but if you have a custom license you can specify a description of it or the full text of it. Multiple entries are allowed.</p>

	<h4>LicenseUri</h4>

	<p>The url(s) for a full copy of the license. If you&#8217;re using an open source license you can link to it&#8217;s page on <a href="http://opensource.org/licenses/">opensource.org</a></p>

	<h4>Category</h4>

	<p>We&#8217;ll publish our official category list later, but the category is intended to be an assignment to a single category in a hierarchical tree. </p>

	<h4>Tags</h4>

	<p>A collection of user-assigned free-text keywords that help to categorize the module and serve as additional search terms.</p>

	<h4>Homepage</h4>

	<p>If the module has a home page on the internet, this is the <span class="caps">URL</span>. You can use the link to the PoshCode Docs page (which our cmdlets will generate for you) if you don&#8217;t have your own page.</p>

	<h4>Download</h4>

	<p>This is the link to download the module. If you&#8217;re hosting it on PoshCode, we will fill this in. If you&#8217;re hosting it elsewhere, this must be a <strong>download</strong> link. If it&#8217;s a commercial module that requires payment, you should leave this link empty unless you have a free trial download.  Note: I&#8217;m still working on the commercial angle.  Would it be helpful to include the price here? If we offered a way to sell your modules through PoshCode, would you use it?</p>

	<h4>RequiredAssemblies</h4>

	<p>Assembly names (or relative paths, if the assemblies are included in the module folder) for assemblies that must be loaded before the module will work. These should be the Assembly FullName, not a partial name.</p>

	<h4>RequiredModules</h4>

	<p>The names and versions (and GUIDs) of any modules that this module depends on.</p>

	<h4>PowerShellVersion</h4>

	<p>The version of Powershell required (2.0, for now).</p>

	<h4>FrameworkVersion</h4>

	<p>The version of the .Net Framework required. The framework version implies the <span class="caps">CLR</span> version, so we&#8217;ll just stick to this.  I&#8217;m still toying with the idea of saying the list is 2.0, 3.0, 3.5, 3.5.1, and 4.0 &#8230; rather than allowing the normal version with the full four digits.</p>

	<h4>VersionChanges</h4>

	<p>This is either the list of changes in this version, or a complete list of the changes in previous versions.</p>

	<h4>Exported Cmdlets</h4>

	<p>The list of (binary) cmdlets exported by this module.</p>

	<h4>Exported Functions</h4>

	<p>The list of script functions exported by this module.</p>

	<h4>Exported Aliases</h4>

	<p>The list of aliases exported by this module.</p>

	<h4>Exported Variables</h4>

	<p>The list of variables exported by this module.</p>

	<h3>Deprecated things &#8230;</h3>

	<p>I&#8217;m leaning against having these items in the PoshCode manifest &#8212; they don&#8217;t seem to be helpful for finding or sorting or understanding a module.</p>

	<ul>
		<li>ModuleFile</li>
		<li>ModuleToProcess</li>
		<li>FormatsToProcess</li>
	</ul>
	<ul>
		<li>TypesToProcess</li>
	</ul>

	<h2>Comments Requested</h2>

	<p>I&#8217;m hoping for feedback about this list, what I might be missing, or if there&#8217;s anything in here I should leave out &#8230;  let me hear it!</p>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/rfc-information-in-poshcode-module-manifests/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>What Scope Am I In?</title>
		<link>http://huddledmasses.org/what-scope-am-i-in/</link>
		<comments>http://huddledmasses.org/what-scope-am-i-in/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 06:28:11 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[PowerUser]]></category>
		<category><![CDATA[Scope]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Variable Scope]]></category>

		<guid isPermaLink="false">http://huddledmasses.org/?p=1523</guid>
		<description><![CDATA[In PowerShell the question of scope is too complicated and convoluted. I&#8217;m going to try to help you understand it, but I&#8217;m not guaranteeing that I will be able to make it seem any simpler than it actually is. Hopefully, I won&#8217;t make it more complicated than it inherently is In PowerShell you always have [...]]]></description>
			<content:encoded><![CDATA[	<p>In PowerShell the question of scope is too complicated and convoluted. I&#8217;m going to try to help you understand it, but I&#8217;m not guaranteeing that I will be able to make it seem any simpler than it actually is. Hopefully, I won&#8217;t make it more complicated than it inherently is  <img src='http://huddledmasses.org/wordpress/wp-includes/images/smilies/../../../wp-content/plugins/smilingmasses/wink.gif' alt=';-)' class='wp-smiley' /> </p>

	<p>In PowerShell you always have three named variable scopes: script, local and global. The default scope is always <strong>the same</strong> as the local scope, so when you set a variable without specifying the scope, it&#8217;s always set at local scope. One thing to note is that you can access these named scopes through the <code>$variable</code> notation, or through the variable drive, so all of the following are equivalent:</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #0066cc; font-style: italic;">Set-<span style="font-style: normal;">Variable</span></span> <span style="color: #666699; font-weight: bold;">var</span> <span style="color: #009900;">&quot;one&quot;</span> <span style="color: #000066;">-Scope</span> Local<br />
<span style="color: #660033; font-weight: bold;">$var</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;one&quot;</span><br />
<span style="color: #660033; font-weight: bold;">$local</span>:<span style="color: #666699; font-weight: bold;">var</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;one&quot;</span><br />
<span style="color: #0066cc; font-style: italic;">Set-<span style="font-style: normal;">Content</span></span> Variable::<span style="color: #003366;">Local</span>:<span style="color: #666699; font-weight: bold;">Var</span> <span style="color: #009900;">&quot;one&quot;</span><br />
&nbsp;</div>

	<p>A side note: the PSProvider drive notation means that when you&#8217;re in strict mode, if you want to test for the existence of a variable without causing an error, the simplest way to do it is with <code>Test-Path Variable:Var</code>&#8230;</p>

	<h3>What&#8217;s so hard about that?</h3>

	<p>Well, the question is: what scope are you in &#8220;right now&#8221; when a line of code is executing from a function or a script &#8230; </p>

	<p>Sometimes local scope is <span class="caps">ALSO</span> script scope, and sometimes, script scope is also global scope.  Specifically: when you&#8217;re typing at the console, all three scopes are the same. </p>

	<p>Let&#8217;s write a function to determine what named scope we&#8217;re in: </p>

	<p><script lang="posh"><br />
function Get-Scope {
   New-Variable scope_test
   Write-Output @{
      $GlobalScope = [bool](Get-Variable scope_test -Scope global -ea 0)
      $ScriptScope = [bool](Get-Variable scope_test -Scope script -ea 0)
      $LocalScope = $true
   }<br />
}<br />
</script></p>

	<p>By setting a variable, and then testing the named scopes, we can verify what scope we were in when we set the variable. Of course, there&#8217;s no point testing the Local scope, because we already know that is where we are&#8230; then we return a hashtable of booleans indicating which scopes are active.</p>

	<p>If you dot-source that Get-Scope function, you&#8217;ll find the scope that you&#8217;re in where you dot-source it:</p>

	<ul>
		<li>if you do it at the interactive prompt it should tell you all three scopes are set</li>
		<li>if you do it in a script file it should tell you Local and Script</li>
		<li>but if you do it in a function, it will always just tell you &#8220;local&#8221; &#8212; and will not tell you if the function is in a script or not &#8230; nor how deep you are.</li>
	</ul>
	<ul>
		<li>and if you do it in a module, the results will depend on whether Find-Scope is defined in the module or not (this is very weird)</li>
	</ul>

	<h3>So are we done?</h3>

	<p>Not even remotely. On top of the named scopes, PowerShell also has nested scopes. Each script, function, scriptblock, etc. adds to the nested scopes, and takes you further from the global scope. On top of that, PowerShell has Modules. In a module, scope is flattened. Specifically, in a module, the default scope becomes the Script scope, which in this case is not actually reserved for a single file, but for any scripts, functions, etc that are executed from within that module&#8217;s context.</p>

	<p>To determine nesting level of the scope, we must do something like this:</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #666699; font-weight: bold;">function</span> <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">ScopeDepth</span></span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">trap</span> <span style="color: #333;">&#123;</span> <span style="color: #666699; font-weight: bold;">continue</span> <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$depth</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">do</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Set-<span style="font-style: normal;">Variable</span></span> scope_test <span style="color: #000066;">-Scope</span> <span style="color: #333;">&#40;</span><span style="color: #66cc66;">++</span><span style="color: #660033; font-weight: bold;">$depth</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span> <span style="color: #666699; font-weight: bold;">while</span><span style="color: #333;">&#40;</span>$?<span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">return</span> <span style="color: #660033; font-weight: bold;">$depth</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><br />
<span style="color: #333;">&#125;</span><br />
<br />
<span style="color: #666666; font-style: italic;"># Test it like this:</span><br />
. <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">ScopeDepth</span></span><br />
<span style="color: #66cc66;">&amp;</span><span style="color: #333;">&#123;</span> . <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">ScopeDepth</span></span> <span style="color: #333;">&#125;</span><br />
<span style="color: #66cc66;">&amp;</span><span style="color: #333;">&#123;</span> <span style="color: #66cc66;">&amp;</span><span style="color: #333;">&#123;</span> . <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">ScopeDepth</span></span> <span style="color: #333;">&#125;</span> <span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>As long as modules aren&#8217;t involved, that will tell you how many scopes there are between you and global scope (and thus, return zero when dot-source from the console commandline).</p>

	<p>This falls apart a bit if you&#8217;re in a module (in a module, you can&#8217;t get to global scope by increasing the scope value &#8212; effectively, the highest you can go is script scope, but in reality you can still access global scope by naming it). To determine if you&#8217;re in a module, you can simply check for the existence of the <code>$PSScriptRoot</code> variable, or verify that <code>$Invocation.MyCommand.Module</code> is set to something.</p>

	<p>Additionally, if you&#8217;re in a module, you need to define this function <strong>in that module</strong> for it to work at all.</p>

	<p>There&#8217;s one more thing you could use to help you learn what scope you&#8217;re in, and that is the Get-PSCallStack cmdlet. This will tell you how many commands have been called to get you where you are. It&#8217;s <em>usually</em> the same as the Scope Depth, but not when it&#8217;s in a script file, etc.</p>

	<p>Here&#8217;s my finished scope digging function:</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #666699; font-weight: bold;">function</span> <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Scope</span></span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#91;</span>CmdletBinding<span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">Param</span><span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#91;</span>Parameter<span style="color: #333;">&#40;</span>Mandatory<span style="color: #66cc66;">=</span><span style="color: #660033; font-weight: bold;">$true</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>System.<span style="color: #003366;">Management</span>.<span style="color: #003366;">Automation</span>.<span style="color: #003366;">InvocationInfo</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$Invocation</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#41;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">function</span> <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">ScopeDepth</span></span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">trap</span> <span style="color: #333;">&#123;</span> <span style="color: #666699; font-weight: bold;">continue</span> <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$depth</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">do</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">Set-<span style="font-style: normal;">Variable</span></span> scope_test <span style="color: #000066;">-Scope</span> <span style="color: #333;">&#40;</span><span style="color: #66cc66;">++</span><span style="color: #660033; font-weight: bold;">$depth</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span> <span style="color: #666699; font-weight: bold;">while</span><span style="color: #333;">&#40;</span>$?<span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">return</span> <span style="color: #660033; font-weight: bold;">$depth</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$depth</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">ScopeDepth</span></span><br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Remove-<span style="font-style: normal;">Variable</span></span> scope_test<br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Variable</span></span> scope_test<br />
<br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Object</span></span> <span style="color: #003366; font-weight: bold;">PSObject</span> @<span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; ModuleScope <span style="color: #66cc66;">=</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">bool</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$Invocation</span>.<span style="color: #003366;">MyCommand</span>.<span style="color: #003366;">Module</span><br />
&nbsp; &nbsp; &nbsp; GlobalScope <span style="color: #66cc66;">=</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">bool</span><span style="color: #333;">&#93;</span></span><span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Variable</span></span> scope_test <span style="color: #000066;">-Scope</span> global <span style="color: #000066;">-ea</span> <span style="color: #cc66cc;">0</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; ScriptScope <span style="color: #66cc66;">=</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">bool</span><span style="color: #333;">&#93;</span></span><span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Variable</span></span> scope_test <span style="color: #000066;">-Scope</span> script <span style="color: #000066;">-ea</span> <span style="color: #cc66cc;">0</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; ScopeDepth &nbsp;<span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$depth</span><br />
&nbsp; &nbsp; &nbsp; PipelinePosition <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$Invocation</span>.<span style="color: #003366;">PipelinePosition</span><br />
&nbsp; &nbsp; &nbsp; PipelineLength <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$Invocation</span>.<span style="color: #003366;">PipelineLength</span><br />
&nbsp; &nbsp; &nbsp; CallStack <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">PSCallStack</span></span><br />
&nbsp; &nbsp; &nbsp; StackDepth <span style="color: #66cc66;">=</span> <span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">PSCallStack</span></span><span style="color: #333;">&#41;</span>.<span style="color: #003366;">Count</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><br />
&nbsp; &nbsp; &nbsp; Invocation <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$Invocation</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<ul>
		<li>Remember: modules sometimes flatten scope.</li>
	</ul>
	<ul>
		<li>Remember: when calling this function you should dot-source it, and pass it $MyInvocation</li>
	</ul>

	<p>As as side note and counter-example, take for instance this module:</p>

	<p><script lang="posh"><br />
New-Module { 
   function test-scope { . Get-Scope $MyInvocation } 
   function test-nestedscope { test-scope }
   function test-nestednestedscope { test-nestedscope }<br />
} | Import-Module<br />
</script></p>

	<p>All three of those functions will return ScopeDepth = 2 (the test-scope function, and the module itself), but the StackDepth will increase correctly. I don&#8217;t know why. It&#8217;s late, so I&#8217;m going to stop writing before I get <em>more</em> confusing.</p>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/what-scope-am-i-in/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerShell Scripting Best Practices: Prefix A</title>
		<link>http://huddledmasses.org/powershell-scripting-best-practices-prefix-a/</link>
		<comments>http://huddledmasses.org/powershell-scripting-best-practices-prefix-a/#comments</comments>
		<pubDate>Fri, 30 Jul 2010 02:45:52 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Modules]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://huddledmasses.org/?p=1516</guid>
		<description><![CDATA[I&#8217;m starting a new series of blog posts about Best Practices for scripting in PowerShell, and I was going to start at the beginning with a requirement that you should use [CmdletBinding()], but the explanation of that will have to wait for the next post, because a bug in PowerShell 2.0 has surfaced which can [...]]]></description>
			<content:encoded><![CDATA[	<p>I&#8217;m starting a new series of blog posts about Best Practices for scripting in PowerShell, and I was going to start at the beginning with a requirement that you should use [CmdletBinding()], but the explanation of that will have to wait for the next post, because a bug in PowerShell 2.0 has surfaced which can only be avoided by carefully following a couple of rules &#8230; and I&#8217;m going to issue those rules as the prefix for the best practices.</p>

	<h3>Rule #1: Never use <code>Get-Module -ListAvailable</code> in a module.</h3>

	<p>You need to run the command outside of your module.  The simplest way to do that is to use <code>Invoke-Command { Get-Module -List Available }</code> &#8230; that should give you the same output, but without the nasty side effects.</p>

	<p>There is <a href="https://connect.microsoft.com/PowerShell/feedback/details/580927">a bug</a> in the <code>ListAvailable</code> parameter, which causes PowerShell to mark other modules <em>which are already loaded</em> as being &#8220;nested&#8221; in your module. </p>

	<p>It does that to all modules which have correct manifests, and the problem is that if your module gets unloaded later (using Remove-Module), it removes these nested modules as well &#8230; even though the user had loaded them separately.</p>

	<h5> <img src='http://huddledmasses.org/wordpress/wp-includes/images/smilies/../../../wp-content/plugins/smilingmasses/new.gif' alt='[new]' class='wp-smiley' />  <strong>Edit: 2010-08-05</strong></h5>

	<p>I should have mentioned this originally (so I&#8217;m adding it now): one of the reasons developers were using Get-Module with -ListAvailable was to get information <em>about their <strong>own</strong> module</em> during the initial load (such as to check module versions, or load data from the PrivateData). If you were doing that, you can use Test-ModuleManifest instead with the path to your manifest: <code>Test-ModuleManifest $PSScriptRoot\ModuleName.psd1</code></p>

	<h3>Rule #2: Do not use <code>Import-Module</code> in a module.</h3>

	<p>If you have a dependency on another module, you should load it by specifying it as a <code>NestedModules</code> in your module manifest. </p>

	<p>There is a bug in the way that Remove-Module unloads modules which causes modules which are loaded from <em>inside</em> your module (whether by Import-Module or by Get-Module -ListAvailable), to be unloaded <em>completely</em> even if they&#8217;ve been previously loaded in the console (global) scope interactively by the user (or via their profile). </p>

	<p>You could possibly make an exception to this rule, if the module is actually in your module&#8217;s folder (and thus, not easily loadable from outside your module), but you&#8217;re making the assumption that no one will ever use that module outside of your module.  </p>

	<p>Modules loaded via the metadata file&#8217;s <code>NestedModules</code> property don&#8217;t have this problem, so you should always load nested modules that way.</p>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/powershell-scripting-best-practices-prefix-a/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Import Binary Modules from Network Shares</title>
		<link>http://huddledmasses.org/how-to-import-binary-modules-from-network-shares/</link>
		<comments>http://huddledmasses.org/how-to-import-binary-modules-from-network-shares/#comments</comments>
		<pubDate>Sat, 03 Jul 2010 06:15:04 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[.Net4]]></category>
		<category><![CDATA[CAS]]></category>
		<category><![CDATA[FileShare]]></category>
		<category><![CDATA[Modules]]></category>
		<category><![CDATA[Policy]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[PowerUser]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[UNC]]></category>

		<guid isPermaLink="false">http://huddledmasses.org/?p=1506</guid>
		<description><![CDATA[Note: This is from a wiki page I just wrote on Importing Binary Modules from Network Shares which discusses not just the solution below that works for .Net 2.0 but also how to solve the problem on .Net 4.0 (e.g.: in PoshConsole). I will most likely not keep this page up to date, so you [...]]]></description>
			<content:encoded><![CDATA[	<p><strong>Note:</strong> This is from a wiki page I just wrote on <a href="http://wiki.poshcode.org/FAQ/Problems_and_Gotchas/Importing_Binary_Modules_from_Network_Shares">Importing Binary Modules from Network Shares</a> which discusses not just the solution below that works for .Net 2.0 but also how to solve the problem on .Net 4.0 (e.g.: in PoshConsole).  I will most likely <em>not</em> keep this page up to date, so you should refer to that wiki if you need more information.</p>

	<p>Almost every author of a binary module has probably had someone ask about this at some point, because there&#8217;s always someone who has their user profiles stored on a network location, and therefore installed their modules on that network path and can&#8217;t get them to load because they get a warning that .Net &#8220;Failed to grant minimum permission requests.&#8221;</p>

	<p>Before we get into this any further let me just say: <strong>by far</strong> the simplest thing to do is to create a local folder on your local hard drive, add that to your environment PSPathModules variable, and just install your modules there.</p>

	<p>Other than that, the solution depends on the version of .Net that you&#8217;re using (you can tell by checking the $PSVersionTable.CLRVersion</p>

	<h3>The .Net 2.0 framework (and 3.0 and 3.5 and 3.5 SP1)</h3>

	<p>The problem is not a PowerShell problem at all, it&#8217;s a .Net problem. The .Net framework 2.0 (remember that PowerShell targets 2.0, and is actually based on .Net 1.1) didn&#8217;t trust assemblies loaded from network shares. You can fix that for an individual assembly or for a whole share using the <a title="http://msdn.microsoft.com/en-us/library/cb6t8dtz(VS.80).aspx" class=" external" rel="external nofollow" href="http://msdn.microsoft.com/en-us/library/cb6t8dtz%28VS.80%29.aspx" target="_blank">Caspol</a> tool.</p>

	<p>A complete discussion of that tool and it&#8217;s myriad command-line options is beyond me, but for a simple solution, you can run this command specifying the server and share you want to load from (in my example the &#8220;Modules&#8221; share on the &#8220;ProfileServer&#8221; server).</p>

	<div class="posh code posh" style="font-family:monospace;"><span style="color: #0066cc; font-style: italic;">Set-<span style="font-style: normal;">Alias</span></span> CasPol <span style="color: #009900;">&quot;$([Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory())CasPol.exe&quot;</span> <br />
CasPol <span style="color: #000066;">-pp</span> off <span style="color: #000066;">-machine</span> <span style="color: #000066;">-addgroup</span> <span style="color: #cc66cc;">1.2</span> <span style="color: #000066;">-url</span> file:<span style="color: #66cc66;">//</span>\ProfileServer\Modules\<span style="color: #66cc66;">*</span> FullTrust</div>

	<p>Hopefully the only thing that needs explaning there is that 1.2 is the default &#8220;Local Intranet&#8221; group, and that CasPol.exe is in your Framework Runtime directory. Once you&#8217;ve run that, you&#8217;ll be able to import any modules that are in subdirectories of that share.</p>

	<p><b>Note:</b> You <em>must</em> run the version of CasPol.exe which is in the lcation defined by the GetRuntimeDirectory() command (it&#8217;s important to use the same version as the runtime you want to be affected).</p>

	<p>You can read more about <a href="http://wiki.poshcode.org/FAQ/Problems_and_Gotchas/Importing_Binary_Modules_from_Network_Shares">importing binary modules from network shares</a>, including how it changed in .Net 3.5 SP1 and why it&#8217;s not automatically fixed in .Net 4 over on the PoshCode wiki.  <img src='http://huddledmasses.org/wordpress/wp-includes/images/smilies/../../../wp-content/plugins/smilingmasses/smile.gif' alt=':)' class='wp-smiley' /> </p>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/how-to-import-binary-modules-from-network-shares/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What posts should I update?</title>
		<link>http://huddledmasses.org/what-posts-should-i-update/</link>
		<comments>http://huddledmasses.org/what-posts-should-i-update/#comments</comments>
		<pubDate>Sun, 20 Jun 2010 18:06:04 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Blogging]]></category>
		<category><![CDATA[HuddledMasses]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://huddledmasses.org/?p=1502</guid>
		<description><![CDATA[Someone asked me this week about this old post about custom ICompareers, and wondered if I could rewrite it for PowerShell 2.0 and wrap it in an advanced function &#8230; and it made me think: I really should update some of my old posts from PowerShell 1 and the preview releases of 2 so that [...]]]></description>
			<content:encoded><![CDATA[	<p>Someone asked me this week about <a href="http://huddledmasses.org/custom-icomparers-in-powershell-and-add-type-for-v1/">this old post about custom <code>ICompare</code>ers</a>, and wondered if I could rewrite it for PowerShell 2.0 and wrap it in an advanced function &#8230; and it made me think: I really should update some of my old posts from PowerShell 1 and the preview releases of 2 so that they are accurate and useful.  I thought I&#8217;d throw this out there and let you guys who read my stuff tell me which ones I should update first &#8212; I&#8217;m likely to get sick of it after just a few of them, so it&#8217;s important that I update the ones you want the most first  <img src='http://huddledmasses.org/wordpress/wp-includes/images/smilies/../../../wp-content/plugins/smilingmasses/wink.gif' alt=';-)' class='wp-smiley' /> </p>

	<p>Based on traffic I&#8217;m going to pre-select these three, but anything else is fair game too:</p>

	<ul>
		<li><a href="http://huddledmasses.org/trap-exception-in-powershell/">Trap Exceptions in PowerShell</a></li>
		<li><a href="http://huddledmasses.org/scriptable-ssh-from-powershell/">Scriptable <span class="caps">SSH</span> in PowerShell</a></li>
	</ul>
	<ul>
		<li><a href="http://huddledmasses.org/powershell-modules/">PowerShell Modules</a></li>
	</ul>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/what-posts-should-i-update/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>PowerBoots 0.3 – The Faster Edition</title>
		<link>http://huddledmasses.org/powerboots-0-3-the-faster-edition/</link>
		<comments>http://huddledmasses.org/powerboots-0-3-the-faster-edition/#comments</comments>
		<pubDate>Sat, 19 Jun 2010 05:40:53 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[PowerBoots]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Teaser]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://huddledmasses.org/?p=1496</guid>
		<description><![CDATA[I&#8217;ve been working on a ton of new functionality for this next release of PowerBoots &#8230; and now that I&#8217;m getting close to ready to release, I thought it was time to work on the performance! Here&#8217;s a completely trivial example: WPK: Command : $boxes = 1..100 &#124; % { New-TextBox -Text Foo -FontFamily Consolas [...]]]></description>
			<content:encoded><![CDATA[	<p>I&#8217;ve been working on a ton of new functionality for this next release of PowerBoots &#8230; and now that I&#8217;m getting close to ready to release, I thought it was time to work on the performance! Here&#8217;s a completely trivial example:</p>

	<h3>WPK:</h3>

	<p>Command   : $boxes = 1..100 | % { New-TextBox -Text Foo -FontFamily Consolas -On_GotFocus { $_ } }<br />
Duration  : 5.25153s</p>

	<h3>Current PowerBoots 0.2:</h3>

	<p>Command   : $boxes = 1..100 | % { TextBox -Text Foo -FontFamily Consolas -On_GotFocus { $_ } }<br />
<strong>Average   : 9.40994s</strong></p>

	<p>You can see why I thought I should probably work on improving that. It was bad.</p>

	<h3>PowerBoots 0.3 yesterday:</h3>

	<p>Command   : $boxes = 1..100 | % { TextBox -Text Foo -FontFamily Consolas -On_GotFocus { $_ } }<br />
Duration  : 7.43874s</p>

	<h3>PowerBoots 0.3 tonight:</h3>

	<p>Command   : $boxes = 1..100 | % { TextBox -Text Foo -FontFamily Consolas -On_GotFocus { $_ } }<br />
<strong>Duration  : 0.34103s</strong></p>

	<p>Now, if you&#8217;re like me, you&#8217;re probably thinking I screwed up <em>something</em> and that TextBox isn&#8217;t actually getting created right &#8230;</p>

	<p><img src="http://joelbennett.net/images/PowerBoots/Boots-Performance-Boost.png" alt="" width="902" height="573" /></p>

	<p>Postscript: ran another test. A little more useful. I have 248 fonts on my system.  I have an &#8220;Samples&#8221; script which shows them all:</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">BootsWindow</span></span> <span style="color: #333;">&#123;</span> ScrollViewer <span style="color: #333;">&#123;</span> TextBlock <span style="color: #009900;">&quot;Loading Fonts...&quot;</span> <span style="color: #000066;">-FontSize</span> <span style="color: #cc66cc;">62</span> <span style="color: #000066;">-FontFamily</span> SegoeUI <span style="color: #333;">&#125;</span> <span style="color: #333;">&#125;</span> <span style="color: #000066;">-Async</span> <span style="color: #000066;">-Passthru</span> <span style="color: #66cc66;">|</span> <br />
<span style="color: #0066cc; font-style: italic;">Invoke-<span style="font-style: normal;">BootsWindow</span></span> <span style="color: #000066;">-Script</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$This</span>.<span style="color: #003366;">Content</span>.<span style="color: #003366;">Content</span> <span style="color: #66cc66;">=</span> $<span style="color: #333;">&#40;</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">ForEach</span><span style="color: #333;">&#40;</span> <span style="color: #660033; font-weight: bold;">$font</span> <span style="color: #666699; font-weight: bold;">in</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>System.<span style="color: #003366;">Windows</span>.<span style="color: #003366;">Media</span>.<span style="color: #003366;">Fonts</span><span style="color: #333;">&#93;</span></span>::<span style="color: #003366;">SystemFontFamilies</span> <span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TextBlock <span style="color: #000066;">-FontFamily</span> <span style="color: #660033; font-weight: bold;">$font</span>.<span style="color: #003366;">Source</span> <span style="color: #000066;">-Text</span> <span style="color: #009900;">&quot;The Quick Brown Fox Jumps over the Lazy Dog&quot;</span> <span style="color: #000066;">-FontSize</span> <span style="color: #cc66cc;">18</span>; <span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Host</span></span> <span style="color: #660033; font-weight: bold;">$font</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#41;</span> <span style="color: #66cc66;">|</span> StackPanel<br />
<span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<h3>Old PowerBoots:</h3>

	<p>Duration  : 19.39894s</p>

	<h3>New PowerBoots:</h3>

	<p>Duration  : 3.53100s</p>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/powerboots-0-3-the-faster-edition/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Better error messages for PowerShell ValidatePattern</title>
		<link>http://huddledmasses.org/better-error-messages-for-powershell-validatepattern/</link>
		<comments>http://huddledmasses.org/better-error-messages-for-powershell-validatepattern/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 03:08:35 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Attribute]]></category>
		<category><![CDATA[Error message]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[ValidatePattern]]></category>

		<guid isPermaLink="false">http://huddledmasses.org/?p=1487</guid>
		<description><![CDATA[If you&#8217;ve been writing advanced PowerShell 2.0 functions, you&#8217;ve probably used some of the Validate* attributes to enforce valid parameter values, and you may have noticed that their error messages leave a lot to be desired. For example, imagine that you have a parameter which takes a 10-digit phone number: function Test-PhoneNumber &#123; param&#40; &#91;ValidatePattern&#40;'^\(?\d{3}\)?[-\s.]?\d{3}[-\s.]\d{4}$'&#41;&#93;$number [...]]]></description>
			<content:encoded><![CDATA[	<p>If you&#8217;ve been writing advanced PowerShell 2.0 functions, you&#8217;ve probably used some of the Validate* attributes to enforce valid parameter values, and you may have noticed that their error messages leave a lot to be desired. For example, imagine that you have a parameter which takes a 10-digit phone number:</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #666699; font-weight: bold;">function</span> <span style="color: #0066cc; font-style: italic;">Test-<span style="font-style: normal;">PhoneNumber</span></span> <span style="color: #333;">&#123;</span><br />
<span style="color: #666699; font-weight: bold;">param</span><span style="color: #333;">&#40;</span> <span style="color: #333;">&#91;</span>ValidatePattern<span style="color: #333;">&#40;</span><span style="color: #009900;">'^\(?\d{3}\)?[-\s.]?\d{3}[-\s.]\d{4}$'</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><span style="color: #660033; font-weight: bold;">$number</span> <span style="color: #333;">&#41;</span><br />
<span style="color: #666666; font-style: italic;">&lt;# do stuff #&gt;</span><br />
<span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<h3>The problem</h3>

	<p>Mark Schill (Meson) brought this up at our <a href="http://PowerShellGroup.org/virtual">virtual PowerShell User Group</a> on <span class="caps">IRC</span> tonight: the error messages are confusing and not helpful. For instance, when you try that function and pass an invalid phone number (let&#8217;s say you forget to include the area code), you get this error message:</p>

	<p><span style="color:red;font-family:Consolas,'Courier New',monospace">Test-PhoneNumber : Cannot validate argument on parameter 'number'. The argument "555-1212" does not match the "^\(?\d{3}\)?[-\s.]?\d{3}[-\s.]\d{4}$" pattern. Supply an argument that matches "^\(?\d{3}\)?[-\s.]?\d{3}[-\s.]\d{4}$" and try the command again.</span></p>

	<p>There aren&#8217;t very many people who can read regular expressions, but only someone who <em>can</em> would really find the entirety of that error message useful. Everyone else is going to get (at most) this out of it: <span style="color:red;font-family:Consolas,'Courier New',monospace"> Cannot validate argument on parameter &#8216;number&#8217;. The argument &#8220;555-1212&#8221; does not match <strong>... yadda, yadda</strong></span>.  </p>

	<p>That being the case, we&#8217;d like to hide the rest of that message &#8230; particularly the part that says: &#8220;Supply an argument that matches &#8230;&#8221; which is, frankly, just annoying or insulting depending on who your users are. In fact, as Mark suggested, I&#8217;d like to replace it with a custom message &#8230; something like: <span style="color:red;font-family:Consolas,'Courier New',monospace">Cannot validate argument on parameter &#8216;number&#8217;. The supplied value is not a valid phone number. Please supply a full 10-digit number like: (123) 555-1212</span></p>

	<h3>Custom Validation Properties</h3>

	<p>So, this evening I decided to do something about it. It&#8217;s really pretty simple to write your own Validate*Attribute &#8230; you just have to derive from <code>ValidateEnumeratedArgumentsAttribute</code>, and override <code>ValidateElement</code>.  Here&#8217;s an example ValidatePattern that supports a custom error message.  I&#8217;ll paste the C# code separately, but basically you can just use <code>Add-Type -TypeDefinition</code> and pass this code as a here-string &#8230; </p>

	<div class="csharp code csharp" style="font-family:monospace;"><br />
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.ComponentModel</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Management.Automation</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Text.RegularExpressions</span><span style="color: #008000;">;</span><br />
<span style="color: #000000;">&#91;</span>AttributeUsage<span style="color: #000000;">&#40;</span>AttributeTargets.<span style="color: #0000FF;">Field</span> <span style="color: #008000;">|</span> AttributeTargets.<span style="color: #0000FF;">Property</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span><br />
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> ValidatePatternExAttribute <span style="color: #008000;">:</span> ValidateEnumeratedArgumentsAttribute<br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">private</span> RegexOptions _options <span style="color: #008000;">=</span> RegexOptions.<span style="color: #0000FF;">IgnoreCase</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">private</span> <span style="color: #FF0000;">string</span> _pattern<span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">private</span> <span style="color: #FF0000;">string</span> _message<span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #0600FF;">protected</span> <span style="color: #0600FF;">override</span> <span style="color: #0600FF;">void</span> ValidateElement<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> element<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>element <span style="color: #008000;">==</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">throw</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> ValidationMetadataException<span style="color: #000000;">&#40;</span>_message <span style="color: #008000;">+</span> <span style="color: #666666;">&quot;<span style="color: #008080; font-weight: bold;">\n</span>ValidatePatternEx Failure: Argument Is Null&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #FF0000;">string</span> input <span style="color: #008000;">=</span> element.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; Regex regex <span style="color: #008000;">=</span> null<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; regex <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> Regex<span style="color: #000000;">&#40;</span>_pattern, _options<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #008000;">!</span>regex.<span style="color: #0000FF;">Match</span><span style="color: #000000;">&#40;</span>input<span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Success</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">throw</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> ValidationMetadataException<span style="color: #000000;">&#40;</span>_message <span style="color: #008000;">+</span> <span style="color: #666666;">&quot;<span style="color: #008080; font-weight: bold;">\n</span>ValidatePatternEx failure, the value didn't match the pattern: &quot;</span> <span style="color: #008000;">+</span> _pattern<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> RegexOptions Options<br />
&nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; get<br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">return</span> _options<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; set<br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_options <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">string</span> Pattern<br />
&nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; get<br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">return</span> _pattern<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; set<br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">string</span>.<span style="color: #0000FF;">IsNullOrEmpty</span><span style="color: #000000;">&#40;</span>value<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">throw</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> ArgumentException<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;RegularExpression Pattern is null or empty&quot;</span>, <span style="color: #666666;">&quot;message&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_pattern <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">string</span> Message<br />
&nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; get<br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">return</span> _message<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; set<br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">string</span>.<span style="color: #0000FF;">IsNullOrEmpty</span><span style="color: #000000;">&#40;</span>value<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">throw</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> ArgumentException<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Error Message is null or empty&quot;</span>, <span style="color: #666666;">&quot;message&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_message <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#125;</span><br />
<span style="color: #000000;">&#125;</span></div>

	<h4>Using it in PowerShell</h4>

	<p>When you use that in PowerShell, assuming that you called <code>Add-Type</code> with that as-is, you only have to change your function slightly, using ValidatePatternEx instead of ValidatePattern, and passing named properties, including the message.</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #666699; font-weight: bold;">function</span> <span style="color: #0066cc; font-style: italic;">Test-<span style="font-style: normal;">PhoneNumber</span></span> <span style="color: #333;">&#123;</span><br />
<span style="color: #666699; font-weight: bold;">param</span><span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#91;</span>ValidatePatternEx<span style="color: #333;">&#40;</span>Pattern<span style="color: #66cc66;">=</span><span style="color: #009900;">'^\(?\d{3}\)?[-\s.]?\d{3}[-\s.]\d{4}$'</span>, Message<span style="color: #66cc66;">=</span><span style="color: #009900;">'Please enter a 10-digit phone number like: (123) 555-1212'</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$number</span><br />
<span style="color: #333;">&#41;</span><br />
wrote<span style="color: #66cc66;">-</span>host <span style="color: #660033; font-weight: bold;">$number</span> <span style="color: #000066;">-fore</span> magenta<br />
<span style="color: #333;">&#125;</span></div>

	<p>But once you do, you will get much better error messages:</p>

	<p><span style="color:red;font-family:Consolas,'Courier New',monospace">Test-PhoneNumber : Cannot validate argument on parameter 'number'. Please enter a 10-digit phone number like: (123) 555-1212
ValidatePatternEx failure, the value didn't match the pattern: ^\(?\d{3}\)?[-\s.]?\d{3}[-\s.]\d{4}$</span></p>

	<h3>Other Applications</h3>

	<p>Of course, you may have noticed that this is really a completely custom parameter validator. You aren&#8217;t limited to just adding nice error messages to the validation error &#8212; you can create whatever validator you can dream up. Let me know what you come up with!</p>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/better-error-messages-for-powershell-validatepattern/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>F.A.Q.: How do I Install a PowerShell Module</title>
		<link>http://huddledmasses.org/f-a-q-how-do-i-install-a-powershell-module/</link>
		<comments>http://huddledmasses.org/f-a-q-how-do-i-install-a-powershell-module/#comments</comments>
		<pubDate>Wed, 26 May 2010 20:00:52 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Install]]></category>
		<category><![CDATA[Modules]]></category>
		<category><![CDATA[PoshCode]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://huddledmasses.org/?p=1482</guid>
		<description><![CDATA[As a warm up to writing my best-practices posts, I decided to answer this frequently asked question on the PowerShell wiki at PoshCode. I&#8217;m not going to repeat the whole post here, but suffice it to say that there&#8217;s a good explanation on the How Do I Install a PowerShell Module page, along with this [...]]]></description>
			<content:encoded><![CDATA[	<p>As a warm up to writing my best-practices posts, I decided to answer this frequently asked question on the PowerShell wiki at PoshCode. I&#8217;m not going to repeat the whole post here, but suffice it to say that there&#8217;s a good explanation on the <a href="http://wiki.poshcode.org/FAQ/Tips_and_Tricks/How_Do_I..._Install_a_Module">How Do I Install a PowerShell Module</a> page, along with this script:</p>

	<p><script type="text/javascript" src="http://PoshCode.org/embed/1875"></script></p>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/f-a-q-how-do-i-install-a-powershell-module/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Creating WPF UIs for PowerShell with PowerBoots and Visual Studio WPF Designer</title>
		<link>http://huddledmasses.org/creating-wpf-uis-for-powershell-with-powerboots-and-visual-studio-wpf-designer/</link>
		<comments>http://huddledmasses.org/creating-wpf-uis-for-powershell-with-powerboots-and-visual-studio-wpf-designer/#comments</comments>
		<pubDate>Fri, 30 Apr 2010 03:09:42 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[PowerBoots]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">http://huddledmasses.org/?p=1433</guid>
		<description><![CDATA[I&#8217;ve had several people ask me how PowerBoots compares to PrimalForms, or ask for a visual designer for PowerBoots. I usually answer something along the lines of the fact that Microsoft has already created a very good WPF/XAML designer in Visual Studio (including the free Express editions), particularly in 2010, so I don&#8217;t see why [...]]]></description>
			<content:encoded><![CDATA[	<p>I&#8217;ve had several people ask me how <a href="http://boots.codeplex.com/">PowerBoots</a> compares to PrimalForms, or ask for a visual designer for PowerBoots. I usually answer something along the lines of the fact that Microsoft has already created a very good WPF/<span class="caps">XAML</span> designer in Visual Studio (including the free Express editions), particularly in 2010, so I don&#8217;t see why I should duplicate their efforts.  However, up until now I haven&#8217;t written or published any sort of walk through about how to make that work &#8230; </p>

	<p>So crank up your <a href="http://msdn.com/express/">Visual Studio Express Edition</a> and make yourself some user interfaces!</p>

	<p>Basically, you just create a <span class="caps">WPF</span> project in C# or VB.Net or whatever &#8230; I chose to name my project &#8220;XamlForBoots&#8221; &#8212; your project will start off with an empty MainWindow.xaml file which will look something like this:</p>

	<a href="/wordpress/wp-content/uploads/2010/03/NewMainWindow.xaml_.png"><img src="/wordpress/wp-content/uploads/2010/03/NewMainWindow.xaml_-300x199.png" alt="This is what the Main Window looks like at first" title="NewMainWindow.xaml" width="300" height="199" class="size-medium wp-image-1434" /></a>

	<p>After you drag a few more controls onto the form, and you&#8217;ve created a complete user interface, you should delete the x:Class attribute.  You need to make sure you know the <em>name</em> of the controls you want to interact with, so you might end up with something like this (I used the property pane, which you can&#8217;t see in this shot, to name each textbox and the button):</p>

	<a href="/wordpress/wp-content/uploads/2010/04/FinishedMainWindow.xaml_.png"><img src="/wordpress/wp-content/uploads/2010/04/FinishedMainWindow.xaml_-300x212.png" alt="Once you&#039;ve dragged some controls onto it" title="FinishedMainWindow.xaml" width="300" height="212" class="size-medium wp-image-1439" /></a>

	<p>At this point, we&#8217;re ready to drop into PowerShell and write some script. Now &#8230; there is one catch here.  The first script I&#8217;m going to show you here is for <strong>PowerBoots 0.3</strong> (which will be the first release candidate for a gold 1.0 release, and will be out soon&#8482;). However, I&#8217;ll post below some code to make it work on the current release, but it requires an external function.</p>

	<p>So, in the next release, you can just do something like this:</p>

	<div class="posh code posh" style="font-family:monospace;"><span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">BootsWindow</span></span> <span style="color: #000066;">-FileTemplate</span> <span style="color: #660033; font-weight: bold;">$pwd</span>\MainWindow.<span style="color: #003366;">xaml</span> <span style="color: #000066;">-On_Loaded</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Register-<span style="font-style: normal;">BootsEvent</span></span> <span style="color: #000066;">-InputObject</span> <span style="color: #660033; font-weight: bold;">$Calculate</span> <span style="color: #000066;">-EventName</span> Click <span style="color: #000066;">-Action</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$Total</span>.<span style="color: #003366;">Text</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">'${0:n2}'</span> <span style="color: #000066;">-f</span> <span style="color: #333;">&#40;</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Miles</span>.<span style="color: #003366;">Text</span> <span style="color: #000066;">-as</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">Double</span><span style="color: #333;">&#93;</span></span><span style="color: #333;">&#41;</span> <span style="color: #66cc66;">/</span> <span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Mpg</span>.<span style="color: #003366;">Text</span> <span style="color: #000066;">-as</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">Double</span><span style="color: #333;">&#93;</span></span><span style="color: #333;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Cost</span>.<span style="color: #003366;">Text</span> <span style="color: #000066;">-as</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">Double</span><span style="color: #333;">&#93;</span></span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span></div>

	<p>The key thing you&#8217;re supposed to notice here is that the named controls in the <span class="caps">XAML</span> are automatically surfaced as variables in the event handlers, and all you have to do is write your logic and hook it up to the controls. We provide a <code>Register-BootsEvent</code> cmdlet which is like Register-ObjectEvent except that it executes the event handlers on the UI thread (so they can do things to the UI) instead of in a new runspace, but basically it&#8217;s like calling <code>Add_Click</code>. Of course, you <strong>can</strong> use Register-ObjectEvent if you just want to spin off PowerShell tasks that don&#8217;t read/write the UI.</p>

	<h3>Backwards compatibility</h3>

	<p>To get this to work in the current release, you need a function <code>Export-NamedControl</code> to create variables for each of those named controls as variables. Once you&#8217;ve defined that function, you can write code very much like I did before, but you have to <em>call Export-NamedControl yourself</em>, and you won&#8217;t have that Register-BootsEvent cmdlet. You don&#8217;t really need it for this anyway, so that&#8217;s not a big deal, at least in this case. Here&#8217;s the function. and the actual code to create the window.  You can just paste this into a script file:</p>

	<div class="posh code posh" style="font-family:monospace;"><span style="color: #666699; font-weight: bold;">function</span> global:<span style="color: #0066cc; font-style: italic;">Export-<span style="font-style: normal;">NamedControl</span></span> <span style="color: #333;">&#123;</span><br />
<span style="color: #333;">&#91;</span>CmdletBinding<span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><br />
<span style="color: #666699; font-weight: bold;">param</span><span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#91;</span>Parameter<span style="color: #333;">&#40;</span>ValueFromPipeline<span style="color: #66cc66;">=</span><span style="color: #660033; font-weight: bold;">$true</span>, Position<span style="color: #66cc66;">=</span><span style="color: #cc66cc;">1</span>, Mandatory<span style="color: #66cc66;">=</span><span style="color: #660033; font-weight: bold;">$true</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$Root</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$BootsWindow</span><br />
<span style="color: #333;">&#41;</span><br />
<span style="color: #666699; font-weight: bold;">process</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Invoke-<span style="font-style: normal;">BootsWindow</span></span> <span style="color: #660033; font-weight: bold;">$Root</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$control</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$BootsWindow</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">while</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$control</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$control</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$control</span> <span style="color: #66cc66;">|</span> ForEach<span style="color: #66cc66;">-</span>Object <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$Element</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$_</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span><span style="color: #66cc66;">!</span><span style="color: #660033; font-weight: bold;">$Element</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span> <span style="color: #666699; font-weight: bold;">return</span> <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Verbose</span></span> <span style="color: #009900;">&quot;This $($Element.GetType().Name) is $Element&quot;</span><br />
&nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Element</span>.<span style="color: #003366;">Name</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Verbose</span></span> <span style="color: #009900;">&quot;Defining $($Element.Name) = $Element&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Set-<span style="font-style: normal;">Variable</span></span> <span style="color: #009900;">&quot;$($Element.Name)&quot;</span> <span style="color: #660033; font-weight: bold;">$Element</span> <span style="color: #000066;">-Scope</span> <span style="color: #cc66cc;">2</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">## Return all the child controls ...</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @<span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Element</span>.<span style="color: #003366;">Children</span><span style="color: #333;">&#41;</span> <span style="color: #66cc66;">+</span> @<span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Element</span>.<span style="color: #003366;">Child</span><span style="color: #333;">&#41;</span> <span style="color: #66cc66;">+</span> @<span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Element</span>.<span style="color: #003366;">Content</span><span style="color: #333;">&#41;</span> <span style="color: #66cc66;">+</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @<span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Element</span>.<span style="color: #003366;">Items</span><span style="color: #333;">&#41;</span> <span style="color: #66cc66;">+</span> @<span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Element</span>.<span style="color: #003366;">Inlines</span><span style="color: #333;">&#41;</span> <span style="color: #66cc66;">+</span> @<span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Element</span>.<span style="color: #003366;">Blocks</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span><br />
<br />
<span style="color: #666666; font-style: italic;">####################################################################################################################</span><br />
<span style="color: #666666; font-style: italic;">## Create the window and hook the click. Make sure to use full paths</span><br />
<span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">BootsWindow</span></span> <span style="color: #333;">&#123;</span><span style="color: #333;">&#125;</span> <span style="color: #000066;">-FileTemplate</span> <span style="color: #660033; font-weight: bold;">$pwd</span>\MainWindow.<span style="color: #003366;">xaml</span> <span style="color: #000066;">-On_Loaded</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Export-<span style="font-style: normal;">NamedControl</span></span> <span style="color: #000066;">-Root</span> <span style="color: #660033; font-weight: bold;">$Args</span><span style="color: #333;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #333;">&#93;</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$Calculate</span>.<span style="color: #003366;">Add_Click</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$Total</span>.<span style="color: #003366;">Text</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">'${0:n2}'</span> <span style="color: #000066;">-f</span> <span style="color: #333;">&#40;</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Miles</span>.<span style="color: #003366;">Text</span> <span style="color: #000066;">-as</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">Double</span><span style="color: #333;">&#93;</span></span><span style="color: #333;">&#41;</span> <span style="color: #66cc66;">/</span> <span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Mpg</span>.<span style="color: #003366;">Text</span> <span style="color: #000066;">-as</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">Double</span><span style="color: #333;">&#93;</span></span><span style="color: #333;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Cost</span>.<span style="color: #003366;">Text</span> <span style="color: #000066;">-as</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">Double</span><span style="color: #333;">&#93;</span></span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><span style="color: #333;">&#41;</span><br />
<span style="color: #333;">&#125;</span></div>

	<p>And in order to try <strong>my</strong> demo, you&#8217;re going to need that MainWindow.xaml file:</p>

	<div class="xml code xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Window</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">xmlns:x</span>=<span style="color: #ff0000;">&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;</span></span><br />
<span style="color: #009900;"> &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000066;">Title</span>=<span style="color: #ff0000;">&quot;Trip Cost&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid.RowDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;28&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;28&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;28&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;RowDefinition</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;28&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid.RowDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Grid.ColumnDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ColumnDefinition</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;110&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ColumnDefinition</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid.ColumnDefinitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Label</span> <span style="color: #000066;">Content</span>=<span style="color: #ff0000;">&quot;Miles&quot;</span> <span style="color: #000066;">VerticalAlignment</span>=<span style="color: #ff0000;">&quot;Top&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;23&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;200&quot;</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;miles&quot;</span> <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Stretch&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Label</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Content</span>=<span style="color: #ff0000;">&quot;Miles per Gallon&quot;</span> <span style="color: #000066;">VerticalAlignment</span>=<span style="color: #ff0000;">&quot;Top&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;23&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;200&quot;</span> <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Stretch&quot;</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;mpg&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Label</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;2&quot;</span> <span style="color: #000066;">Content</span>=<span style="color: #ff0000;">&quot;Cost per Gallon&quot;</span> &nbsp;<span style="color: #000066;">VerticalAlignment</span>=<span style="color: #ff0000;">&quot;Top&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBox</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;2&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;23&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;200&quot;</span> <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Stretch&quot;</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;cost&quot;</span> &nbsp;<span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Button</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;calculate&quot;</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;3&quot;</span> <span style="color: #000066;">Content</span>=<span style="color: #ff0000;">&quot;_Calculate&quot;</span> <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Center&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextBlock</span> <span style="color: #000066;">Grid.Column</span>=<span style="color: #ff0000;">&quot;1&quot;</span> <span style="color: #000066;">Grid.Row</span>=<span style="color: #ff0000;">&quot;3&quot;</span> <span style="color: #000066;">Height</span>=<span style="color: #ff0000;">&quot;23&quot;</span> <span style="color: #000066;">Width</span>=<span style="color: #ff0000;">&quot;200&quot;</span> <span style="color: #000066;">HorizontalAlignment</span>=<span style="color: #ff0000;">&quot;Stretch&quot;</span> <span style="color: #000066;">Name</span>=<span style="color: #ff0000;">&quot;total&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Grid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Window<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/creating-wpf-uis-for-powershell-with-powerboots-and-visual-studio-wpf-designer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Logging Robocopy errors to the Event Log using PowerShell</title>
		<link>http://huddledmasses.org/logging-robocopy-errors-to-the-event-log-using-powershell/</link>
		<comments>http://huddledmasses.org/logging-robocopy-errors-to-the-event-log-using-powershell/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 04:59:22 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[EventLog]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Module]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[RoboCopy]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://huddledmasses.org/?p=1435</guid>
		<description><![CDATA[Someone came into IRC last week asking for help converting a rather large vbscript into PowerShell, and got me interested in turning Robocopy logs into Windows Events&#8230; The original VBScript is about 68 lines of code, and writes one event per log file. We duplicated it&#8217;s functionality with the following 11 lines of code: Param&#40;$LogPath, [...]]]></description>
			<content:encoded><![CDATA[	<p>Someone came into <span class="caps">IRC</span> last week asking for help converting a <a href="http://www.askthemct.com/2009/07/16/circularish-logging-the-event-viewer-and-robocopy/">rather large vbscript</a> into PowerShell, and got me interested in turning Robocopy logs into Windows Events&#8230;</p>

	<p>The original VBScript is about 68 lines of code, and writes one event per log file.  We duplicated it&#8217;s functionality with the following 11 lines of code:<br />
<div class="posh code posh" style="font-family:monospace;"><span style="color: #666699; font-weight: bold;">Param</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$LogPath</span>, <span style="color: #660033; font-weight: bold;">$LogName</span>, <span style="color: #660033; font-weight: bold;">$ArchiveDays</span><span style="color: #333;">&#41;</span><br />
<span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">string</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$Log</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">Join-<span style="font-style: normal;">Path</span></span> <span style="color: #660033; font-weight: bold;">$LogPath</span> <span style="color: #660033; font-weight: bold;">$LogName</span><br />
<span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">Select-<span style="font-style: normal;">String</span></span> <span style="color: #000066;">-Path</span> <span style="color: #660033; font-weight: bold;">$Log</span> <span style="color: #000066;">-pattern</span> <span style="color: #009900;">&quot;0x0000&quot;</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$logError</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;$Log.ERROR.$(get-date -format 'yyyy-MM-dd-hhmmss')&quot;</span><br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">write-<span style="font-style: normal;">eventlog</span></span> Application <span style="color: #000066;">-Source</span> Robocopy <span style="color: #000066;">-EventId</span> <span style="color: #cc66cc;">12</span> <span style="color: #000066;">-EntryType</span> Error <span style="color: #000066;">-Message</span> <span style="color: #009900;">&quot;Robocopy Job Failed -please check log file $LogError&quot;</span><br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">move-<span style="font-style: normal;">item</span></span> <span style="color: #660033; font-weight: bold;">$log</span> <span style="color: #660033; font-weight: bold;">$logError</span><br />
<span style="color: #333;">&#125;</span> <span style="color: #666699; font-weight: bold;">else</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># If you do not want to send Success Events to the Application Log, comment out the following line</span><br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">write-<span style="font-style: normal;">eventlog</span></span> Application <span style="color: #000066;">-Source</span> Robocopy <span style="color: #000066;">-EventId</span> <span style="color: #cc66cc;">1</span> <span style="color: #000066;">-EntryType</span> Information <span style="color: #000066;">-Message</span> <span style="color: #009900;">&quot;Robocopy Job Failed -please check log file $LogError&quot;</span><br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">move-<span style="font-style: normal;">item</span></span> <span style="color: #660033; font-weight: bold;">$Log</span> <span style="color: #009900;">&quot;$Log.ARCHIVE.$(Get-Date -f 'yyyy-MM-dd-hhmmss')&quot;</span><br />
<span style="color: #333;">&#125;</span><br />
<span style="color: #666666; font-style: italic;">## Remove archive logs older than $archiveDate</span><br />
<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">ChildItem</span></span> <span style="color: #009900;">&quot;$Log.ARCHIVE.*&quot;</span> <span style="color: #66cc66;">|</span> <span style="color: #660033;">Where</span> <span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">CreationTime</span> <span style="color: #000066;">-lt</span> <span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Date</span></span><span style="color: #333;">&#41;</span>.<span style="color: #003366;">AddDays</span><span style="color: #333;">&#40;</span><span style="color: #66cc66;">-</span><span style="color: #660033; font-weight: bold;">$archiveDays</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#125;</span> <span style="color: #66cc66;">|</span> <span style="color: #0066cc; font-style: italic;">Remove-<span style="font-style: normal;">Item</span></span></div>

	<p>Actually, even that first attempt extended the functionality a little, because we potentially make multiple archive copies which we only delete once they pass the archive date. </p>

	<h3>New-EventLog Application Robocopy</h3>

	<p>There are two catches.  First, you need PowerShell 2.0.  Second, before you can run that script <em>the first time</em>, you have to create the &#8220;Robocopy&#8221; event source for the machine by running this command in an elevated PowerShell console (that is, you have to run it &#8220;as Administrator&#8221;):</p>

	<div class="posh code posh" style="font-family:monospace;"><span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">EventLog</span></span> Application Robocopy</div>

	<p>Of course, being a good geek, I couldn&#8217;t leave well enough alone, so we changed the script so that it would log each unique error to the event log (including the line following the error, which has more details), so that there&#8217;s no need to go &#8220;check the log file&#8221; on the machine, since you can retrieve the event logs remotely.  The finished script looks like this:</p>

	<div class="posh code posh" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#requires -Version 2.0</span><br />
<span style="color: #666666; font-style: italic;">## BEFORE you use this the FIRST time (only once per machine)</span><br />
<span style="color: #666666; font-style: italic;">## you must run the following command elevated (as Administrator):</span><br />
<span style="color: #666666; font-style: italic;">## New-EventLog Application Robocopy</span><br />
<br />
<span style="color: #666699; font-weight: bold;">Param</span><span style="color: #333;">&#40;</span> &nbsp;<span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">string</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$LogPath</span> &nbsp;<span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;C:\Logs\&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">string</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$LogName</span> &nbsp;<span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;Robocopy-log-file.log&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">int</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$ArchiveDays</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">30</span><br />
<span style="color: #333;">&#41;</span><br />
<span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">string</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$Log</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">Join-<span style="font-style: normal;">Path</span></span> <span style="color: #660033; font-weight: bold;">$LogPath</span> <span style="color: #660033; font-weight: bold;">$LogName</span><br />
<br />
<span style="color: #660033; font-weight: bold;">$Archive</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;ARCHIVE&quot;</span><br />
<span style="color: #666699; font-weight: bold;">foreach</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$errorEvent</span> <span style="color: #666699; font-weight: bold;">in</span> <span style="color: #0066cc; font-style: italic;">Select-<span style="font-style: normal;">String</span></span> <span style="color: #000066;">-Path</span> <span style="color: #660033; font-weight: bold;">$Log</span> <span style="color: #000066;">-Pattern</span> <span style="color: #009900;">'ERROR .*0x0000.*$'</span> <span style="color: #000066;">-context</span> <span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">|</span> <span style="color: #660033;">sort</span> <span style="color: #333;">&#123;</span><span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">matches</span><span style="color: #333;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #333;">&#93;</span>.<span style="color: #003366;">value</span><span style="color: #333;">&#125;</span> <span style="color: #000066;">-Unique</span> <span style="color: #333;">&#41;</span> <br />
<span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$Archive</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;ERROR&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">write-<span style="font-style: normal;">eventlog</span></span> Application <span style="color: #000066;">-Source</span> Robocopy <span style="color: #000066;">-EventId</span> <span style="color: #cc66cc;">12</span> <span style="color: #000066;">-EntryType</span> Error <span style="color: #000066;">-Message</span> $<span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$errorEvent</span>.<span style="color: #003366;">Line</span> <span style="color: #66cc66;">+</span> <span style="color: #009900;">&quot;<span style="color: #000099; font-weight: bold;">`n</span>&quot;</span> <span style="color: #66cc66;">+</span> <span style="color: #660033; font-weight: bold;">$errorEvent</span>.<span style="color: #003366;">Context</span>.<span style="color: #003366;">PostContext</span><span style="color: #333;">&#41;</span><br />
<span style="color: #333;">&#125;</span><br />
<br />
<span style="color: #666699; font-weight: bold;">switch</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Archive</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&quot;ERROR&quot;</span> <span style="color: #333;">&#123;</span> <span style="color: #666666; font-style: italic;">## Archive the log file as an ERROR (we never delete these automatically)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #660033;">move</span> <span style="color: #660033; font-weight: bold;">$Log</span> <span style="color: #009900;">&quot;$Log.ERROR.$(get-date -format 'yyyy-MM-dd-hhmmss')&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&quot;ARCHIVE&quot;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">write-<span style="font-style: normal;">eventlog</span></span> Application <span style="color: #000066;">-Source</span> Robocopy <span style="color: #000066;">-EventId</span> <span style="color: #cc66cc;">1</span> <span style="color: #000066;">-EntryType</span> Information &nbsp;<span style="color: #000066;">-Message</span> <span style="color: #009900;">&quot;Robocopy successful&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">## Archive the log file</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">move-<span style="font-style: normal;">item</span></span> <span style="color: #660033; font-weight: bold;">$Log</span> <span style="color: #009900;">&quot;$Log.ARCHIVE.$(Get-Date -f 'yyyy-MM-dd-hhmmss')&quot;</span> <span style="color: #000066;">-Force</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span><br />
<br />
<span style="color: #666666; font-style: italic;">## Remove archive logs older than $archiveDate</span><br />
<span style="color: #660033; font-weight: bold;">$archiveDate</span> <span style="color: #66cc66;">=</span> <span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Date</span></span><span style="color: #333;">&#41;</span>.<span style="color: #003366;">AddDays</span><span style="color: #333;">&#40;</span><span style="color: #66cc66;">-</span><span style="color: #660033; font-weight: bold;">$archiveDays</span><span style="color: #333;">&#41;</span><br />
<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">ChildItem</span></span> <span style="color: #009900;">&quot;$Log.ARCHIVE.*&quot;</span> <span style="color: #66cc66;">|</span> <span style="color: #660033;">Where</span> <span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">CreationTime</span> <span style="color: #000066;">-lt</span> <span style="color: #660033; font-weight: bold;">$archiveDate</span> <span style="color: #333;">&#125;</span> <span style="color: #66cc66;">|</span> <span style="color: #0066cc; font-style: italic;">Remove-<span style="font-style: normal;">Item</span></span></div>

	<p>Notice that we cleaned up the parameters a little bit, and put some defaults in, but we still haven&#8217;t written &#8220;help&#8221; ... that&#8217;s partly because I still am not sure that&#8217;s the best option for logging  <img src='http://huddledmasses.org/wordpress/wp-includes/images/smilies/../../../wp-content/plugins/smilingmasses/smile.gif' alt=':)' class='wp-smiley' />   Another way would be to just write one log event, but with details about the errors like:</p>

	<div class="posh code posh" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#requires -Version 2.0</span><br />
<span style="color: #666666; font-style: italic;">## BEFORE you use this the FIRST time (only once per machine)</span><br />
<span style="color: #666666; font-style: italic;">## you must run the following command elevated (as Administrator):</span><br />
<span style="color: #666666; font-style: italic;">## New-EventLog Application Robocopy</span><br />
<br />
<span style="color: #666699; font-weight: bold;">Param</span><span style="color: #333;">&#40;</span> &nbsp;<span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">string</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$LogPath</span> &nbsp;<span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;C:\Logs\&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">string</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$LogName</span> &nbsp;<span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;Robocopy-log-file.log&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">int</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$ArchiveDays</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">30</span><br />
<span style="color: #333;">&#41;</span><br />
<span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">string</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$Log</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">Join-<span style="font-style: normal;">Path</span></span> <span style="color: #660033; font-weight: bold;">$LogPath</span> <span style="color: #660033; font-weight: bold;">$LogName</span><br />
<span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">string</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$LogError</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;$Log.ERROR.$(get-date -format 'yyyy-MM-dd-hhmmss')&quot;</span><br />
<span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">string</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$LogArchive</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;$Log.ARCHIVE.$(get-date -format 'yyyy-MM-dd-hhmmss')&quot;</span><br />
<br />
<span style="color: #660033; font-weight: bold;">$Errors</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">Select-<span style="font-style: normal;">String</span></span> <span style="color: #000066;">-Path</span> <span style="color: #660033; font-weight: bold;">$Log</span> <span style="color: #000066;">-Pattern</span> <span style="color: #009900;">'ERROR .*0x0000.*$'</span> <span style="color: #000066;">-context</span> <span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">|</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">Group-<span style="font-style: normal;">Object</span></span> <span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">Context</span>.<span style="color: #003366;">PostContext</span> <span style="color: #333;">&#125;</span> <span style="color: #66cc66;">|</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">Format-<span style="font-style: normal;">Table</span></span> Count, Name <span style="color: #000066;">-HideTableHeaders</span> <span style="color: #000066;">-AutoSize</span> <span style="color: #66cc66;">|</span> <span style="color: #0066cc; font-style: italic;">Out-<span style="font-style: normal;">String</span></span><br />
<span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Errors</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">write-<span style="font-style: normal;">eventlog</span></span> Application <span style="color: #000066;">-Source</span> Robocopy <span style="color: #000066;">-EventId</span> <span style="color: #cc66cc;">12</span> <span style="color: #000066;">-EntryType</span> Error <span style="color: #000066;">-Message</span> <span style="color: #009900;">&quot;$errors<span style="color: #000099; font-weight: bold;">`n</span><span style="color: #000099; font-weight: bold;">`n</span>Please check: $LogError&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #660033;">move</span> <span style="color: #660033; font-weight: bold;">$Log</span> <span style="color: #660033; font-weight: bold;">$LogError</span><br />
<span style="color: #333;">&#125;</span> <span style="color: #666699; font-weight: bold;">else</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">write-<span style="font-style: normal;">eventlog</span></span> Application <span style="color: #000066;">-Source</span> Robocopy <span style="color: #000066;">-EventId</span> <span style="color: #cc66cc;">1</span> <span style="color: #000066;">-EntryType</span> Information &nbsp;<span style="color: #000066;">-Message</span> <span style="color: #009900;">&quot;Robocopy successful. Log archived: $LogArchive&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">move-<span style="font-style: normal;">item</span></span> <span style="color: #660033; font-weight: bold;">$Log</span> <span style="color: #660033; font-weight: bold;">$LogArchive</span><br />
<span style="color: #333;">&#125;</span><br />
<br />
<span style="color: #666666; font-style: italic;">## Remove archive logs older than $archiveDate</span><br />
<span style="color: #660033; font-weight: bold;">$archiveDate</span> <span style="color: #66cc66;">=</span> <span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Date</span></span><span style="color: #333;">&#41;</span>.<span style="color: #003366;">AddDays</span><span style="color: #333;">&#40;</span><span style="color: #66cc66;">-</span><span style="color: #660033; font-weight: bold;">$archiveDays</span><span style="color: #333;">&#41;</span><br />
<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">ChildItem</span></span> <span style="color: #009900;">&quot;$Log.ARCHIVE.*&quot;</span> <span style="color: #66cc66;">|</span> <span style="color: #660033;">Where</span> <span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">CreationTime</span> <span style="color: #000066;">-lt</span> <span style="color: #660033; font-weight: bold;">$archiveDate</span> <span style="color: #333;">&#125;</span> <span style="color: #66cc66;">|</span> <span style="color: #0066cc; font-style: italic;">Remove-<span style="font-style: normal;">Item</span></span></div>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/logging-robocopy-errors-to-the-event-log-using-powershell/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
