<?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>Live PowerShell With Karl Prosser &#187; pscom</title>
	<atom:link href="http://karlprosser.com/coder/category/pscom/feed/" rel="self" type="application/rss+xml" />
	<link>http://karlprosser.com/coder</link>
	<description>invoke-intelligence &#124; where { $_.necessary }</description>
	<lastBuildDate>Tue, 01 May 2012 18:50:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Fast New PSCustomObject.</title>
		<link>http://karlprosser.com/coder/2009/08/15/fast-new-pscustomobject/</link>
		<comments>http://karlprosser.com/coder/2009/08/15/fast-new-pscustomobject/#comments</comments>
		<pubDate>Sat, 15 Aug 2009 06:49:55 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Bare Metal]]></category>
		<category><![CDATA[Gotchas Etc]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2008/06/15/fast-new-pscustomobject/</guid>
		<description><![CDATA[Given the context on the last few posts. I&#8217;ve made a simple helper method in C# that can take a simple powershell hashtable and create a PSCustomObject based on it. Here is an example of how you can call it. [snapinini.newobjecthelper]::newObjectFast(@{name="karl";age=31;now = [datetime]::Now}) very simple and its at least 6 times faster than the closest [...]]]></description>
			<content:encoded><![CDATA[<p>Given the context on the last few posts. I&#8217;ve made a simple helper method in C# that can take a simple powershell hashtable and create a PSCustomObject based on it. Here is an example of how you can call it.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">[snapinini.newobjecthelper]::newObjectFast(@{name=<span style="color: #006080">"karl"</span>;age=31;now = [datetime]::Now})</pre>
<p>very simple and its at least 6 times faster than the closest other technique in powershell. Most of hte overhead is in creating the hashtable. (otherwise its 90 times faster). The hashtable syntax is very convenient however maybe even its overhead is too much and we deserve a better way.</p>
<p>Here is the C# method. Its pretty basic stuff.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">public static PSObject newObjectFast( Hashtable noteproperties )</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">        {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">            PSObject obj = new PSObject();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">            <span style="color: #0000ff">if</span> (noteproperties != null)</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">                <span style="color: #0000ff">foreach</span>(DictionaryEntry item <span style="color: #0000ff">in</span> noteproperties)</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">                    obj.Properties.Add(new PSNoteProperty((string)item.Key,item.Value));</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">            <span style="color: #0000ff">return</span> obj;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">        }</pre>
<p>- Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2009/08/15/fast-new-pscustomobject/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>PowerShell ISE-Cream</title>
		<link>http://karlprosser.com/coder/2009/02/05/powershell-ise-cream/</link>
		<comments>http://karlprosser.com/coder/2009/02/05/powershell-ise-cream/#comments</comments>
		<pubDate>Thu, 05 Feb 2009 18:11:00 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>
		<category><![CDATA[PSV2]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2009/02/05/powershell-ise-cream/</guid>
		<description><![CDATA[A while back I threw together a few scripts to enhance PowerShell V2 ISE experience that added some PowerShell Analyzer like features . They were a natural fit as ISE (Intergrated Scripting Environment) is like a WPF-based stripped PowerShell Analyzer like with its multiple runspaces, editors, and immediate command area. The extensibility model of ISE [...]]]></description>
			<content:encoded><![CDATA[<p>A while back I threw together a <a href="http://karlprosser.com/coder/2009/01/03/powershell-analayzer-like-execution-hotkeys-for-ps-ctp3-ise/">few scripts</a> to enhance PowerShell V2 ISE experience that added some PowerShell Analyzer like features . They were a natural fit as ISE (Intergrated Scripting Environment) is like a WPF-based stripped PowerShell Analyzer like with its multiple runspaces, editors, and immediate command area.</p>
<p>The extensibility model of ISE has caught on, and many people have been writing some great scripts adding hotkeys to do every what not you could imagine, so I&#8217;ve decided to start a <a href="http://www.codeplex.com/psisecream">codeplex project</a> with the punny name “<a href="http://www.codeplex.com/psisecream">PowerShell ISE-Cream</a>” . The Goal of this project is first to gather a huge variety of functionality that various people are willing to share, refactor it into production quality functions, with extensive error handling, and packaged in V2 Modules, and finally incorporate it in a way that users can easily turn on and off different features through a consistent configuration.</p>
<p>Right now however we are just going to gather whatever scraps there are, whether they conflict with each other or not, and anybody passionate about this can join the project, as we sculpt it hopefully into something both useful and beautiful.</p>
<p>Doug Finke has already joined the club with his <a href="http://www.codeplex.com/psisecream">Expand-Alias and Expand-CurrentAlias</a> functions, and there are quite a few other functions that people i know are willing to share, so it should be good.</p>
<p>We’ll be brainstorming and deciding on a bunch of design issue, you can join the conversation on the first one in this <a href="http://www.codeplex.com/psisecream/Thread/View.aspx?ThreadId=46157">discussion thread</a>.</p>
<p>The <a href="http://powerscripting.wordpress.com/">PowerScripting Podcast</a> tonight (Thursday 5th Feb 2009) will be talking about ISE. There should be a number of MVPs (including myself) and some PowerShell Team staff calling in. It Should be fun.</p>
<p>-Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2009/02/05/powershell-ise-cream/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tobias and Idera make PowerShellPlus 2.1 Beta Public.</title>
		<link>http://karlprosser.com/coder/2009/02/03/tobias-and-idera-make-powershellplus-21-beta-public/</link>
		<comments>http://karlprosser.com/coder/2009/02/03/tobias-and-idera-make-powershellplus-21-beta-public/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 04:45:37 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Powershell Plus]]></category>
		<category><![CDATA[pscom]]></category>
		<category><![CDATA[PSV2]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2009/02/03/tobias-and-idera-make-powershellplus-21-beta-public/</guid>
		<description><![CDATA[Well its been six months or more since our baby PowerShell Plus grew up, left home and moved in with Idera. Well its been progressing nicely, and we are happy to see the vision being fulfilled,nd even expanded, with a successful commercial product. Go Tobias – Go Idera. Anyhow, I&#8217;m pretty much going to reblog [...]]]></description>
			<content:encoded><![CDATA[<p>Well its been six months or more since our baby PowerShell Plus grew up, left home and moved in with Idera. Well its been progressing nicely, and we are happy to see the vision being fulfilled,nd even expanded, with a successful commercial product. Go Tobias – Go Idera.</p>
<p>Anyhow, I&#8217;m pretty much going to reblog the content from Tobias’s blog entry below. If you haven’t tried PS+ yet. I recommend wholeheartedly that you do. It really is about 3 generations and a couple of years ahead of anything else out there. Other vendors have only recently implemented “borrowed” features that have been in PowerShell Analyzer and PowerShell Plus since 2006.</p>
<p><a href="http://powershell.com/cs/blogs/news/archive/2009/02/02/powershellplus-v2-1-beta-is-live.aspx" title="http://powershell.com/cs/blogs/news/archive/2009/02/02/powershellplus-v2-1-beta-is-live.aspx">http://powershell.com/cs/blogs/news/archive/2009/02/02/powershellplus-v2-1-beta-is-live.aspx</a></p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>Exciting news! Effective immediately, PowerShellPlus v2.1 Beta is live and publicly available! Below you will find exciting information about an early look at what the PowerShellPlus team has been working on.</p>
<p><img src="http://powershell.com/cs/cfs-file.ashx/__key/CommunityServer.Components.UserFiles/00.00.00.21.03/psp213.png" /></p>
<p>PowerShellPlus version 2.1 introduces several new and cool features focused on reducing the PowerShell learning curve, increasing the productivity of PowerShell development and exercising the capabilities of PowerShell 2.0. The new features include:</p>
<ul>
<li><strong>Code sharing </strong>– Enables you to leverage the wealth of scripts that reside in the PowerShell.com and PoshCode.org libraries. Increase your productivity by quickly and easily searching and grabbing the scripts from those libraries. You can also submit your own scripts to the PowerShell.com library directly from PowerShell Plus Editor</li>
<li><strong>Visual Basic support </strong>– The PowerShell Plus Editor can now edit and run Visual Basic scripts</li>
<li><strong>STA mode support </strong>– Enables you to produce pretty cool looking GUI’s with Windows Presentation Framework (WPF) using PowerShell 2.0.</li>
<li><strong>PowerShell Assembly Detection </strong>– Gives the Learning Center an auto-upgrade path if PowerShell v2 CTP3 is detected and then displays the most up-to-date information</li>
<li><strong>Learning Center Auto-Load &#8211; </strong>Makes searching for a request with a single match much easier to use since the topic will load automatically, saving extra keystrokes</li>
<li><strong>Cmdlet parameter position – </strong>Shows you additional information in the code completion popup window about parameters including position and type</li>
<li><strong>Console size overlay </strong>– Shows you the height and width of the Console when you resize it</li>
<li><strong>Additional Sample Scripts </strong>- Active Directory, IIS 7.0 and MySQL</li>
<li><strong>PowerShell v2 CTP3 Support </strong>– Including Block Comments and the $Profile variable</li>
</ul>
<p><strong>How to get the New Version</p>
<p></strong>Use the link at the bottom of this page to download the installation package, but before you do please read the following disclaimers, warnings and other general portents of doom.</p>
<ul>
<li><strong>This software is a pre-release version and should not be deployed in a production environment. It will not work the way a final version of the software does. Features will change before the final release</strong></li>
<li>If you already have a PowerShellPlus license we recommend that you install this version on another machine, but we do support an upgrade in place your production version.</li>
<li>If you upgrade your production version of 2.0 we will not overwrite any user customizations that have been made to PowerShellPlus but we do recommend you make a copy of the Sample scripts if you have modified them.</li>
<li>A list of the changes is provided in the Release Notes in the Installation Package.</li>
<li>This release is designed to provide the PowerShellPlus community with a preview of key features coming in 2.1 and to solicit feedback about them. This Technical Beta is not supported by the Idera Technical Support Team. Please visit the Beta Place: <a href="http://powershell.com/cs/forums/93.aspx">http://powershell.com/cs/forums/93.aspx</a></li>
</ul>
<p><strong>System Requirements </strong></p>
<ul>
<li>Microsoft Windows PowerShell Version 1 or Version 2 CTP2 or CTP3</li>
<li>Windows XP, Server 2003, Windows Vista, Server 2008, Windows 7</li>
</ul>
<p><strong>Installation Instructions </strong></p>
<p>To install PowerShellPlus:</p>
<ol>
<li>Click the link at the bottom of this page and complete the download form</li>
<li>An email will be sent with instructions on how to download the Beta.</li>
<li>After downloading the Beta, unzip the contents of the Installer package.</li>
<li>Read the Release Notes for late breaking information about the Beta.</li>
<li>If you are upgrading from PowerShellPlus 2.0 make that you copy the Sample Scripts to another location, if you have modified them.</li>
<li>Run the Setup.exe program to install PowerShellPlus 2.1.</li>
</ol>
<p>Grab your copy now:</p>
<p><a href="https://www.idera.com/Content/Show.aspx?PageID=2&amp;PurchaseType=DLNowAdd&amp;AddProdID=9000">Download Here</a></p>
<p>For feedback, bug reports, suggestions and discussions regarding this beta release, please visit and use our Beta Place:</p>
<p><a href="http://powershell.com/cs/forums/93.aspx">http://powershell.com/cs/forums/93.aspx</a></p>
<p>Enjoy!</p>
<p>-Tobias</p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2009/02/03/tobias-and-idera-make-powershellplus-21-beta-public/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Debugging Realtime by Ear. Adding one more dimension</title>
		<link>http://karlprosser.com/coder/2009/01/30/debugging-realtime-by-ear-adding-one-more-dimension/</link>
		<comments>http://karlprosser.com/coder/2009/01/30/debugging-realtime-by-ear-adding-one-more-dimension/#comments</comments>
		<pubDate>Fri, 30 Jan 2009 08:07:29 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2009/01/30/debugging-realtime-by-ear-adding-one-more-dimension/</guid>
		<description><![CDATA[I am amazed by people who can pick out every single note and chord when listening to music, and others who can totally play by ear. However even the musically inept and tone-deaf of us can detect an odd note, especially if its in a tune we know, but often even in an unknown tune, [...]]]></description>
			<content:encoded><![CDATA[<p>I am amazed by people who can pick out every single note and chord when listening to music, and others who can totally play by ear. However even the musically inept and tone-deaf of us can detect an odd note, especially if its in a tune we know, but often even in an unknown tune, we can detect an out of place note, that isn&#8217;t in the scale, whether we know what a scale is, or even what key the song is in.</p>
<p>So what&#8217;s this got to do with debugging? We&#8217;ll mostly it’s the real time aspect. You are able to process a lot of information (notes), in context, and are able to discern real-time what is out of place and wrong.</p>
<p>Compare that to typical debugging. You might use checkpoints, and tracing through code, slowing down the execution often a million-fold, tediously stepping through each line of code, looking here and there.<br />
Alternatively you might be processing log output, whether a debug stream in your IDE, console output, or something else. However just getting those messages to somewhere you can display can be hard when threading, and you aren&#8217;t in the GUI thread etc.<br />
Additionally you are having to interpret this, often after the fact, and you can often miss things when lots is going on. How often , especially when finding a rare threading bug, are you running something 10 or more times, and maybe logging 10 or so different events each time. Going through the log takes time, and sometimes you miss the cue.</p>
<p>So, is debugging with sounds going to change and revolutionize everything? No its just another tool in a really great toolkit we have these days.</p>
<p>I thank my friend Oisin Grehan (<a href="http://nivot.org">http://nivot.org</a> ) for inspiring this as I don&#8217;t think I&#8217;ve used sound in debugging since the my  <a href="http://en.wikipedia.org/wiki/Demoscene">Demoscene</a>  days when I was coding MOD players. <a href="http://en.wikipedia.org/wiki/Tracker">Mod Players</a> . So naturaller the tracker syntax has inspired me a bit.</p>
<p> <img src="http://tutorials.renoise.com/uploads/Renoise/vvoois_fasttracker.s.gif" /></p>
<p><strong>So how does this work. Well work out the steps you are listening to, and maybe things you particularly want to catch, play the notes over and over a few times so you know mentality what to expect, then just start running you code, and listen to what actually IS happening, and then maybe at certain times you might make a certain note MEAN something (like middle  C  for TRUE function result and middle A for FALSE), but I typically just use notices to indicate execution flow, and if I want to know some value, I ask windows Speech API to help me out. </strong></p>
<pre><span style="color: #0000ff">function</span><span style="color: #000000"> </span><span style="color: #008080">Play-Note</span><span style="color: #000000">([</span><span style="color: #0000ff">string</span><span style="color: #000000">]</span><span style="color: #0000ff">$note</span><span style="color: #000000">,[</span><span style="color: #0000ff">int</span><span style="color: #000000">] </span><span style="color: #0000ff">$duration</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #ff0000">5</span><span style="color: #000000">)
{
  </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #000000">!</span><span style="color: #000000">(</span><span style="color: #0000ff">$note</span><span style="color: #000000"> </span><span style="color: #0000ff">-match</span><span style="color: #000000"> </span><span style="color: #000080">'</span><span style="color: #000080">(\d+)</span><span style="color: #000080">'</span><span style="color: #000000">)) { </span><span style="color: #0000ff">$note</span><span style="color: #000000">+=</span><span style="color: #000080">'</span><span style="color: #000080">4</span><span style="color: #000080">'</span><span style="color: #000000"> };[void](</span><span style="color: #0000ff">$note</span><span style="color: #000000"> </span><span style="color: #0000ff">-match</span><span style="color: #000000"> </span><span style="color: #000080">'</span><span style="color: #000080">([A-G#]{1,2})(\d+)</span><span style="color: #000080">'</span><span style="color: #000000">)
  [console]::Beep((</span><span style="color: #ff0000">440</span><span style="color: #000000"> </span><span style="color: #000000">*</span><span style="color: #000000"> [math]::Pow([math]::pow(</span><span style="color: #ff0000">2</span><span style="color: #000000">,(</span><span style="color: #ff0000">1</span><span style="color: #000000">/</span><span style="color: #ff0000">12</span><span style="color: #000000">)),
    (([</span><span style="color: #0000ff">int</span><span style="color: #000000">] </span><span style="color: #0000ff">$matches</span><span style="color: #000000">[</span><span style="color: #ff0000">2</span><span style="color: #000000">]) </span><span style="color: #000000">-</span><span style="color: #000000"> </span><span style="color: #ff0000">4</span><span style="color: #000000">)</span><span style="color: #000000">*</span><span style="color: #000000"> </span><span style="color: #ff0000">12</span><span style="color: #000000"> </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #0000ff">$</span><span style="color: #000000">( </span><span style="color: #0000ff">switch</span><span style="color: #000000">(</span><span style="color: #0000ff">$matches</span><span style="color: #000000">[</span><span style="color: #ff0000">1</span><span style="color: #000000">])
  {  </span><span style="color: #000080">'</span><span style="color: #000080">A</span><span style="color: #000080">'</span><span style="color: #000000">  { </span><span style="color: #ff0000">0</span><span style="color: #000000"> }  </span><span style="color: #000080">'</span><span style="color: #000080">A#</span><span style="color: #000080">'</span><span style="color: #000000"> { </span><span style="color: #ff0000">1</span><span style="color: #000000"> }  </span><span style="color: #000080">'</span><span style="color: #000080">Bb</span><span style="color: #000080">'</span><span style="color: #000000"> { </span><span style="color: #ff0000">1</span><span style="color: #000000"> }  </span><span style="color: #000080">'</span><span style="color: #000080">B</span><span style="color: #000080">'</span><span style="color: #000000">  { </span><span style="color: #ff0000">2</span><span style="color: #000000"> }  </span><span style="color: #000080">'</span><span style="color: #000080">C</span><span style="color: #000080">'</span><span style="color: #000000">  { </span><span style="color: #ff0000">3</span><span style="color: #000000"> }  </span><span style="color: #000080">'</span><span style="color: #000080">C#</span><span style="color: #000080">'</span><span style="color: #000000"> { </span><span style="color: #ff0000">4</span><span style="color: #000000"> }  </span><span style="color: #000080">'</span><span style="color: #000080">Db</span><span style="color: #000080">'</span><span style="color: #000000"> { </span><span style="color: #ff0000">4</span><span style="color: #000000"> }
     </span><span style="color: #000080">'</span><span style="color: #000080">D</span><span style="color: #000080">'</span><span style="color: #000000">  { </span><span style="color: #ff0000">5</span><span style="color: #000000"> }  </span><span style="color: #000080">'</span><span style="color: #000080">D#</span><span style="color: #000080">'</span><span style="color: #000000"> { </span><span style="color: #ff0000">6</span><span style="color: #000000"> }  </span><span style="color: #000080">'</span><span style="color: #000080">Eb</span><span style="color: #000080">'</span><span style="color: #000000"> { </span><span style="color: #ff0000">6</span><span style="color: #000000"> }  </span><span style="color: #000080">'</span><span style="color: #000080">E</span><span style="color: #000080">'</span><span style="color: #000000">  { </span><span style="color: #ff0000">7</span><span style="color: #000000"> }  </span><span style="color: #000080">'</span><span style="color: #000080">F</span><span style="color: #000080">'</span><span style="color: #000000">  { </span><span style="color: #ff0000">8</span><span style="color: #000000"> }  </span><span style="color: #000080">'</span><span style="color: #000080">F#</span><span style="color: #000080">'</span><span style="color: #000000"> { </span><span style="color: #ff0000">9</span><span style="color: #000000"> }  </span><span style="color: #000080">'</span><span style="color: #000080">Gb</span><span style="color: #000080">'</span><span style="color: #000000"> { </span><span style="color: #ff0000">9</span><span style="color: #000000"> }
     </span><span style="color: #000080">'</span><span style="color: #000080">G</span><span style="color: #000080">'</span><span style="color: #000000">  { </span><span style="color: #ff0000">10</span><span style="color: #000000"> } </span><span style="color: #000080">'</span><span style="color: #000080">G#</span><span style="color: #000080">'</span><span style="color: #000000"> { </span><span style="color: #ff0000">11</span><span style="color: #000000"> } </span><span style="color: #000080">'</span><span style="color: #000080">Ab</span><span style="color: #000080">'</span><span style="color: #000000"> { </span><span style="color: #ff0000">11</span><span style="color: #000000"> }
  }))),</span><span style="color: #0000ff">$duration</span><span style="color: #000000"> </span><span style="color: #000000">*</span><span style="color: #000000"> </span><span style="color: #ff0000">100</span><span style="color: #000000"> )
}
</span></pre>
<p>So two things. I’ve based the notes on common tracker syntax including the octave. so middle A is A4 , then you have things like F#3 etc. however if as with everything PowerShell we want pithy, so if you don’t put an octave number then it will be 4 by default.</p>
<p>play-note C ; play-note Eb ; play-note &#8220;C#”</p>
<p>also i included a duration, so if the want the note to be anything but the default half a second put that as a parameter</p>
<p>play-note Eb4 20</p>
<p>and you’ll get an E flat for 2 whole seconds. You may ask why I don’t use seconds or milliseconds, because those are our official measurements in this 1,000,000 3 grouped western world. Well the reason is pithiness (something i love in my scripts, but aren’t good about when it comes to blogging). Typically i want a note between say 300 milliseconds and 5 seconds. so if i used milliseconds i’d always have to have those 2 or 3 extra zeros, while if i used seconds I&#8217;d be doing things like 0.4 and 1.5. If Japanese and Chinese we often communicate number differently, and group them differently. so there is a word for 10,000 , so to say 15 thousand you may say 1 (character for 10,000) 5.</p>
<p>So what about voice. You can use a very simple function using the SAPI COM objects such as:</p>
<pre><span style="color: #0000ff">function</span><span style="color: #000000"> </span><span style="color: #008080">Speak-words</span><span style="color: #000000"> ([</span><span style="color: #0000ff">string</span><span style="color: #000000">]</span><span style="color: #0000ff">$words</span><span style="color: #000000">,[</span><span style="color: #0000ff">bool</span><span style="color: #000000">]</span><span style="color: #0000ff">$pause</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$true</span><span style="color: #000000">)
{   </span><span style="color: #0000ff">$flag</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #ff0000">1</span><span style="color: #000000">
    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$pause</span><span style="color: #000000">) {</span><span style="color: #0000ff">$flag</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #ff0000">2</span><span style="color: #000000">}
    </span><span style="color: #0000ff">$voice</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #008080">new-Object</span><span style="color: #000000"> </span><span style="color: #000000">-</span><span style="color: #008080">com</span><span style="color: #000000"> SAPI.spvoice
    </span><span style="color: #0000ff">$voice</span><span style="color: #000000">.speak(</span><span style="color: #0000ff">$words</span><span style="color: #000000">, [</span><span style="color: #0000ff">int</span><span style="color: #000000">] </span><span style="color: #0000ff">$flag</span><span style="color: #000000">)
    </span><span style="color: #008000">#</span><span style="color: #008000"> 2 means wait until speaking is finished to continue</span><span style="color: #008000">
</span><span style="color: #000000">}
</span></pre>
<p>Typically though i don’t create a $voice everytime , but kept a reference somewhere , like in my V2 module. Others however have done more impressive things with the voice in powershell ( <a href="http://poshcode.org/667" title="http://poshcode.org/667">http://poshcode.org/667</a> | <a href="http://huddledmasses.org/powershell-speaks/" title="http://huddledmasses.org/powershell-speaks/">http://huddledmasses.org/powershell-speaks/</a> ).</p>
<p>So now you may want a way to play more notes and speak more words together, in a pithy line. you can just use play-notes</p>
<pre><span style="color: #0000ff">function</span><span style="color: #000000"> </span><span style="color: #008080">Play-Notes</span><span style="color: #000000">
{
</span><span style="color: #0000ff">$defaultduration</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #ff0000">5</span><span style="color: #000000">;</span><span style="color: #0000ff">if</span><span style="color: #000000">(</span><span style="color: #0000ff">$args</span><span style="color: #000000">[</span><span style="color: #ff0000">0</span><span style="color: #000000">] </span><span style="color: #0000ff">-is</span><span style="color: #000000"> [</span><span style="color: #0000ff">int</span><span style="color: #000000">]) {</span><span style="color: #0000ff">$defaultduration</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$args</span><span style="color: #000000">[</span><span style="color: #ff0000">0</span><span style="color: #000000">]}
</span><span style="color: #0000ff">for</span><span style="color: #000000">(</span><span style="color: #0000ff">$i</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #ff0000">0</span><span style="color: #000000">;</span><span style="color: #0000ff">$i</span><span style="color: #000000"> </span><span style="color: #0000ff">-lt</span><span style="color: #000000"> </span><span style="color: #0000ff">$args</span><span style="color: #000000">.length;</span><span style="color: #0000ff">$i</span><span style="color: #000000">++</span><span style="color: #000000">)
 {    </span><span style="color: #0000ff">$duration</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$defaultduration</span><span style="color: #000000">
    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$i</span><span style="color: #000000"> </span><span style="color: #0000ff">-lt</span><span style="color: #000000"> </span><span style="color: #0000ff">$args</span><span style="color: #000000">.length</span><span style="color: #000000">-</span><span style="color: #ff0000">1</span><span style="color: #000000">) { </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$args</span><span style="color: #000000">[</span><span style="color: #0000ff">$i</span><span style="color: #000000">+</span><span style="color: #ff0000">1</span><span style="color: #000000">] </span><span style="color: #0000ff">-is</span><span style="color: #000000"> [</span><span style="color: #0000ff">int</span><span style="color: #000000">]) {</span><span style="color: #0000ff">$duration</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$args</span><span style="color: #000000">[</span><span style="color: #0000ff">$i</span><span style="color: #000000">+</span><span style="color: #ff0000">1</span><span style="color: #000000">] } }
    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$args</span><span style="color: #000000">[</span><span style="color: #0000ff">$i</span><span style="color: #000000">] </span><span style="color: #0000ff">-is</span><span style="color: #000000"> [</span><span style="color: #0000ff">string</span><span style="color: #000000">]) {
        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$args</span><span style="color: #000000">[</span><span style="color: #0000ff">$i</span><span style="color: #000000">].startswith(</span><span style="color: #000080">"</span><span style="color: #000080">!</span><span style="color: #000080">"</span><span style="color: #000000">)) { </span><span style="color: #008080">speak-words</span><span style="color: #000000"> </span><span style="color: #0000ff">$args</span><span style="color: #000000">[</span><span style="color: #0000ff">$i</span><span style="color: #000000">].replace(</span><span style="color: #000080">'</span><span style="color: #000080">!</span><span style="color: #000080">'</span><span style="color: #000000">,</span><span style="color: #000080">''</span><span style="color: #000000">) } </span><span style="color: #0000ff">else</span><span style="color: #000000">
        { </span><span style="color: #008080">play-note</span><span style="color: #000000"> </span><span style="color: #0000ff">$args</span><span style="color: #000000">[</span><span style="color: #0000ff">$i</span><span style="color: #000000">] </span><span style="color: #0000ff">$duration</span><span style="color: #000000"> }
        }
 }
}
</span></pre>
<p>And with this you can simply pass in a list of notes, which will be played with a default duration, unless you choose to specify a duration after the note.</p>
<p><span style="color: #008080">play-notes</span><span style="color: #000000"> A B C </span><span style="color: #ff0000">20</span><span style="color: #000000"> E </span><span style="color: #ff0000">10</span><span style="color: #000000"> B </span><span style="color: #ff0000">10</span><span style="color: #000000"></p>
<p><span style="color: #008080">play-notes</span><span style="color: #000000"> F5 </span><span style="color: #ff0000">2</span><span style="color: #000000"> E5 </span><span style="color: #ff0000">2</span><span style="color: #000000"> D5 </span><span style="color: #ff0000">2</span><span style="color: #000000"> C5 </span><span style="color: #ff0000">2</span><span style="color: #000000"> B5 </span><span style="color: #ff0000">2</span><span style="color: #000000"> A5 </span><span style="color: #ff0000">2</span><span style="color: #000000"> G </span><span style="color: #ff0000">4</span><span style="color: #000000"> F5 </span><span style="color: #ff0000">2</span><span style="color: #000000"> E5 </span><span style="color: #ff0000">2</span><span style="color: #000000"> D5 </span><span style="color: #ff0000">2</span><span style="color: #000000"> C5 </span><span style="color: #ff0000">2</span><span style="color: #000000"> B5 </span><span style="color: #ff0000">2</span><span style="color: #000000"> A5 </span><span style="color: #ff0000">2</span><span style="color: #000000"> G </span><span style="color: #ff0000">4</span><span style="color: #000000"> </span></span></p>
<p>If you want to change the default duration to reduce the redundancy above, just put that number as the first parameter</p>
<p><span style="color: #008080">play-notes</span><span style="color: #000000"> </span><span style="color: #ff0000">2</span><span style="color: #000000"> F5 E5 D5 C5 B5 A5 G </span><span style="color: #ff0000">4</span><span style="color: #000000"> F5 E5 D5 C5 B5 A5 G </span><span style="color: #ff0000">4</span><span style="color: #000000"> </span></p>
<p>and finally if you want some speaking in there, just have your string start with an exclamation mark!</p>
<pre><span style="color: #008080">play-notes</span><span style="color: #000000"> </span><span style="color: #000080">"</span><span style="color: #000080">!here we go now</span><span style="color: #000080">"</span><span style="color: #000000"> Db5 Db Eb Gb Ab </span><span style="color: #000080">"</span><span style="color: #000080">C#</span><span style="color: #000080">"</span><span style="color: #000000"> </span><span style="color: #ff0000">6</span><span style="color: #000000"> </span><span style="color: #000080">!YEAH</span><span style="color: #000000">
</span></pre>
<p>But of course most of the time you will have speaking, you’ll want it to say something you don’t know like a variable or the results of a formula.</p>
<p><span style="color: #008080">play-notes</span><span style="color: #000000"> A</span><span style="color: #000080">&#8220;</span><span style="color: #000080">!$([datetime]::now)</span><span style="color: #000080">&#8220;</span><span style="color: #000000"> C</p>
<p></span></p>
<p><span style="color: #000000">So you can get all these functions together at poshcode. ( <a href="http://poshcode.org/835">Script</a> | <a href="http://poshcode.org/get/835">Download</a> )  . We’ll time will tell if this will stay a habit of mine or be a fad. Additionally if you wanted to take this seriously you’d probably want to use something better than console.beep , maybe you’d use a full on MOD engine like <a href="http://fmod.org/" title="http://fmod.org/">http://fmod.org/</a> and having it running iringn a different process, and have a very cpu lightweight IPC going on, and different threads could play different channels, so between threads you could debug via Chords if you really have the ear for it.</span></p>
<p><span style="color: #000000"><strong>WARNING, NOT A CUBICLE FRIENDLY DEBUGGING TECHNIQUE WITHOUT HEADPHONES UNLESS YOU WANT YOUR COLLEGUES TO DEBUG YOU.</strong></span></p>
<p><span style="color: #000000">Enjoy,</p>
<p></span><span style="color: #000000">Karl</span></p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2009/01/30/debugging-realtime-by-ear-adding-one-more-dimension/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerSMUG &#8211; Syncronize folders on your machine with Smugmug.</title>
		<link>http://karlprosser.com/coder/2009/01/12/powersmug-syncronize-folders-on-your-machine-with-smugmug/</link>
		<comments>http://karlprosser.com/coder/2009/01/12/powersmug-syncronize-folders-on-your-machine-with-smugmug/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 05:36:11 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2009/01/12/powersmug-syncronize-folders-on-your-machine-with-smugmug/</guid>
		<description><![CDATA[In ShellTools most of you were familiar with only Tobias Weltner and Myself, however behind the scenes was a critical cofounder – Eddie Hadjes. Below is a script Eddie wrote a few months back to synchronize data between your local folders and the excellent SmugMug web album service. You can always get the latest version [...]]]></description>
			<content:encoded><![CDATA[<p>In ShellTools most of you were familiar with only Tobias Weltner and Myself, however behind the scenes was a critical cofounder – Eddie Hadjes. Below is a script Eddie wrote a few months back to synchronize data between your local folders and the excellent <a href="http://smugmug.com/">SmugMug</a> web album service. You can always get the latest version and info on our <a href="http://shelltools.wik.is/Other_Projects/PowerSmug">wiki</a>. </p>
<p> Script @ PoshCode: <a href="http://poshcode.org/796">View Script</a> | <a href="http://poshcode.org/get/796">Download</a></p>
<p> <script>function fbs_click() {u=location.href;t=document.title;window.open(\'http://www.facebook.com/sharer.php?u=\'+encodeURIComponent(u)+\'&#038;t=\'+encodeURIComponent(t),\'sharer\',\'toolbar=0,status=0,width=626,height=436\');return false;}</script></p>
<style> html .fb_share_link { padding:2px 0 0 20px; height:16px; background:url(http://b.static.ak.fbcdn.net/images/share/facebook_share_icon.gif?7:26981) no-repeat top left; }</style>
<p><a href="http://www.facebook.com/share.php?u=&lt;url&gt;" onclick="return fbs_click()" target="_blank" class="fb_share_link">Share on Facebook</a></p>
<p> </p>
<p>&#8212;-</p>
<pre><span style="color: #008000">#</span><span style="color: #008000"> PowerSmug photo sync script v1.0</span><span style="color: #008000">
#</span><span style="color: #008000"> This PowerShell script will syncronize a folder of images with a users SmugMug account</span><span style="color: #008000">
#</span><span style="color: #008000"> Please set the appropriate variables in the User Defined Variables region</span><span style="color: #008000">
#</span><span style="color: #008000"> For more information visit </span><span style="color: #008000; text-decoration: underline">http://shelltools.wik.is/Other_Projects/PowerSmug</span><span style="color: #008000">
#
#</span><span style="color: #008000"> Images are uploaded to a gallery with the same name as the folder they are contained in.</span><span style="color: #008000">
#</span><span style="color: #008000"> All folders below the Photo Directory path and the images they contain will be uploaded to SmugMug</span><span style="color: #008000">
#</span><span style="color: #008000"> Folders that end in _ are ignored, so if you don't want to sync a folder with SmugMug, just add an underscore at the end</span><span style="color: #008000">
#
#</span><span style="color: #008000"> Copyright 2008 Shell Tools, LLC</span><span style="color: #008000">
</span><span style="color: #000000">
</span><span style="color: #0000ff">#Region</span><span style="color: #000000"> User Defined Variables</span><span style="color: #000000">

</span><span style="color: #0000ff">$ApiKey</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000080">'</span><span style="color: #000080">uVUvCbXP3f6MgO9wIRJn21YCIgEidVly</span><span style="color: #000080">'</span><span style="color: #000000">
</span><span style="color: #0000ff">$EmailAddress</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000080">'</span><span style="color: #000080">[SmugMug Email]</span><span style="color: #000080">'</span><span style="color: #000000">
</span><span style="color: #0000ff">$Password</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000080">'</span><span style="color: #000080">[SmugMug Password]</span><span style="color: #000080">'</span><span style="color: #000000">
</span><span style="color: #0000ff">$PhotoDirectory</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000080">'</span><span style="color: #000080">[Path To Photos]</span><span style="color: #000080">'</span><span style="color: #000000">
</span><span style="color: #0000ff">$filesToInclude</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> @(</span><span style="color: #000080">'</span><span style="color: #000080">*.jpg</span><span style="color: #000080">'</span><span style="color: #000000">,</span><span style="color: #000080">'</span><span style="color: #000080">*.png</span><span style="color: #000080">'</span><span style="color: #000000">,</span><span style="color: #000080">'</span><span style="color: #000080">*.tif</span><span style="color: #000080">'</span><span style="color: #000000">,</span><span style="color: #000080">'</span><span style="color: #000080">*.cr2</span><span style="color: #000080">'</span><span style="color: #000000">)
</span><span style="color: #0000ff">$worldSearchable</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #ff0000">1</span><span style="color: #000000">
</span><span style="color: #0000ff">$smugSearchable</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #ff0000">1</span><span style="color: #000000">

</span><span style="color: #008000">#</span><span style="color: #008000"> Professional Accounts Only</span><span style="color: #008000">
</span><span style="color: #0000ff">$watermark</span><span style="color: #000000">=</span><span style="color: #ff0000">0</span><span style="color: #000000">
</span><span style="color: #0000ff">$watermarkId</span><span style="color: #000000">=</span><span style="color: #ff0000">0</span><span style="color: #000000">

</span><span style="color: #008000">#</span><span style="color: #008000">Email Variables</span><span style="color: #008000">
</span><span style="color: #0000ff">$smtpServer</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000080">'</span><span style="color: #000080">[SMTP Server]</span><span style="color: #000080">'</span><span style="color: #000000">
</span><span style="color: #0000ff">$smtpUser</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000080">'</span><span style="color: #000080">[SMTP User]</span><span style="color: #000080">'</span><span style="color: #000000">
</span><span style="color: #0000ff">$smtpPassword</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000080">'</span><span style="color: #000080">[SMTP Password]</span><span style="color: #000080">'</span><span style="color: #000000">
</span><span style="color: #0000ff">$smtpFrom</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000080">'</span><span style="color: #000080">PowerSmug@shelltools.net</span><span style="color: #000080">'</span><span style="color: #000000">

</span><span style="color: #0000ff">#EndRegion</span><span style="color: #000000">

</span><span style="color: #0000ff">#Region</span><span style="color: #000000"> Global Variables</span><span style="color: #000000">

</span><span style="color: #0000ff">$baseUrl</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000080">'</span><span style="color: #000080">http://api.smugmug.com/hack/rest/1.2.0/</span><span style="color: #000080">'</span><span style="color: #000000">
</span><span style="color: #0000ff">$userAgent</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000080">'</span><span style="color: #000080">PowerSmug v1.0</span><span style="color: #000080">'</span><span style="color: #000000">
</span><span style="color: #0000ff">$logFile</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000080">'</span><span style="color: #000080">PowerSmug.log</span><span style="color: #000080">'</span><span style="color: #000000">
</span><span style="color: #0000ff">$script:SessionId</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$null</span><span style="color: #000000">
</span><span style="color: #0000ff">$script:startStringState</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$false</span><span style="color: #000000">
</span><span style="color: #0000ff">$script:valueState</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$false</span><span style="color: #000000">
</span><span style="color: #0000ff">$script:arrayState</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$false</span><span style="color: #000000">
</span><span style="color: #0000ff">$script:saveArrayState</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$false</span><span style="color: #000000">
</span><span style="color: #0000ff">$script:datFileDirty</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$false</span><span style="color: #000000">
</span><span style="color: #0000ff">$script:datFile</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> @()
</span><span style="color: #0000ff">$script:albumList</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$null</span><span style="color: #000000">
</span><span style="color: #0000ff">$script:imageList</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$null</span><span style="color: #000000">

</span><span style="color: #0000ff">#EndRegion</span><span style="color: #000000">

</span><span style="color: #0000ff">#region</span><span style="color: #000000"> Helper Functions</span><span style="color: #000000">

</span><span style="color: #0000ff">function</span><span style="color: #000000"> SendEmail([</span><span style="color: #0000ff">string</span><span style="color: #000000">] </span><span style="color: #0000ff">$to</span><span style="color: #000000">, [</span><span style="color: #0000ff">string</span><span style="color: #000000">] </span><span style="color: #0000ff">$subject</span><span style="color: #000000">, [</span><span style="color: #0000ff">string</span><span style="color: #000000">] </span><span style="color: #0000ff">$msg</span><span style="color: #000000">)
{
    </span><span style="color: #0000ff">$smtpMail</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #008080">new-Object</span><span style="color: #000000"> System.Net.Mail.SmtpClient </span><span style="color: #0000ff">$smtpServer</span><span style="color: #000000">
    </span><span style="color: #0000ff">$smtpMail</span><span style="color: #000000">.DeliveryMethod </span><span style="color: #000000">=</span><span style="color: #000000"> [System.Net.Mail.SmtpDeliveryMethod]</span><span style="color: #000080">'</span><span style="color: #000080">Network</span><span style="color: #000080">'</span><span style="color: #000000">
    </span><span style="color: #0000ff">$smtpMail</span><span style="color: #000000">.Credentials </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #008080">new-Object</span><span style="color: #000000"> System.Net.NetworkCredential </span><span style="color: #0000ff">$smtpUser</span><span style="color: #000000">, </span><span style="color: #0000ff">$smtpPassword</span><span style="color: #000000">

    </span><span style="color: #0000ff">$smtpMail</span><span style="color: #000000">.Send(</span><span style="color: #0000ff">$smtpFrom</span><span style="color: #000000">, </span><span style="color: #0000ff">$to</span><span style="color: #000000">, </span><span style="color: #0000ff">$subject</span><span style="color: #000000">, </span><span style="color: #0000ff">$msg</span><span style="color: #000000">)
}

</span><span style="color: #0000ff">function</span><span style="color: #000000"> </span><span style="color: #008080">Get-MD5</span><span style="color: #000000">([System.IO.FileInfo] </span><span style="color: #0000ff">$file</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$</span><span style="color: #000000">(Throw </span><span style="color: #000080">'</span><span style="color: #000080">Usage: Get-MD5 [System.IO.FileInfo]</span><span style="color: #000080">'</span><span style="color: #000000">))
{
    </span><span style="color: #008000">#</span><span style="color: #008000"> This Get-MD5 function sourced from:</span><span style="color: #008000">
</span><span style="color: #000000">    </span><span style="color: #008000">#</span><span style="color: #008000"> </span><span style="color: #008000; text-decoration: underline">http://blogs.msdn.com/powershell/archive/2006/04/25/583225.aspx</span><span style="color: #008000">
</span><span style="color: #000000">    </span><span style="color: #0000ff">$stream</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$null</span><span style="color: #000000">;
    </span><span style="color: #0000ff">$cryptoServiceProvider</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> [System.Security.Cryptography.MD5CryptoServiceProvider];
    </span><span style="color: #0000ff">$hashAlgorithm</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #008080">new-object</span><span style="color: #000000"> </span><span style="color: #0000ff">$cryptoServiceProvider</span><span style="color: #000000">
    </span><span style="color: #0000ff">$stream</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$file</span><span style="color: #000000">.OpenRead();
    </span><span style="color: #0000ff">$hashByteArray</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$hashAlgorithm</span><span style="color: #000000">.ComputeHash(</span><span style="color: #0000ff">$stream</span><span style="color: #000000">);
    </span><span style="color: #0000ff">$stream</span><span style="color: #000000">.Close();

    </span><span style="color: #008000">#</span><span style="color: #008000"># We have to be sure that we close the file stream if any exceptions are thrown.</span><span style="color: #008000">
</span><span style="color: #000000">    trap
    {
        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$stream</span><span style="color: #000000"> </span><span style="color: #0000ff">-ne</span><span style="color: #000000"> </span><span style="color: #0000ff">$null</span><span style="color: #000000">) { </span><span style="color: #0000ff">$stream</span><span style="color: #000000">.Close(); }
        </span><span style="color: #0000ff">break</span><span style="color: #000000">;
    }

    </span><span style="color: #008000">#</span><span style="color: #008000"> Convert the MD5 hash to Hex</span><span style="color: #008000">
</span><span style="color: #000000">    </span><span style="color: #0000ff">$hashByteArray</span><span style="color: #000000"> </span><span style="color: #000000">|</span><span style="color: #000000"> </span><span style="color: #0000ff">foreach</span><span style="color: #000000"> { </span><span style="color: #0000ff">$result</span><span style="color: #000000"> </span><span style="color: #000000">+=</span><span style="color: #000000"> </span><span style="color: #0000ff">$_</span><span style="color: #000000">.ToString(</span><span style="color: #000080">"</span><span style="color: #000080">X2</span><span style="color: #000080">"</span><span style="color: #000000">) }

    </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">$result</span><span style="color: #000000">
}

</span><span style="color: #0000ff">function</span><span style="color: #000000"> SendWebRequest([</span><span style="color: #0000ff">string</span><span style="color: #000000">]</span><span style="color: #0000ff">$method</span><span style="color: #000000">, </span><span style="color: #0000ff">$queryParams</span><span style="color: #000000">, </span><span style="color: #0000ff">$ssl</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$false</span><span style="color: #000000">)
{
    </span><span style="color: #0000ff">$url</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$baseUrl</span><span style="color: #000000">
    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$ssl</span><span style="color: #000000"> </span><span style="color: #0000ff">-eq</span><span style="color: #000000"> </span><span style="color: #0000ff">$true</span><span style="color: #000000">) {
        </span><span style="color: #0000ff">$url</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$url</span><span style="color: #000000">.Replace(</span><span style="color: #000080">"</span><span style="color: #000080">http</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #000080">"</span><span style="color: #000080">https</span><span style="color: #000080">"</span><span style="color: #000000">)
    }

    </span><span style="color: #0000ff">$url</span><span style="color: #000000"> </span><span style="color: #000000">+=</span><span style="color: #000000"> </span><span style="color: #000080">"</span><span style="color: #000080">?method=$method</span><span style="color: #000080">"</span><span style="color: #000000">

    </span><span style="color: #0000ff">foreach</span><span style="color: #000000"> (</span><span style="color: #0000ff">$key</span><span style="color: #000000"> </span><span style="color: #0000ff">in</span><span style="color: #000000"> </span><span style="color: #0000ff">$queryParams</span><span style="color: #000000">.Keys) {
        </span><span style="color: #0000ff">$url</span><span style="color: #000000"> </span><span style="color: #000000">+=</span><span style="color: #000000"> </span><span style="color: #000080">"</span><span style="color: #000080">&#038;$key=</span><span style="color: #000080">"</span><span style="color: #000000"> </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #0000ff">$queryParams</span><span style="color: #000000">[</span><span style="color: #0000ff">$key</span><span style="color: #000000">]
    }

    </span><span style="color: #0000ff">$wc</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #008080">New-Object</span><span style="color: #000000"> Net.WebClient

    </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.Headers.Add(</span><span style="color: #000080">"</span><span style="color: #000080">user-agent</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #0000ff">$userAgent</span><span style="color: #000000">)
    [xml]</span><span style="color: #0000ff">$webResult</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.DownloadString(</span><span style="color: #0000ff">$url</span><span style="color: #000000">)

    CheckResponseForError </span><span style="color: #0000ff">$webResult</span><span style="color: #000000">

    </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">$webResult</span><span style="color: #000000">.rsp
}

</span><span style="color: #008000">#</span><span style="color: #008000"> Adds image information to our data file</span><span style="color: #008000">
</span><span style="color: #0000ff">function</span><span style="color: #000000"> AddFile ([System.IO.FileInfo]</span><span style="color: #0000ff">$file</span><span style="color: #000000">, </span><span style="color: #0000ff">$smugId</span><span style="color: #000000">) { 

    </span><span style="color: #0000ff">$a</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #ff0000">1</span><span style="color: #000000"> </span><span style="color: #000000">|</span><span style="color: #000000"> </span><span style="color: #008080">Select-Object</span><span style="color: #000000"> Name, SmugId, LastModifiedTime;
    </span><span style="color: #0000ff">$a</span><span style="color: #000000">.Name </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$file</span><span style="color: #000000">.Name
    </span><span style="color: #0000ff">$a</span><span style="color: #000000">.SmugId </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$smugId</span><span style="color: #000000">
    </span><span style="color: #0000ff">$a</span><span style="color: #000000">.LastModifiedTime </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$file</span><span style="color: #000000">.LastWriteTimeUtc.ToString()

    </span><span style="color: #0000ff">$script:datFile</span><span style="color: #000000"> </span><span style="color: #000000">+=</span><span style="color: #000000"> </span><span style="color: #0000ff">$a</span><span style="color: #000000">
</span><span style="color: #008000">#</span><span style="color: #008000">    $script:datFileDirty = $true</span><span style="color: #008000">
</span><span style="color: #000000">
    </span><span style="color: #008000">#</span><span style="color: #008000">we are now saving the file after each upload to prevent duplicates when there is a failure</span><span style="color: #008000">
</span><span style="color: #000000">    AppendDataFile </span><span style="color: #0000ff">$datFilePath</span><span style="color: #000000"> </span><span style="color: #0000ff">$a</span><span style="color: #000000">
}

</span><span style="color: #008000">#</span><span style="color: #008000"> writes the data file to the local directory</span><span style="color: #008000">
#</span><span style="color: #008000"> each directory will have a data file with information for images contained in it</span><span style="color: #008000">
</span><span style="color: #0000ff">function</span><span style="color: #000000"> SaveDataFile(</span><span style="color: #0000ff">$filePath</span><span style="color: #000000">, </span><span style="color: #0000ff">$clearFile</span><span style="color: #000000">=</span><span style="color: #0000ff">$true</span><span style="color: #000000">)
{
    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$script:datFileDirty</span><span style="color: #000000"> </span><span style="color: #0000ff">-eq</span><span style="color: #000000"> </span><span style="color: #0000ff">$false</span><span style="color: #000000">) { </span><span style="color: #0000ff">$script:datFile</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> @(); </span><span style="color: #0000ff">return</span><span style="color: #000000"> }

    [System.IO.File]::Delete(</span><span style="color: #0000ff">$filePath</span><span style="color: #000000">)

    </span><span style="color: #0000ff">$sortedFile</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$script:datFile</span><span style="color: #000000"> </span><span style="color: #000000">|</span><span style="color: #000000"> </span><span style="color: #008080">sort-Object</span><span style="color: #000000"> </span><span style="color: #000000">-</span><span style="color: #008080">property</span><span style="color: #000000"> Name
    </span><span style="color: #0000ff">$sortedFile</span><span style="color: #000000"> </span><span style="color: #000000">|</span><span style="color: #000000"> </span><span style="color: #008080">Export-Csv</span><span style="color: #000000"> </span><span style="color: #0000ff">$filePath</span><span style="color: #000000"> 

    </span><span style="color: #0000ff">$script:datFileDirty</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$false</span><span style="color: #000000">

    </span><span style="color: #008000">#</span><span style="color: #008000"> mark the file as hidden</span><span style="color: #008000">
</span><span style="color: #000000">    ls </span><span style="color: #0000ff">$filePath</span><span style="color: #000000"> </span><span style="color: #000000">|</span><span style="color: #000000"> </span><span style="color: #0000ff">foreach</span><span style="color: #000000"> { </span><span style="color: #0000ff">$_</span><span style="color: #000000">.Attributes </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$_</span><span style="color: #000000">.Attributes </span><span style="color: #0000ff">-bor</span><span style="color: #000000"> [System.IO.FileAttributes]::Hidden }

    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$clearFile</span><span style="color: #000000"> </span><span style="color: #0000ff">-eq</span><span style="color: #000000"> </span><span style="color: #0000ff">$true</span><span style="color: #000000">) {
        </span><span style="color: #008000">#</span><span style="color: #008000"> clear the variable</span><span style="color: #008000">
</span><span style="color: #000000">        </span><span style="color: #0000ff">$script:datFile</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> @()
    }
}

</span><span style="color: #008000">#</span><span style="color: #008000"> appends a new row to the data file</span><span style="color: #008000">
</span><span style="color: #0000ff">function</span><span style="color: #000000"> AppendDataFile(</span><span style="color: #0000ff">$filePath</span><span style="color: #000000">, </span><span style="color: #0000ff">$record</span><span style="color: #000000">)
{
    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #008080">test-Path</span><span style="color: #000000"> </span><span style="color: #0000ff">$datFilePath</span><span style="color: #000000">) {
        </span><span style="color: #0000ff">$newLine</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> [System.</span><span style="color: #0000ff">String</span><span style="color: #000000">]::Format(</span><span style="color: #000080">'</span><span style="color: #000080">{0},{1},"{2}"</span><span style="color: #000080">'</span><span style="color: #000000">, </span><span style="color: #0000ff">$a</span><span style="color: #000000">.Name, </span><span style="color: #0000ff">$a</span><span style="color: #000000">.SmugId, </span><span style="color: #0000ff">$a</span><span style="color: #000000">.LastModifiedTime)
        </span><span style="color: #008080">Add-Content</span><span style="color: #000000"> </span><span style="color: #0000ff">$filePath</span><span style="color: #000000"> </span><span style="color: #0000ff">$newLine</span><span style="color: #000000">
    }
    </span><span style="color: #0000ff">else</span><span style="color: #000000">
    {
        </span><span style="color: #0000ff">$script:datFileDirty</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$true</span><span style="color: #000000">
        SaveDataFile </span><span style="color: #0000ff">$filePath</span><span style="color: #000000"> </span><span style="color: #0000ff">$false</span><span style="color: #000000">
    }
}

</span><span style="color: #008000">#</span><span style="color: #008000"> ensure our web request was successful</span><span style="color: #008000">
</span><span style="color: #0000ff">function</span><span style="color: #000000"> CheckResponseForError(</span><span style="color: #0000ff">$xmlResponse</span><span style="color: #000000">)
{
    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$xmlResponse</span><span style="color: #000000">.rsp.stat </span><span style="color: #0000ff">-eq</span><span style="color: #000000"> </span><span style="color: #000080">'</span><span style="color: #000080">fail</span><span style="color: #000080">'</span><span style="color: #000000">)    {
        throw </span><span style="color: #0000ff">$webResult</span><span style="color: #000000">.rsp.err.msg
    }
}

</span><span style="color: #0000ff">#endregion</span><span style="color: #000000">

</span><span style="color: #0000ff">#region</span><span style="color: #000000"> Login/Logout</span><span style="color: #000000">

</span><span style="color: #0000ff">function</span><span style="color: #000000"> Login()
{
    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$script:SessionId</span><span style="color: #000000"> </span><span style="color: #0000ff">-ne</span><span style="color: #000000"> </span><span style="color: #0000ff">$null</span><span style="color: #000000">) { </span><span style="color: #0000ff">return</span><span style="color: #000000"> }

    </span><span style="color: #0000ff">$ht</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> @{APIKey</span><span style="color: #000000">=</span><span style="color: #0000ff">$ApiKey</span><span style="color: #000000">;EmailAddress</span><span style="color: #000000">=</span><span style="color: #0000ff">$EmailAddress</span><span style="color: #000000">;Password</span><span style="color: #000000">=</span><span style="color: #0000ff">$Password</span><span style="color: #000000">}
    </span><span style="color: #0000ff">$loginResult</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> SendWebRequest </span><span style="color: #000080">"</span><span style="color: #000080">smugmug.login.withPassword</span><span style="color: #000080">"</span><span style="color: #000000"> </span><span style="color: #0000ff">$ht</span><span style="color: #000000"> </span><span style="color: #0000ff">$true</span><span style="color: #000000">

    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$loginResult</span><span style="color: #000000">.stat </span><span style="color: #0000ff">-eq</span><span style="color: #000000"> </span><span style="color: #000080">"</span><span style="color: #000080">ok</span><span style="color: #000080">"</span><span style="color: #000000">) {
        </span><span style="color: #0000ff">$script:SessionId</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$loginResult</span><span style="color: #000000">.Login.Session.id
    }
    </span><span style="color: #0000ff">else</span><span style="color: #000000"> {
        Throw </span><span style="color: #000080">"</span><span style="color: #000080">Error on login: </span><span style="color: #000080">"</span><span style="color: #000000"> </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #0000ff">$loginResult</span><span style="color: #000000">.Message
    }
}

</span><span style="color: #0000ff">function</span><span style="color: #000000"> Logout()
{
    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$script:SessionId</span><span style="color: #000000"> </span><span style="color: #0000ff">-eq</span><span style="color: #000000"> </span><span style="color: #0000ff">$null</span><span style="color: #000000">) { </span><span style="color: #0000ff">return</span><span style="color: #000000"> }

    </span><span style="color: #0000ff">$ht</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> @{SessionID</span><span style="color: #000000">=</span><span style="color: #0000ff">$script:SessionId</span><span style="color: #000000">}
    </span><span style="color: #0000ff">$logoutResult</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> SendWebRequest </span><span style="color: #000080">"</span><span style="color: #000080">smugmug.logout</span><span style="color: #000080">"</span><span style="color: #000000"> </span><span style="color: #0000ff">$ht</span><span style="color: #000000">
}

</span><span style="color: #0000ff">#endregion</span><span style="color: #000000">

</span><span style="color: #0000ff">#region</span><span style="color: #000000"> Images</span><span style="color: #000000">

</span><span style="color: #008000">#</span><span style="color: #008000"> this method is only needed if we cannot find the PowerSmug.dat file.</span><span style="color: #008000">
#</span><span style="color: #008000"> preventing us from uploading duplicate images</span><span style="color: #008000">
</span><span style="color: #0000ff">function</span><span style="color: #000000"> GetImage(</span><span style="color: #0000ff">$name</span><span style="color: #000000">, </span><span style="color: #0000ff">$album</span><span style="color: #000000">)
{
    Login 

    </span><span style="color: #0000ff">$image</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$script:imageList</span><span style="color: #000000">.Images </span><span style="color: #000000">|</span><span style="color: #000000"> </span><span style="color: #008080">Where-Object</span><span style="color: #000000"> { </span><span style="color: #0000ff">$_</span><span style="color: #000000">.FileName </span><span style="color: #0000ff">-eq</span><span style="color: #000000"> </span><span style="color: #0000ff">$name</span><span style="color: #000000"> }
    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$image</span><span style="color: #000000"> </span><span style="color: #0000ff">-ne</span><span style="color: #000000"> </span><span style="color: #0000ff">$null</span><span style="color: #000000">) { </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">$image</span><span style="color: #000000"> }

    </span><span style="color: #008000">#</span><span style="color: #008000"> we are using heavy because we need the file name</span><span style="color: #008000">
</span><span style="color: #000000">    </span><span style="color: #0000ff">$ht</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> @{SessionID</span><span style="color: #000000">=</span><span style="color: #0000ff">$script:SessionId</span><span style="color: #000000">;AlbumID</span><span style="color: #000000">=</span><span style="color: #0000ff">$album</span><span style="color: #000000">.id;Heavy</span><span style="color: #000000">=</span><span style="color: #ff0000">1</span><span style="color: #000000">;AlbumKey</span><span style="color: #000000">=</span><span style="color: #0000ff">$album</span><span style="color: #000000">.Key}
    [xml]</span><span style="color: #0000ff">$script:imageList</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> SendWebRequest </span><span style="color: #000080">"</span><span style="color: #000080">smugmug.images.get</span><span style="color: #000080">"</span><span style="color: #000000"> </span><span style="color: #0000ff">$ht</span><span style="color: #000000">

    </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">$script:imageList</span><span style="color: #000000">.Images.Image </span><span style="color: #000000">|</span><span style="color: #000000"> </span><span style="color: #008080">Where-Object</span><span style="color: #000000"> { </span><span style="color: #0000ff">$_</span><span style="color: #000000">.FileName </span><span style="color: #0000ff">-eq</span><span style="color: #000000"> </span><span style="color: #0000ff">$name</span><span style="color: #000000"> }
}

</span><span style="color: #0000ff">function</span><span style="color: #000000"> UploadFile(</span><span style="color: #0000ff">$file</span><span style="color: #000000">, </span><span style="color: #0000ff">$albumName</span><span style="color: #000000">)
{
    </span><span style="color: #0000ff">$album</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> GetAlbum </span><span style="color: #0000ff">$albumName</span><span style="color: #000000">
    </span><span style="color: #008000">#</span><span style="color: #008000"> $image = GetImage $file.Name $album    </span><span style="color: #008000">
</span><span style="color: #000000">    </span><span style="color: #008000">#</span><span style="color: #008000"> if ($image -ne $null) { return $image.id }</span><span style="color: #008000">
</span><span style="color: #000000">
    </span><span style="color: #0000ff">$url</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000080">"</span><span style="color: #000080">http://upload.smugmug.com/</span><span style="color: #000080">"</span><span style="color: #000000"> </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #0000ff">$file</span><span style="color: #000000">.Name

    </span><span style="color: #0000ff">$wc</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #008080">New-Object</span><span style="color: #000000"> Net.WebClient

    </span><span style="color: #0000ff">$hash</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #008080">Get-MD5</span><span style="color: #000000"> </span><span style="color: #0000ff">$file</span><span style="color: #000000">

    </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.Headers.Add(</span><span style="color: #000080">"</span><span style="color: #000080">user-agent</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #0000ff">$userAgent</span><span style="color: #000000">)
    </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.Headers.Add(</span><span style="color: #000080">"</span><span style="color: #000080">ContentMd5</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #0000ff">$hash</span><span style="color: #000000">)
    </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.Headers.Add(</span><span style="color: #000080">"</span><span style="color: #000080">X-Smug-FileName</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #0000ff">$file</span><span style="color: #000000">.Name)
    </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.Headers.Add(</span><span style="color: #000080">"</span><span style="color: #000080">X-Smug-AlbumID</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #0000ff">$album</span><span style="color: #000000">.id)
    </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.Headers.Add(</span><span style="color: #000080">"</span><span style="color: #000080">X-Smug-SessionID</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #0000ff">$script:SessionId</span><span style="color: #000000">)
    </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.Headers.Add(</span><span style="color: #000080">"</span><span style="color: #000080">X-Smug-Version</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #000080">"</span><span style="color: #000080">1.2.0</span><span style="color: #000080">"</span><span style="color: #000000">)
    </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.Headers.Add(</span><span style="color: #000080">"</span><span style="color: #000080">X-Smug-ResponseType</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #000080">"</span><span style="color: #000080">REST</span><span style="color: #000080">"</span><span style="color: #000000">)
    </span><span style="color: #0000ff">$webResult</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.UploadFile(</span><span style="color: #0000ff">$url</span><span style="color: #000000">, </span><span style="color: #000080">"</span><span style="color: #000080">PUT</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #0000ff">$file</span><span style="color: #000000">.FullName)
    [xml]</span><span style="color: #0000ff">$webResult</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> [System.Text.Encoding]::ASCII.GetString(</span><span style="color: #0000ff">$webResult</span><span style="color: #000000">)

    CheckResponseForError </span><span style="color: #0000ff">$webResult</span><span style="color: #000000">

    </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">$webResult</span><span style="color: #000000">.rsp.Image.id
}

</span><span style="color: #0000ff">function</span><span style="color: #000000"> UploadExistingFile(</span><span style="color: #0000ff">$file</span><span style="color: #000000">, </span><span style="color: #0000ff">$id</span><span style="color: #000000">)
{
    Login 

    </span><span style="color: #0000ff">$url</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000080">"</span><span style="color: #000080">http://upload.smugmug.com/</span><span style="color: #000080">"</span><span style="color: #000000"> </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #0000ff">$file</span><span style="color: #000000">.Name

    </span><span style="color: #0000ff">$wc</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #008080">New-Object</span><span style="color: #000000"> Net.WebClient

    </span><span style="color: #0000ff">$hash</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #008080">Get-MD5</span><span style="color: #000000"> </span><span style="color: #0000ff">$file</span><span style="color: #000000">

    </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.Headers.Add(</span><span style="color: #000080">"</span><span style="color: #000080">user-agent</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #0000ff">$userAgent</span><span style="color: #000000">)
    </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.Headers.Add(</span><span style="color: #000080">"</span><span style="color: #000080">ContentMd5</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #0000ff">$hash</span><span style="color: #000000">)
    </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.Headers.Add(</span><span style="color: #000080">"</span><span style="color: #000080">X-Smug-FileName</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #0000ff">$file</span><span style="color: #000000">.Name)
    </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.Headers.Add(</span><span style="color: #000080">"</span><span style="color: #000080">X-Smug-ImageID</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #0000ff">$id</span><span style="color: #000000">)
    </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.Headers.Add(</span><span style="color: #000080">"</span><span style="color: #000080">X-Smug-SessionID</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #0000ff">$script:SessionId</span><span style="color: #000000">)
    </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.Headers.Add(</span><span style="color: #000080">"</span><span style="color: #000080">X-Smug-Version</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #000080">"</span><span style="color: #000080">1.2.0</span><span style="color: #000080">"</span><span style="color: #000000">)
    </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.Headers.Add(</span><span style="color: #000080">"</span><span style="color: #000080">X-Smug-ResponseType</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #000080">"</span><span style="color: #000080">REST</span><span style="color: #000080">"</span><span style="color: #000000">)
    </span><span style="color: #0000ff">$webResult</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$wc</span><span style="color: #000000">.UploadFile(</span><span style="color: #0000ff">$url</span><span style="color: #000000">, </span><span style="color: #000080">"</span><span style="color: #000080">PUT</span><span style="color: #000080">"</span><span style="color: #000000">, </span><span style="color: #0000ff">$file</span><span style="color: #000000">.FullName)

    [xml]</span><span style="color: #0000ff">$webResult</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> [System.Text.Encoding]::ASCII.GetString(</span><span style="color: #0000ff">$webResult</span><span style="color: #000000">)

    CheckResponseForError </span><span style="color: #0000ff">$webResult</span><span style="color: #000000">

    </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">$webResult</span><span style="color: #000000">.rsp
}

</span><span style="color: #0000ff">#endregion</span><span style="color: #000000">

</span><span style="color: #0000ff">#region</span><span style="color: #000000"> Album</span><span style="color: #000000">

</span><span style="color: #0000ff">function</span><span style="color: #000000"> GetAlbumList(</span><span style="color: #0000ff">$forceRefresh</span><span style="color: #000000">=</span><span style="color: #0000ff">$false</span><span style="color: #000000">) {
    Login

    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$forceRefresh</span><span style="color: #000000"> </span><span style="color: #0000ff">-eq</span><span style="color: #000000"> </span><span style="color: #0000ff">$false</span><span style="color: #000000">) {
        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$script:albumList</span><span style="color: #000000"> </span><span style="color: #0000ff">-ne</span><span style="color: #000000"> </span><span style="color: #0000ff">$null</span><span style="color: #000000">) { </span><span style="color: #0000ff">return</span><span style="color: #000000"> }
    }

    </span><span style="color: #0000ff">$ht</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> @{SessionID</span><span style="color: #000000">=</span><span style="color: #0000ff">$script:SessionId</span><span style="color: #000000">}
    </span><span style="color: #0000ff">$script:albumList</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> SendWebRequest </span><span style="color: #000080">"</span><span style="color: #000080">smugmug.albums.get</span><span style="color: #000080">"</span><span style="color: #000000"> </span><span style="color: #0000ff">$ht</span><span style="color: #000000">
}

</span><span style="color: #0000ff">function</span><span style="color: #000000"> GetAlbum(</span><span style="color: #0000ff">$name</span><span style="color: #000000">)
{
    </span><span style="color: #008000">#</span><span style="color: #008000">before we create an album ensure it doesn't already exist</span><span style="color: #008000">
</span><span style="color: #000000">    GetAlbumList

    </span><span style="color: #0000ff">$album</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$script:albumList</span><span style="color: #000000">.Albums.Album </span><span style="color: #000000">|</span><span style="color: #000000"> </span><span style="color: #008080">Where-Object</span><span style="color: #000000"> { </span><span style="color: #0000ff">$_</span><span style="color: #000000">.Title </span><span style="color: #0000ff">-eq</span><span style="color: #000000"> </span><span style="color: #0000ff">$name</span><span style="color: #000000"> }
    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$album</span><span style="color: #000000"> </span><span style="color: #0000ff">-ne</span><span style="color: #000000"> </span><span style="color: #0000ff">$null</span><span style="color: #000000">) { </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">$album</span><span style="color: #000000"> } 

    </span><span style="color: #008080">Write-Host</span><span style="color: #000000"> </span><span style="color: #000080">"</span><span style="color: #000080">Creating album: $name</span><span style="color: #000080">"</span><span style="color: #000000">
    </span><span style="color: #0000ff">$ht</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> @{SessionID</span><span style="color: #000000">=</span><span style="color: #0000ff">$script:SessionId</span><span style="color: #000000">;Title</span><span style="color: #000000">=</span><span style="color: #0000ff">$name</span><span style="color: #000000">;CategoryID</span><span style="color: #000000">=</span><span style="color: #ff0000">0</span><span style="color: #000000">;Public</span><span style="color: #000000">=</span><span style="color: #ff0000">0</span><span style="color: #000000">;
    X2Larges</span><span style="color: #000000">=</span><span style="color: #ff0000">0</span><span style="color: #000000">;X3Larges</span><span style="color: #000000">=</span><span style="color: #ff0000">0</span><span style="color: #000000">;Originals</span><span style="color: #000000">=</span><span style="color: #ff0000">0</span><span style="color: #000000">;Watermarking</span><span style="color: #000000">=</span><span style="color: #0000ff">$watermark</span><span style="color: #000000">;
    WatermarkID</span><span style="color: #000000">=</span><span style="color: #0000ff">$watermarkId</span><span style="color: #000000">;WorldSearchable</span><span style="color: #000000">=</span><span style="color: #0000ff">$worldSearchable</span><span style="color: #000000">;SmugSearchable</span><span style="color: #000000">=</span><span style="color: #0000ff">$smugSearchable</span><span style="color: #000000">}
    </span><span style="color: #0000ff">$result</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> SendWebRequest </span><span style="color: #000080">"</span><span style="color: #000080">smugmug.albums.create</span><span style="color: #000080">"</span><span style="color: #000000"> </span><span style="color: #0000ff">$ht</span><span style="color: #000000">

    </span><span style="color: #008000">#</span><span style="color: #008000"> be sure we refresh the album list after creation</span><span style="color: #008000">
</span><span style="color: #000000">    GetAlbumList </span><span style="color: #0000ff">$true</span><span style="color: #000000">

    </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">$result</span><span style="color: #000000">.Album
}

</span><span style="color: #0000ff">#endregion</span><span style="color: #000000">

</span><span style="color: #0000ff">#region</span><span style="color: #000000"> Process File</span><span style="color: #000000">

</span><span style="color: #0000ff">function</span><span style="color: #000000"> ProcessFile([System.IO.FileInfo]</span><span style="color: #0000ff">$file</span><span style="color: #000000">, </span><span style="color: #0000ff">$albumName</span><span style="color: #000000">)
{
    </span><span style="color: #0000ff">$photoObject</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$script:datFile</span><span style="color: #000000"> </span><span style="color: #000000">|</span><span style="color: #000000"> </span><span style="color: #008080">Where-Object</span><span style="color: #000000"> { </span><span style="color: #0000ff">$_</span><span style="color: #000000">.Name </span><span style="color: #0000ff">-eq</span><span style="color: #000000"> </span><span style="color: #0000ff">$file</span><span style="color: #000000">.Name }

    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$photoObject</span><span style="color: #000000"> </span><span style="color: #0000ff">-ne</span><span style="color: #000000"> </span><span style="color: #0000ff">$null</span><span style="color: #000000">) {
        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$photoObject</span><span style="color: #000000">.LastModifiedTime </span><span style="color: #0000ff">-ne</span><span style="color: #000000"> </span><span style="color: #0000ff">$file</span><span style="color: #000000">.LastWriteTimeUtc.ToString()) {
            </span><span style="color: #008000">#</span><span style="color: #008000"> file has been modified, so re-upload the file</span><span style="color: #008000">
</span><span style="color: #000000">            </span><span style="color: #008080">write-Host</span><span style="color: #000000"> </span><span style="color: #000080">"</span><span style="color: #000080">Updating existing file: </span><span style="color: #000080">"</span><span style="color: #000000"> </span><span style="color: #0000ff">$file</span><span style="color: #000000">.FullName
            UploadExistingFile </span><span style="color: #0000ff">$file</span><span style="color: #000000"> </span><span style="color: #0000ff">$photoObject</span><span style="color: #000000">.SmugId
            </span><span style="color: #0000ff">$photoObject</span><span style="color: #000000">.LastModifiedTime </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$file</span><span style="color: #000000">.LastWriteTimeUtc.ToString()

            </span><span style="color: #008000">#</span><span style="color: #008000"> mark the dat file as dirty so it will be saved after processing this folder</span><span style="color: #008000">
</span><span style="color: #000000">            </span><span style="color: #0000ff">$script:datFileDirty</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$true</span><span style="color: #000000">
        }
    }
    </span><span style="color: #0000ff">else</span><span style="color: #000000"> {
        </span><span style="color: #008000">#</span><span style="color: #008000">file doesn't exist in local file, upload to SmugMug</span><span style="color: #008000">
</span><span style="color: #000000">        </span><span style="color: #008080">write-Host</span><span style="color: #000000"> </span><span style="color: #000080">"</span><span style="color: #000080">Uploading new file: </span><span style="color: #000080">"</span><span style="color: #000000"> </span><span style="color: #0000ff">$file</span><span style="color: #000000">.FullName
        </span><span style="color: #0000ff">$id</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> UploadFile </span><span style="color: #0000ff">$file</span><span style="color: #000000"> </span><span style="color: #0000ff">$albumName</span><span style="color: #000000">
        AddFile </span><span style="color: #0000ff">$file</span><span style="color: #000000"> </span><span style="color: #0000ff">$id</span><span style="color: #000000">
    }
}

</span><span style="color: #0000ff">#endregion</span><span style="color: #000000">

</span><span style="color: #0000ff">#region</span><span style="color: #000000"> Main Script</span><span style="color: #000000">

</span><span style="color: #008000">#</span><span style="color: #008000"> this section will look through all sub-directories of $PhotoDirectory and upload the images to SmugMug</span><span style="color: #008000">
</span><span style="color: #008080">Get-ChildItem</span><span style="color: #000000"> </span><span style="color: #000000">-</span><span style="color: #008080">recurse</span><span style="color: #000000"> </span><span style="color: #0000ff">$PhotoDirectory</span><span style="color: #000000"> </span><span style="color: #000000">|</span><span style="color: #000000"> </span><span style="color: #008080">Where-Object</span><span style="color: #000000"> { </span><span style="color: #0000ff">$_</span><span style="color: #000000">.Attributes </span><span style="color: #0000ff">-band</span><span style="color: #000000"> [System.IO.FileAttributes]::Directory } </span><span style="color: #000000">|</span><span style="color: #000000"> </span><span style="color: #0000ff">foreach</span><span style="color: #000000"> {
    </span><span style="color: #008000">#</span><span style="color: #008000"> don't process folders that end in _</span><span style="color: #008000">
</span><span style="color: #000000">    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$_</span><span style="color: #000000">.FullName.EndsWith(</span><span style="color: #000080">"</span><span style="color: #000080">_</span><span style="color: #000080">"</span><span style="color: #000000">) </span><span style="color: #0000ff">-eq</span><span style="color: #000000"> </span><span style="color: #0000ff">$false</span><span style="color: #000000">) {
        </span><span style="color: #0000ff">$datFilePath</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$_</span><span style="color: #000000">.FullName </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000080">"</span><span style="color: #000080">\PowerSmug.dat</span><span style="color: #000080">"</span><span style="color: #000000">
        </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #008080">test-Path</span><span style="color: #000000"> </span><span style="color: #0000ff">$datFilePath</span><span style="color: #000000">) {
            </span><span style="color: #008000">#</span><span style="color: #008000"> casting as array to ensure we have an array returned</span><span style="color: #008000">
</span><span style="color: #000000">            [array]</span><span style="color: #0000ff">$script:datFile</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #008080">import-Csv</span><span style="color: #000000"> </span><span style="color: #0000ff">$datFilePath</span><span style="color: #000000">
        }

        </span><span style="color: #0000ff">$albumName</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$_</span><span style="color: #000000">.FullName.Remove(</span><span style="color: #ff0000">0</span><span style="color: #000000">, </span><span style="color: #0000ff">$PhotoDirectory</span><span style="color: #000000">.Length).Trim(</span><span style="color: #000080">'</span><span style="color: #000080">\')</span><span style="color: #000080">
</span><span style="color: #000000">
        </span><span style="color: #0000ff">$path</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$_</span><span style="color: #000000">.FullName </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000080">"</span><span style="color: #000080">\*</span><span style="color: #000080">"</span><span style="color: #000000">
        </span><span style="color: #0000ff">foreach</span><span style="color: #000000"> (</span><span style="color: #0000ff">$file</span><span style="color: #000000"> </span><span style="color: #0000ff">in</span><span style="color: #000000"> </span><span style="color: #008080">get-ChildItem</span><span style="color: #000000"> </span><span style="color: #0000ff">$path</span><span style="color: #000000"> </span><span style="color: #000000">-</span><span style="color: #008080">include</span><span style="color: #000000"> </span><span style="color: #0000ff">$filesToInclude</span><span style="color: #000000">) {
            ProcessFile </span><span style="color: #0000ff">$file</span><span style="color: #000000"> </span><span style="color: #0000ff">$albumName</span><span style="color: #000000">
        }
        SaveDataFile </span><span style="color: #0000ff">$datFilePath</span><span style="color: #000000">
        </span><span style="color: #0000ff">$script:imageList</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$null</span><span style="color: #000000">
    }
}

Logout

</span><span style="color: #0000ff">$date</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #008080">Get-Date</span><span style="color: #000000">
</span><span style="color: #008080">Write-Host</span><span style="color: #000000"> </span><span style="color: #000080">"</span><span style="color: #000080">Script Completed: $date</span><span style="color: #000080">"</span><span style="color: #000000">

trap [Exception] {
        </span><span style="color: #0000ff">$date</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #008080">Get-Date</span><span style="color: #000000">
        </span><span style="color: #0000ff">$Msg</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$date</span><span style="color: #000000">.ToString() </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000080">"</span><span style="color: #000080"> ; </span><span style="color: #000080">"</span><span style="color: #000000"> </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #0000ff">$_</span><span style="color: #000000">.Exception.GetType().FullName </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000080">"</span><span style="color: #000080"> ; </span><span style="color: #000080">"</span><span style="color: #000000"> </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #0000ff">$_</span><span style="color: #000000">.Exception.Message
        </span><span style="color: #008080">Add-Content</span><span style="color: #000000"> </span><span style="color: #0000ff">$logFile</span><span style="color: #000000"> </span><span style="color: #0000ff">$Msg</span><span style="color: #000000">
        SendEmail </span><span style="color: #0000ff">$EmailAddress</span><span style="color: #000000"> </span><span style="color: #000080">"</span><span style="color: #000080">PowerSmug Error</span><span style="color: #000080">"</span><span style="color: #000000"> </span><span style="color: #0000ff">$Msg</span><span style="color: #000000">
        </span><span style="color: #0000ff">break</span><span style="color: #000000">
    }

</span><span style="color: #0000ff">#endregion</span></pre>
<p>&#8212;&#8211;</p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2009/01/12/powersmug-syncronize-folders-on-your-machine-with-smugmug/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PowerShell Analyzer Refresh for PSV2 + CTP3 advanced function features.</title>
		<link>http://karlprosser.com/coder/2009/01/08/powershell-analyzer-refresh-for-psv2-ctp3-advanced-function-features/</link>
		<comments>http://karlprosser.com/coder/2009/01/08/powershell-analyzer-refresh-for-psv2-ctp3-advanced-function-features/#comments</comments>
		<pubDate>Thu, 08 Jan 2009 08:44:19 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Powershell Analyzer]]></category>
		<category><![CDATA[pscom]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2009/01/08/powershell-analyzer-refresh-for-psv2-ctp3-advanced-function-features/</guid>
		<description><![CDATA[Though we don’t have intentions to carry developing PowerShell Analyzer much in the future, there are a number of improvements in my personal fork, and we want to make sure that it keeps its shelf life by updating it for PowerShell V2. Surprisingly we are still getting hundreds of downloads a day so we want [...]]]></description>
			<content:encoded><![CDATA[<p>Though we don’t have intentions to carry developing PowerShell Analyzer much in the future, there are a number of improvements in my personal fork, and we want to make sure that it keeps its shelf life by updating it for PowerShell V2. Surprisingly we are still getting hundreds of downloads a day so we want to make sure that those who prefer PSA can still keep using it and also take advantage of the features I use day in and day out. We’ll probably release some new builds within the next couple of weeks, but will post some screenshots and maybe videos until then. We hope that will minimal effort keep PSA the best free PowerShell tool. However if want a tool that is definitely worth paying for check out PowerShell Plus at its new home at Idera &#8211; <a href="http://www.idera.com/Products/PowerShell/" title="http://www.idera.com/Products/PowerShell/">http://www.idera.com/Products/PowerShell/</a></p>
<p>So here is a screenshot of PowerShell Analyzer running with PowerShell V2 CTP3. The new features are all related to the help features of advanced Functions.</p>
<ul>
<li>Region support for multiline comments &lt;# #&gt;</li>
<li>Syntax Coloring for help documenting keywords (i.e.  .DESCRIPTION )</li>
<li>Code Completion for help documenting keywords.</li>
<li>Rich Rendering of advanced function help from get-help in HTML (any advanced function that is in the RunSpace)</li>
</ul>
<p><a href="http://karlprosser.com/coder/wp-content/uploads/2009/01/1712842.png"><img border="0" width="673" src="http://karlprosser.com/coder/wp-content/uploads/2009/01/1712842-thumb.png" alt="1712842" height="784" style="display: inline; border: 0px" title="1712842" /></a></p>
<p>So there. you go. However the help rendering is only in our really old 3 year old Help rendering engine. If you like it wait for our HelpFusion app which will be separate and be able to be used independently or from any PowerShell host. Some of you have seen it, but the rest of you will have to wait until we finish rewriting it for WPF.</p>
<p>Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2009/01/08/powershell-analyzer-refresh-for-psv2-ctp3-advanced-function-features/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>This is your Admin life. You HAVE to script PowerShell</title>
		<link>http://karlprosser.com/coder/2009/01/06/this-is-your-admin-life-you-have-to-script-powershell/</link>
		<comments>http://karlprosser.com/coder/2009/01/06/this-is-your-admin-life-you-have-to-script-powershell/#comments</comments>
		<pubDate>Tue, 06 Jan 2009 08:20:11 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2009/01/06/this-is-your-admin-life-you-have-to-script-powershell/</guid>
		<description><![CDATA[So i was listening to that Dust Brother’s Tyler Durden song from fight club, and PowerShell lyrics started jumping into my head. We’ll most were fleeting before i could capture them, but i did come up with something at least tacky, and fun to some. No offense to anybody. Anyway here is the original song. [...]]]></description>
			<content:encoded><![CDATA[<p>So i was listening to that Dust Brother’s Tyler Durden song from fight club, and PowerShell lyrics started jumping into my head. We’ll most were fleeting before i could capture them, but i did come up with something at least tacky, and fun to some. No offense to anybody. Anyway here is the original song. Listen to it once to get the picture, then a second time while reading my lyrics. Here is a link to the original <a href="http://www.songmeanings.net/songs/view/65307/">lyrics</a>.</p>
<p style="visibility: visible; margin-left: auto; width: 450px; margin-right: auto; text-align: center"><embed border="0" wmode="transparent" quality="high" menu="false" allowScriptAccess="never" height="270" width="435" src="http://www.musicplaylist.us/mc/mp3player-othersite.swf?config=http://www.musicplaylist.us/mc/config/config_blue_noautostart.xml&amp;mywidth=435&amp;myheight=270&amp;playlist_url=http://www.musicplaylist.us/loadplaylist.php?playlist=56640282" pluginspage="http://www.macromedia.com/go/getflashplayer" name="mp3player" style="visibility: visible; width: 435px; height: 270px"></embed><br />
<a href="http://www.musicplaylist.us"><img border="0" src="http://www.musicplaylist.us/mc/images/create_blue.jpg" /></a><a target="_blank" href="http://www.musicplaylist.us/standalone/56640282"><img border="0" src="http://www.musicplaylist.us/mc/images/launch_blue.jpg" /></a><a href="http://www.musicplaylist.us/download/56640282"><img border="0" src="http://www.musicplaylist.us/mc/images/get_blue.jpg" /></a></p>
<h2>This is your Admin Life</h2>
<p>And you open the door and you step inside<br />
We&#8217;re inside our servers</p>
<p>Now imagine that that Blue Screen is a white ball of healing light<br />
That&#8217;s right, that exception itself is a white ball of healing light</p>
<p>I don&#8217;t think so</p>
<p>This is your job , Good to the last cpu cycle.<br />
It doesn&#8217;t get any better than this.<br />
This is your job and its ending one click at a time.</p>
<p>This isn&#8217;t your favourite tech conference. This isn&#8217;t no geek class.<br />
Where you are now, you can&#8217;t even imagine what the bottom will be like<br />
Only after disaster, will your server need resurrected.<br />
Its only after you&#8217;ve lost everything that you&#8217;ll learn to script anything.<br />
Nothing is static, everything is Dynamic<br />
Without no agile script, it&#8217;s all falling apart.</p>
<p>This is your job.<br />
<em>(Without PowerShell)</em><br />
It doesn&#8217;t get any better than this.<br />
This is your job<br />
And its ending one click at a time.</p>
<p>You are not a beautiful and unique engineer.<br />
You are the same decaying GUI based admin  as everybody else.<br />
We are all part of the same time consuming life draining Slavehood<br />
We are the all cringing,ever working info-saviours of the world</p>
<p>You are not your dollarstore tech certification.<br />
You are not your Antivirus failure.<br />
You are not your dumbed down GUI management tools.</p>
<p>You are not your HR employee primary key<br />
You are not your Active Directory login.<br />
You are not your CIO&#8217;s latest tech fad.<br />
You are not your hungover 70&#8242;s unix shell script.</p>
<p>You have to Code PowerShell.<br />
You have to Code PowerShell.</p>
<p>You have to realize that someday GUI admins will be unemployed<br />
Until you know that, you are useless.</p>
<p>I say never let me be GUI dependant<br />
I say may I never be content.<br />
I say deliver me from MMC console ripoffs.<br />
I say deliver me from VBscript.<br />
I say deliver me from misunderestimating linux zealots.<br />
I say you have to PowerShell<br />
I saw grow, and let the scripts run where they may</p>
<p>This is your job.<br />
<em>(Without PowerShell)</em><br />
It doesn&#8217;t get any better than this.<br />
This is your job<br />
And its ending one click at a time.</p>
<p>You have to Code PowerShell<br />
You have to Code PowerShell</p>
<p>I want you to script me as hard as you can.<br />
I want you to script me as hard as you can.</p>
<p>Welcome to #powershell Club. If this is your first night, you have to code.</p>
<p>Enjoy &#8211; Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2009/01/06/this-is-your-admin-life-you-have-to-script-powershell/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>PowerShell Analyzer like execution hotkeys for PS CTP3 ISE.</title>
		<link>http://karlprosser.com/coder/2009/01/03/powershell-analayzer-like-execution-hotkeys-for-ps-ctp3-ise/</link>
		<comments>http://karlprosser.com/coder/2009/01/03/powershell-analayzer-like-execution-hotkeys-for-ps-ctp3-ise/#comments</comments>
		<pubDate>Sat, 03 Jan 2009 23:14:00 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>
		<category><![CDATA[PSV2]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2009/01/03/powershell-analayzer-like-execution-hotkeys-for-ps-ctp3-ise/</guid>
		<description><![CDATA[PowerShell CTP3 ISE &#8211; Integrated Scripting environment has inherited many ideas and features from PowerShell analyzer including multiple runspaces,editors, a smaller immediate input area and output pane, however it doesn’t have the output visualizers of PSA nor the super fast RTS like execution control of PSA. However Microsoft in their wisdom has made ISE rather [...]]]></description>
			<content:encoded><![CDATA[<p>PowerShell CTP3 ISE &#8211; Integrated Scripting environment has inherited many ideas and features from PowerShell analyzer including multiple runspaces,editors, a smaller immediate input area and output pane, however it doesn’t have the output visualizers of PSA nor the super fast RTS like execution control of PSA.</p>
<p>However Microsoft in their wisdom has made ISE rather extensible through the $PSISE variable, and many people already have added some very cool functionality to ISE through these.</p>
<p>When I first demo’d what was then MSH analyzer to Microsoft back in the first few months of 2006, the feature that seemed to stand out the most to the team was the ability to select an area of code and just run that. Thankfully that level of execution control is now in ISE as F6, but I wanted more, so i’m going to share with you a script that build a few months ago to add a couple of features.</p>
<p><strong><u>F7 run the current physical line.</u></strong></p>
<p>this basically will run the line where the caret current is at.</p>
<p><strong><u>Real Time Strategy like control.. CTRL 1 , CTRL 2 etc</u></strong></p>
<p>This here allows you to use comments to create regions, then EXECUTE those regions with a simple hotkey. I use this extensively. Often i am working on building a function, so I edit the function, press Ctrl 1 to apply the function, then if that was successful, press Ctrl 2 , then maybe Ctrl 3 to run some tests to make sure my changes to the function are what i am expecting.</p>
<p>This gives me a great AGILITY , putting what Jeffery Snover calls <a href="http://www.microsoft.com/technet/scriptcenter/resources/interviews/snover.mspx">the Admin Development Model</a> , but which is really <a href="http://en.wikipedia.org/wiki/REPL">REPL(Repeat Evaluate, Print , Loop )</a> rediscovered, on agile steroids.</p>
<pre><span style="color: #0000ff">function</span><span style="color: #000000"> </span><span style="color: #008080">invoke-caretline</span><span style="color: #000000">
{
</span><span style="color: #008080">invoke-expression</span><span style="color: #000000"> </span><span style="color: #0000ff">$</span><span style="color: #000000">([Regex]::Split(</span><span style="color: #0000ff">$psISE</span><span style="color: #000000">.CurrentOpenedFile.Editor.text,</span><span style="color: #000080">"</span><span style="color: #000080">`r`n</span><span style="color: #000080">"</span><span style="color: #000000"> )[</span><span style="color: #0000ff">$psISE</span><span style="color: #000000">.CurrentOpenedFile.Editor.caretline</span><span style="color: #000000">-</span><span style="color: #ff0000">1</span><span style="color: #000000">])
}
</span><span style="color: #0000ff">$psISE</span><span style="color: #000000">.CustomMenu.Submenus.Add(</span><span style="color: #000080">"</span><span style="color: #000080">Run single line</span><span style="color: #000080">"</span><span style="color: #000000">, {</span><span style="color: #008080">invoke-caretline</span><span style="color: #000000">} ,  </span><span style="color: #000080">'</span><span style="color: #000080">f7</span><span style="color: #000080">'</span><span style="color: #000000">)
</span><span style="color: #0000ff">function</span><span style="color: #000000"> </span><span style="color: #008080">invoke-region</span><span style="color: #000000">([</span><span style="color: #0000ff">int</span><span style="color: #000000">] </span><span style="color: #0000ff">$num</span><span style="color: #000000">)
{
</span><span style="color: #0000ff">$ed</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$psISE</span><span style="color: #000000">.CurrentOpenedFile.Editor
</span><span style="color: #0000ff">$lines</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> [Regex]::Split(</span><span style="color: #0000ff">$ed</span><span style="color: #000000">.text,</span><span style="color: #000080">"</span><span style="color: #000080">`r`n</span><span style="color: #000080">"</span><span style="color: #000000"> )
</span><span style="color: #0000ff">$foundfirst</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">-</span><span style="color: #ff0000">1</span><span style="color: #000000">
</span><span style="color: #0000ff">$foundlast</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000000">-</span><span style="color: #ff0000">1</span><span style="color: #000000">
</span><span style="color: #0000ff">for</span><span style="color: #000000">(</span><span style="color: #0000ff">$count</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #ff0000">0</span><span style="color: #000000">;</span><span style="color: #0000ff">$count</span><span style="color: #000000"> </span><span style="color: #0000ff">-le</span><span style="color: #000000"> </span><span style="color: #0000ff">$lines</span><span style="color: #000000">.length</span><span style="color: #000000">-</span><span style="color: #ff0000">1</span><span style="color: #000000">;</span><span style="color: #0000ff">$count</span><span style="color: #000000">++</span><span style="color: #000000">)
 {
   </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$lines</span><span style="color: #000000">[</span><span style="color: #0000ff">$count</span><span style="color: #000000">].startswith(</span><span style="color: #000080">"</span><span style="color: #000080">#region</span><span style="color: #000080">"</span><span style="color: #000000">) </span><span style="color: #000000">-</span><span style="color: #008080">and</span><span style="color: #000000"> </span><span style="color: #0000ff">$lines</span><span style="color: #000000">[</span><span style="color: #0000ff">$count</span><span style="color: #000000">].contains(</span><span style="color: #000080">"</span><span style="color: #000080">@$num</span><span style="color: #000080">"</span><span style="color: #000000">))
   { </span><span style="color: #0000ff">$foundfirst</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$count</span><span style="color: #000000">;</span><span style="color: #0000ff">break</span><span style="color: #000000">}
 }
 </span><span style="color: #0000ff">if</span><span style="color: #000000">(</span><span style="color: #0000ff">$foundfirst</span><span style="color: #000000"> </span><span style="color: #0000ff">-gt</span><span style="color: #000000"> </span><span style="color: #000000">-</span><span style="color: #ff0000">1</span><span style="color: #000000">)
 {
 </span><span style="color: #0000ff">for</span><span style="color: #000000"> (</span><span style="color: #0000ff">$count</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$foundfirst</span><span style="color: #000000">; </span><span style="color: #0000ff">$count</span><span style="color: #000000"> </span><span style="color: #0000ff">-le</span><span style="color: #000000"> </span><span style="color: #0000ff">$lines</span><span style="color: #000000">.length</span><span style="color: #000000">-</span><span style="color: #ff0000">1</span><span style="color: #000000">;</span><span style="color: #0000ff">$count</span><span style="color: #000000">++</span><span style="color: #000000">)
    {
    </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$lines</span><span style="color: #000000">[</span><span style="color: #0000ff">$count</span><span style="color: #000000">].startswith(</span><span style="color: #000080">"</span><span style="color: #000080">#endregion</span><span style="color: #000080">"</span><span style="color: #000000">) )
   { </span><span style="color: #0000ff">$foundlast</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">$count</span><span style="color: #000000">;</span><span style="color: #0000ff">break</span><span style="color: #000000">}
    } 

 </span><span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #0000ff">$foundlast</span><span style="color: #000000"> </span><span style="color: #0000ff">-gt</span><span style="color: #000000"> </span><span style="color: #000000">-</span><span style="color: #ff0000">1</span><span style="color: #000000">)
   {
     </span><span style="color: #0000ff">$torun</span><span style="color: #000000"> </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #000080">""</span><span style="color: #000000">
     </span><span style="color: #0000ff">$lines</span><span style="color: #000000">[</span><span style="color: #0000ff">$foundfirst</span><span style="color: #000000">..</span><span style="color: #0000ff">$foundlast</span><span style="color: #000000">] </span><span style="color: #000000">|</span><span style="color: #000000"> </span><span style="color: #000000">%</span><span style="color: #000000"> { </span><span style="color: #0000ff">$torun</span><span style="color: #000000">+=</span><span style="color: #0000ff">$_</span><span style="color: #000000"> </span><span style="color: #000000">+</span><span style="color: #000000"> </span><span style="color: #000080">"</span><span style="color: #000080">`r`n</span><span style="color: #000080">"</span><span style="color: #000000">}
     </span><span style="color: #008080">invoke-expression</span><span style="color: #000000"> </span><span style="color: #0000ff">$torun</span><span style="color: #000000">
   }
 } 

}
 </span><span style="color: #0000ff">$psISE</span><span style="color: #000000">.CustomMenu.Submenus.Add(</span><span style="color: #000080">"</span><span style="color: #000080">run region 1</span><span style="color: #000080">"</span><span style="color: #000000">, {</span><span style="color: #008080">invoke-region</span><span style="color: #000000"> </span><span style="color: #ff0000">1</span><span style="color: #000000"> },  </span><span style="color: #000080">'</span><span style="color: #000080">ctrl+1</span><span style="color: #000080">'</span><span style="color: #000000">)
 </span><span style="color: #0000ff">$psISE</span><span style="color: #000000">.CustomMenu.Submenus.Add(</span><span style="color: #000080">"</span><span style="color: #000080">run region 2</span><span style="color: #000080">"</span><span style="color: #000000">, {</span><span style="color: #008080">invoke-region</span><span style="color: #000000"> </span><span style="color: #ff0000">2</span><span style="color: #000000"> },  </span><span style="color: #000080">'</span><span style="color: #000080">ctrl+2</span><span style="color: #000080">'</span><span style="color: #000000">)
 </span><span style="color: #0000ff">$psISE</span><span style="color: #000000">.CustomMenu.Submenus.Add(</span><span style="color: #000080">"</span><span style="color: #000080">run region 3</span><span style="color: #000080">"</span><span style="color: #000000">, {</span><span style="color: #008080">invoke-region</span><span style="color: #000000"> </span><span style="color: #ff0000">3</span><span style="color: #000000"> },  </span><span style="color: #000080">'</span><span style="color: #000080">ctrl+3</span><span style="color: #000080">'</span><span style="color: #000000">)
 </span><span style="color: #0000ff">$psISE</span><span style="color: #000000">.CustomMenu.Submenus.Add(</span><span style="color: #000080">"</span><span style="color: #000080">run region 4</span><span style="color: #000080">"</span><span style="color: #000000">, {</span><span style="color: #008080">invoke-region</span><span style="color: #000000"> </span><span style="color: #ff0000">4</span><span style="color: #000000"> },  </span><span style="color: #000080">'</span><span style="color: #000080">ctrl+4</span><span style="color: #000080">'</span><span style="color: #000000">)
 </span><span style="color: #0000ff">$psISE</span><span style="color: #000000">.CustomMenu.Submenus.Add(</span><span style="color: #000080">"</span><span style="color: #000080">run region 5</span><span style="color: #000080">"</span><span style="color: #000000">, {</span><span style="color: #008080">invoke-region</span><span style="color: #000000"> </span><span style="color: #ff0000">5</span><span style="color: #000000"> },  </span><span style="color: #000080">'</span><span style="color: #000080">ctrl+5</span><span style="color: #000080">'</span><span style="color: #000000">) </span></pre>
<p>Script @ PoshCode: <a href="http://poshcode.org/776">View Script</a> | <a href="http://poshcode.org/get/776">Download</a></p>
<p>Sometime I&#8217;ll wrap all this up into a module, and add other PowerShell Analyzer-like functionality such as running the current PARAGRAPH. So often in an earlier PSA, and in SQL Query Analyzer, i’m highlighting again and again the SAME paragraph query and running it over and over again. Being able to just run the current paragraph saves that time.</p>
<p style="display: inline; float: none; margin: 0px; padding: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:51f724f8-080f-494c-9d52-aa7695a1af0f" class="wlWriterEditableSmartContent">Technorati Tags: <a rel="tag" href="http://technorati.com/tags/powershell">powershell</a>,<a rel="tag" href="http://technorati.com/tags/shelltools">shelltools</a>,<a rel="tag" href="http://technorati.com/tags/ISE">ISE</a>,<a rel="tag" href="http://technorati.com/tags/powershell+analyzer">powershell analyzer</a></p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2009/01/03/powershell-analayzer-like-execution-hotkeys-for-ps-ctp3-ise/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Help us decide which PowerShell tool to release next.</title>
		<link>http://karlprosser.com/coder/2008/12/19/help-us-decide-which-powershell-tool-to-release-next/</link>
		<comments>http://karlprosser.com/coder/2008/12/19/help-us-decide-which-powershell-tool-to-release-next/#comments</comments>
		<pubDate>Sat, 20 Dec 2008 01:06:03 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Powershell Analyzer]]></category>
		<category><![CDATA[Powershell Plus]]></category>
		<category><![CDATA[pscom]]></category>
		<category><![CDATA[Shell Tools]]></category>
		<category><![CDATA[powershell analyzer]]></category>
		<category><![CDATA[powershell plus]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2008/12/19/help-us-decide-which-powershell-tool-to-release-next/</guid>
		<description><![CDATA[Help us decide which PowerShell tool to release next. SURVEY: http://spreadsheets.google.com/viewform?key=pgTpVBomNgDwUA9uQNRKAbw&#38;hl=en Taking an app from an internal application to a shrink-wrap ready for the masses state is a lot of work, and updating/supporting/marketting a product even more so. So after the huge sucess of PowerShell Plus which is now safe in Idera&#8217;s hands we need [...]]]></description>
			<content:encoded><![CDATA[<p>Help us decide which PowerShell tool to release next.</p>
<p>SURVEY: <a href="http://spreadsheets.google.com/viewform?key=pgTpVBomNgDwUA9uQNRKAbw&amp;hl=en">http://spreadsheets.google.com/viewform?key=pgTpVBomNgDwUA9uQNRKAbw&amp;hl=en</a></p>
<p>Taking an app from an internal application to a shrink-wrap ready for<br />
the masses state is a lot of work, and updating/supporting/marketting<br />
a product even more so. So after the huge sucess of PowerShell Plus<br />
which is now safe in Idera&#8217;s hands we need your help to decide what we<br />
are going to release next. We plan to release some free projects, even<br />
some opensource apps, but will likely look at productizing a project<br />
so we can continue to feed our families. Please take the time to take<br />
our survey</p>
<p>&#8212;&#8211;<br />
As many of you know, PowerShell Plus has been a great success and is<br />
now developed and sold by Idera, and we’ve made PowerShell Analyzer<br />
100% free!. Despite PowerShell Analyzer not having much active<br />
development done for almost 2 years, surprisingly it is still very<br />
popular with a large user base. Based on your feedback and the<br />
following thoughts we need to decide where to invest our development<br />
time, and which internal prototypes to bring to the community.<br />
•       We have invested a lot into PowerShell Plus, from vision and<br />
incubation to a mature product and we don’t want to compete in the<br />
marketplace directly with PowerShell Plus.<br />
•       PowerShell editors are now a generic commodity. In addition to<br />
the awesome PowerShell plus. There are many free “good enough”<br />
solutions, including some open source ones, Microsoft’s upcoming<br />
Graphical PowerShell Integrated Scripting Environment and some other<br />
“lower common denominator” solutions that are still free.<br />
•       We have created and continue to innovate PowerShell technology<br />
that can live just as well outside an editor product as in one.</p>
<p>There are many questions on here. Feel free to not answer them all,<br />
it’s the top questions that are most important to us, but the more you<br />
fill in, the happier you’ll make us.</p>
<p>SURVEY: <a href="http://spreadsheets.google.com/viewform?key=pgTpVBomNgDwUA9uQNRKAbw&amp;hl=en">http://spreadsheets.google.com/viewform?key=pgTpVBomNgDwUA9uQNRKAbw&amp;hl=en</a></p>
<p>-Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2008/12/19/help-us-decide-which-powershell-tool-to-release-next/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerShell Analyzer now 100% free.</title>
		<link>http://karlprosser.com/coder/2008/10/02/powershell-analyzer-now-100-free/</link>
		<comments>http://karlprosser.com/coder/2008/10/02/powershell-analyzer-now-100-free/#comments</comments>
		<pubDate>Thu, 02 Oct 2008 05:23:12 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Powershell Analyzer]]></category>
		<category><![CDATA[pscom]]></category>
		<category><![CDATA[Shell Tools]]></category>
		<category><![CDATA[editor]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[powershell analyzer]]></category>
		<category><![CDATA[powershell plus]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2008/10/02/powershell-analyzer-now-100-free/</guid>
		<description><![CDATA[With the phenomenal success of PowerShell Plus and subsequent transfer to Idera, PowerShell Analyzer is now 100% free. You can read more and get it from our recently updated website &#8211; http://www.shelltools.net . In coming weeks we are going to do some surveys to help decide where we want to go as a company with [...]]]></description>
			<content:encoded><![CDATA[<p><meta name="ProgId" content="Word.Document" /><meta name="Generator" content="Microsoft Word 12" /><meta name="Originator" content="Microsoft Word 12" /></p>
<link rel="File-List" href="file:///C:%5CUsers%5Ckprosser%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml" />
<link rel="themeData" href="file:///C:%5CUsers%5Ckprosser%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx" />
<link rel="colorSchemeMapping" href="file:///C:%5CUsers%5Ckprosser%5CAppData%5CLocal%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml" />
<style>   <!--  /* Font Definitions */  @font-face 	{font-family:"MS Mincho"; 	panose-1:2 2 6 9 4 2 5 8 3 4; 	mso-font-alt:"ＭＳ 明朝"; 	mso-font-charset:128; 	mso-generic-font-family:modern; 	mso-font-pitch:fixed; 	mso-font-signature:-536870145 1791491579 18 0 131231 0;} @font-face 	{font-family:"Cambria Math"; 	panose-1:2 4 5 3 5 4 6 3 2 4; 	mso-font-charset:1; 	mso-generic-font-family:roman; 	mso-font-format:other; 	mso-font-pitch:variable; 	mso-font-signature:0 0 0 0 0 0;} @font-face 	{font-family:Calibri; 	panose-1:2 15 5 2 2 2 4 3 2 4; 	mso-font-charset:0; 	mso-generic-font-family:swiss; 	mso-font-pitch:variable; 	mso-font-signature:-1610611985 1073750139 0 0 159 0;} @font-face 	{font-family:"\@MS Mincho"; 	panose-1:2 2 6 9 4 2 5 8 3 4; 	mso-font-charset:128; 	mso-generic-font-family:modern; 	mso-font-pitch:fixed; 	mso-font-signature:-536870145 1791491579 18 0 131231 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-unhide:no; 	mso-style-qformat:yes; 	mso-style-parent:""; 	margin-top:0in; 	margin-right:0in; 	margin-bottom:10.0pt; 	margin-left:0in; 	line-height:115%; 	mso-pagination:widow-orphan; 	font-size:11.0pt; 	font-family:"Calibri","sans-serif"; 	mso-ascii-font-family:Calibri; 	mso-ascii-theme-font:minor-latin; 	mso-fareast-font-family:"MS Mincho"; 	mso-fareast-theme-font:minor-fareast; 	mso-hansi-font-family:Calibri; 	mso-hansi-theme-font:minor-latin; 	mso-bidi-font-family:"Times New Roman"; 	mso-bidi-theme-font:minor-bidi;} .MsoChpDefault 	{mso-style-type:export-only; 	mso-default-props:yes; 	mso-ascii-font-family:Calibri; 	mso-ascii-theme-font:minor-latin; 	mso-fareast-font-family:"MS Mincho"; 	mso-fareast-theme-font:minor-fareast; 	mso-hansi-font-family:Calibri; 	mso-hansi-theme-font:minor-latin; 	mso-bidi-font-family:"Times New Roman"; 	mso-bidi-theme-font:minor-bidi;} .MsoPapDefault 	{mso-style-type:export-only; 	margin-bottom:10.0pt; 	line-height:115%;} @page Section1 	{size:8.5in 11.0in; 	margin:1.0in 1.0in 1.0in 1.0in; 	mso-header-margin:.5in; 	mso-footer-margin:.5in; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --> </style>
<p class="MsoNormal">With the phenomenal success of PowerShell Plus and subsequent transfer to Idera, PowerShell Analyzer is now 100% free. You can read more and get it from our recently updated website &#8211; <a href="http://www.shelltools.net">http://www.shelltools.net </a>. In coming weeks we are going to do some surveys to help decide where we want to go as a company with PowerShell IDEs.</p>
<p class="MsoNormal">Sincerely,</p>
<p class="MsoNormal">Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2008/10/02/powershell-analyzer-now-100-free/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Portable Powershell &#8211; Part 2: Roll your own, plus a challenge</title>
		<link>http://karlprosser.com/coder/2008/06/19/portable-powershell-part-2-roll-your-own-plus-a-challenge/</link>
		<comments>http://karlprosser.com/coder/2008/06/19/portable-powershell-part-2-roll-your-own-plus-a-challenge/#comments</comments>
		<pubDate>Thu, 19 Jun 2008 06:34:00 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Bare Metal]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2008/06/19/portable-powershell-part-2-roll-your-own-plus-a-challenge/</guid>
		<description><![CDATA[UPDATE FEB 2010 We don&#8217;t need to rely on things like thinapp or app-v anymore. At ShellTools we have build our own Portable PowerShell framework. Its currently in Beta &#8211; see http://www.portablepowershell.com for more details. Todays Blog entry is going to cover the HOW of how I put together my demos of Portable PowerShell. Tomorrow [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE FEB 2010</strong> We don&#8217;t need to rely on things like thinapp or app-v anymore. At ShellTools we have build our own Portable PowerShell framework. Its currently in Beta &#8211; see <a href="http://www.portablepowershell.com">http://www.portablepowershell.com</a> for more details.</p>
<hr/>
Todays Blog entry is going to cover the <strong>HOW </strong>of how I put together my demos of Portable PowerShell. Tomorrow I&#8217;ll move back to clearly defining what I&#8217;d like to see from Microsoft. But before I get to the full details a little background:</p>
<p><u>Background</u></p>
<p>So what&#8217;s stopping PowerShell or practically anything from being portable? dependence on a particular file structure and the registry. Basically the technique I  &#8220;HOOK&#8221; apis so that whenever the process tries to call certain APIs (the filesystem and registry ones) the code in memory is changed to jump to custom code instead of the address of the DLL function export where DLL has been loaded. From there custom checks are done to see if its a file or registry setting to do with PowerShell, and if so the code delivers it up, as if it were there, even though its not.</p>
<p>This is a technique that as a programmer I have been doing for a long time. It involves a lot of assembler, historically being able to inject a DLL into a process and in memory rewrite the code, but it works great. The first time I worked out this technique as a programmer was back in the days of windows 95 which wasn&#8217;t unicode. I made an application that could enable Chinese and Japanese characters on english windows. Effectively I hooked the <a href="http://msdn.microsoft.com/en-us/library/ms534019.aspx">TextOut</a> API, and if it was a process that had been chosen to say display in Japanese, and the font chosen was one that was chosen for this purpose then I custom drew the Japanese or Chinese Glyph otherwise I just called the real <a href="http://msdn.microsoft.com/en-us/library/ms534019.aspx">TextOut</a> API call. Another technique when working on <a href="http://www.visualjockey.com/">VisualJockey</a> many years ago, I wanted to be able to pipe the output on a standalone graphics program into <a href="http://www.visualjockey.com">VisualJockey</a> so we could do some video processing on it. The problem is that app drew to fullscreen directX itself, so I had to &#8220;hook&#8221; the directX apis, so that when it created the surface it didn&#8217;t make it fullscreen, and when it rendered it rendered to Texture instead of screen, and then some extra code to retrieve what it had rendered. Another Situation was changing a DB backend of an application without the Applications source, *simply* by hooking the ODBC apis (where we also could discover the password used). Another thing I used this technique for was to add some functionality to abandoned freeware that had no source code.</p>
<p>Fast forward to about 2002, <a href="http://josua.hoengermedia.ch/index.htm">Josua Honger</a> , the main architect of <a href="http://www.visualjockey.com/">VisualJockey</a>, and also the <a href="http://www.green-hippo.com/">Hippotiser</a> (I could talk a week just about these amazing programs, the Hippotiser has gone on to become a huge sensation powering realtime effects for live T.V, large concerts, events like the nobel peace prize, broadway shows, and the worlds largest audiovisual setup- Love by Cirque de Soliel in Las Vegas)  were wanting to use the engine of <a href="http://www.visualjockey.com">VisualJockey</a> to make a <a href="http://en.wikipedia.org/wiki/Demoscene">demoscene demo</a> , without the copy protection , and in a portable manner (Demoscene demos aren&#8217;t allowed to install anything), and on top of that not scare the Green Hippo (who recently purchased the VisualJockey engine and didn&#8217;t want to risk it getting out and reused). We didn&#8217;t have time to roll our own solution so we found a rather recent product called <a href="http://www.thinstall.com">Thinstal</a>l. <a href="http://www.thinstall.com">Thinstall</a> used the techniques mentioned about, but it stored all the files you choose in its own encrypted virtual file system inside one file &#8211; Just what we were needing. <a href="http://www.thinstall.com">Thinstall</a> in those days also was cheap enough for us, even though it was a hobby project, but as a young product it didn&#8217;t quite work fully with our VisualJockey because we used some interesting techniques anyhow, but I did gain a lot of respect for it, and for its author Jonathan Clark. Over the years I&#8217;ve played with it a few times for some hobby projects , but the cost went up and up and I couldn&#8217;t justify using it.</p>
<p>Fast forward to 2008, the complexities and risks of deploying and configuring applications have become a real pain point for many corporations and an abundance of solutions have tried solving this. <a href="http://www.thinstall.com">Thinstall</a> evolved its PR to target this market &#8211; and named it Application Virtualization, and most recently got acquired by VMWARE. (and renamed ThinApp) So now that there was a great beta to try. the scary thing is HOW EASY THIS WAS. I expected that I would have to spend many hours manually tweaking what to include/exclude &#8211; setting up the behaviour of the registry virtualization, but I had something done in 20 minutes, pretty much just following a few instructions. and Click next / next /next</p>
<p><strong>HOW HOW HOW HOW HOW HOW HOW HOW</strong></p>
<p>So I wanted to make 4 different versions of Portable Powershell</p>
<ul>
<li>Powershell V1 (just powershell, don&#8217;t include dotnet 2.0 &#8211; thus dotnet 2.0 is needed to be installed on a machine for it to work)</li>
<li>Powershell V2 CTP2 (just powershell, don&#8217;t include dotnet 2.0 &#8211; thus dotnet 2.0 is needed to be installed on a machine for it to work)</li>
<li>PowerShell V1 (include the who dotnet 2.0 so it can run even where dotnet isn&#8217;t)</li>
<li>PowerShell V1 (include the who dotnet 2.0 so it can run even where dotnet isn&#8217;t)</li>
</ul>
<p>The Key this is to have a Fresh OS to start from, so that you don&#8217;t miss any important files , and don&#8217;t get rubbish either, so the place to build this is most definately in a VM.</p>
<p>So what did i do?</p>
<ol>
<li>Predownloaded what was needed
<ol>
<li>XP SP2 install CD</li>
<li>VMWARE THINAPP BETA (plus free beta key)</li>
<li>DOTNET 2.0 redistributable</li>
<li>Powershell V1 for XP installer</li>
<li>Powershell V2 CTP2 installer</li>
</ol>
</li>
<li>Setup the OS in a VM.</li>
<li>Installed ThinAPP</li>
<li>Made a snapshot of the VM</li>
<li>started the thinapp process</li>
<li>Installed dotnet 2.0</li>
<li>Installed PowerShell V2CTP2</li>
<li>Copied over PowerShell Analyzer</li>
<li>Completed the thinapp process , and build the Portable EXE for my V2 with dotnet Portable Powershell</li>
<li>Copied my portable powerShell off the VM</li>
<li>Reverted the snapshot</li>
<li>Repeated the process but for PowerShell V1</li>
<li>Reverted the snapshot</li>
<li>Installed dotnet 2.0</li>
<li>Made a new snapshot</li>
<li>repeated the process but just installing Powershell V1 (to make a smaller less heavy portable powershell that didn&#8217;t contain dotnet 2.0)</li>
<li>reverted and repeated the process for Powershell V2</li>
</ol>
<p>There there you have it, 4 different flavors on a Portable Powershell made in just a few hours. I can&#8217;t give them enough praise for how far Thinstall has come and how easy the process was.</p>
<p>Are there any other options?</p>
<p>Definately! Thinstall is not the sole player in this now &#8220;<a href="http://en.wikipedia.org/wiki/Application_virtualization">application virtualization</a>&#8221; arena. The management , configuration and deployment has been bundled into apps and called &#8220;<a href="http://en.wikipedia.org/wiki/Application_streaming">Application Streaming</a>&#8220;. Citrix added Application Streaming, Symantec has Altiris, and Microsoft bought out SoftGrid. The &#8220;streaming techniques aren&#8217;t typically really portable since they have some sort of agent or client/server architecture but the interesting one in this mix is software, Which i think is now renamed <strong>Microsoft Application Virtualization or APP-V for short. You can read their </strong><a href="http://blogs.technet.com/softgrid/default.aspx"><strong>blog here</strong></a><strong>. Actually the release candidate was just released </strong><a href="http://blogs.technet.com/softgrid/archive/2008/06/17/microsoft-application-virtualization-4-5-release-candidate-is-now-available.aspx"><strong>YESTERDAY</strong></a><strong>.</strong></p>
<p>With thinstall, I&#8217;m interesting what the pricing is going to be under VMWARE. When its in beta its definitely financially feasible for me to have my own personal portable powershell for personal use, but that&#8217;s probably not the case post RTM.</p>
<p>I didn&#8217;t have time to play with APP-V yet. <strong>SO MUCH CHALLENGE IS WILL SOMEBODY TRY TO VIRTUALIZE POWERSHELL WITH APP-V AND TELL US HOW IT GOES</strong>. I presume Microsoft will be more likely to allow redistribution of PowerShell through one of their own technologies <img src='http://karlprosser.com/coder/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Another cheap option I would challenge somebody is to try it in <a href="http://sandboxie.com/">sandboxie</a> , see if <a href="http://sandboxie.com/">sandboxie</a> is up to the job, as its very cheap, but i don&#8217;t know if it does full &#8220;portable&#8221;</p>
<p>Finally there is another way, that I might implement, and that is roll my own. I wouldn&#8217;t include the dotnet framework in this one (just too much work), but I can whip up a DLL in C++ and Assembler in no time to take care of powershell&#8217;s filesystem and registry needs. Of course I couldn&#8217;t redistribute portable PowerShell but I could make it into a small PORTABLEPOWERSHELLBUILDER.EXE app, that has a button that will build a portable PowerShell for you on any computer that has PowerShell installed in a similar manner to how <a href="http://www.nu2.nu/pebuilder/">BartPE</a> or <a href="http://reatogo.de/REATOGO.htm">ReatogoXPE</a> can build a bootable XP CD based on the files on a particular OS install.</p>
<p>Apart from the challenge of doing that, and doing some fun techniques that I&#8217;ve almost forgotten, and as a PowerShell tool vendor and partner of MS, I don&#8217;t want to do that. I want MS to allow PowerShell to be redistributed, in a portable manner, and if they can fit it into their schedule, do some minor reachitecture of PowerShell V2 to be naturally portable, but more on that in my next blog post.</p>
<p>Over and Out,</p>
<p>Karl Prosser / ShellTools</p>
<p style="display: inline; margin: 0px; padding: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:2b245c1f-8d9a-4862-bb44-36213b32899a" class="wlWriterSmartContent">Technorati Tags: <a rel="tag" href="http://technorati.com/tags/portable%20PowerShell">portable PowerShell</a>,<a rel="tag" href="http://technorati.com/tags/powershell">powershell</a>,<a rel="tag" href="http://technorati.com/tags/shelltools">shelltools</a>,<a rel="tag" href="http://technorati.com/tags/thinapp">thinapp</a>,<a rel="tag" href="http://technorati.com/tags/app-v">app-v</a></p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2008/06/19/portable-powershell-part-2-roll-your-own-plus-a-challenge/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Portable PowerShell &#8211; v1 and v2 side by side &#8211; even on Server Core.</title>
		<link>http://karlprosser.com/coder/2008/06/17/portable-powershell-v1-and-v2-side-by-side-even-on-server-core/</link>
		<comments>http://karlprosser.com/coder/2008/06/17/portable-powershell-v1-and-v2-side-by-side-even-on-server-core/#comments</comments>
		<pubDate>Wed, 18 Jun 2008 04:46:59 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2008/06/17/portable-powershell-v1-and-v2-side-by-side-even-on-server-core/</guid>
		<description><![CDATA[UPDATE FEB 2010We don&#8217;t need to rely on things like thinapp or app-v anymore. At ShellTools we have build our own Portable PowerShell framework. Its currently in Beta &#8211; see http://www.portablepowershell.com for more details. So I&#8217;ve loved portable apps from time memorial and have valued making my own apps as portable as possible &#8211; XCOPY [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE FEB 2010</strong>We don&#8217;t need to rely on things like thinapp or app-v anymore. At ShellTools we have build our own Portable PowerShell framework. Its currently in Beta &#8211; see <a href="http://www.portablepowershell.com">http://www.portablepowershell.com</a> for more details.</p>
<hr/>
<p>
So I&#8217;ve loved portable apps from time memorial and have valued making my own apps as portable as possible &#8211; XCOPY friendly. I&#8217;ve valued this over some fancy installer. But what about PowerShell? Why can&#8217;t PowerShell be portable. Its the sort of tool that begs to be portable. Admins want a power tool, like powershell to be portable, to be able to be run on any computer without installing anything (changing ,even contaminating the state of the computer). Admins don&#8217;t want to have to worry about installing prerequisites such as dotnet 2.0 everywhere and neither do I. I want something that can be self contained , where I can run PowerShell v1 and v2 side by side if I choose, and as a builder of PowerShell hosts, I want to be able to embed, or distribute the PowerShell runtime along with my app, just like I can with a multitude of dotnet libraries and components.</p>
<p>Well is this possible. Yes, I&#8217;ve done it. In this blog post I&#8217;ll show some screenshots and a video about it, and talk about the <strong>WHAT </strong>and the <strong>WHY</strong>, and try to whelm up some passion in the community to encourage Microsoft to allow the PowerShell engine to be redistributed freely, easily , and portably. I know that many people will ask me &#8211; Can I download this, and I have to say <em>NO</em> &#8211; because we don&#8217;t have rights from MS to redistribute PowerShell, especially outside of its official packages, but the good news is that you can make this yourself, but I&#8217;m not going to tell you <strong>HOW</strong> to until tomorrow, hoping that instead of running of to recreate your own personal PowerShell nirvana you might read the rest of my rant and join the movement for a Microsoft endorsed Portable PowerShell.</p>
<p>But before we proceed here is a screenshot:</p>
<p><a href="http://karlprosser.com/coder/wp-content/uploads/2008/06/servercore2.jpg"><img border="0" width="793" src="http://karlprosser.com/coder/wp-content/uploads/2008/06/servercore2-thumb.jpg" alt="servercore2" height="601" style="border-width: 0px" /></a></p>
<p>This beauty shows Server Core Enterprise &#8211; you can verify this isn&#8217;t a trick <a href="http://blogs.dirteam.com/blogs/sanderberkouwer/archive/2008/06/15/how-to-tell-whether-it-s-a-server-core-box.aspx">but is indeed server core</a> by the operatingsystemSKU of 14 shown in the top window. (<a href="http://msdn.microsoft.com/en-us/library/aa394239.aspx">MSDN reference.</a> ) Server Core does not have dotnet 2.0 (a prerequisite of PowerShell) installed and <a href="http://dmitrysotnikov.wordpress.com/2008/05/15/powershell-on-server-core/">we haven&#8217;t applied any cool hacks or Russian reverse engineering</a>  to get it working therefore we haven&#8217;t compromised the secure state of our servercore by installing any untested potential lasting security hole on it. We purely XCOPY across our files, or we can even run it off a USB drive. Another great benefit you see here is on the same machine we are running PowerShell V1 and V2 side by side. How many of us have had to set up a whole new machine or VM just to play with V2 CTP!!!!! and how many cough*cough have installed v2 on a production machine when we should have for lack of patience in setting up a dedicated v2 test machine?</p>
<p>So what are the features of this technique.</p>
<ul>
<li>Fully Portable</li>
<li>versions that presume dotnet 2.0s preexistence (about 3MB to 10MB)</li>
<li>Versions that don&#8217;t need dotnet 2.0 at all (about 100MB)</li>
<li>Can run V1 and V2 side by side.</li>
<li>Can run on a machine with PowerShell already installed, and your portable version has its own execution-policy and other settings.</li>
<li>Can be packaged with SnapIns (so the SnapIns are portable also, no need to install or register them).</li>
<li>Can be used with a custom Host , so you can have a Portable <a href="http://powershell.com">PowerShell Plus</a> or <a href="http://powershellanalyzer.com">PowerShell Analyzer.</a></li>
</ul>
<p>Here is a 3 minute video showing Portable Powershell v1 and v2 and PowerShell Analyzer running side by side on a virgin XP SP2 box that doesn&#8217;t have dotnet 2.0 preinstalled.</p>
<p style="display: inline; margin: 0px; padding: 0px" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:5e95055d-a592-48bb-9238-9d72349b123f" class="wlWriterSmartContent"><object width="600" height="402"></p><param name="allowfullscreen" value="true"></param><param name="allowscriptaccess" value="always"></param><param name="movie" value="http://www.vimeo.com/moogaloop.swf?clip_id=1185791&amp;server=www.vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1"></param></object></p>
<p><a href="http://www.vimeo.com/1185791?pg=embed&amp;sec=1185791">Portable PowerShell</a> from <a href="http://www.vimeo.com/klumsy?pg=embed&amp;sec=1185791">karl prosser</a> on <a href="http://vimeo.com?pg=embed&amp;sec=1185791">Vimeo</a>.</p>
<p>So now you are saying, GIVE THIS TO ME NOW. Sorry but I can&#8217;t but in my next blog entry within a couple of days I will tell you how you can roll your own Portable PowerShell.</p>
<p><strong>Please leave a comment on this blog if you are in favor of Microsoft relaxing its redistributable rules when it comes to PowerShell.</strong> Technically PowerShell doesn&#8217;t have much to stop it being Portable. Its fully dotnet, and although its installed in windows\system32 directory that is more a &#8220;political&#8221; feature , earlier betas would install elsewhere, and technically it wouldn&#8217;t be hard to make it a control in VS.NET that a custom host could merge into their project and be fully portable. There are many many possible use-cases for such portable uses  (both from the perspective of admins as well as developers creating PowerShell enabled and powered applications in the growing PowerShell ecosystem). If MS can&#8217;t make any changes technically to make it as easy as i suggest in V2, can they at least <strong>GIVE FULL REDISTRIBUTABLE RIGHTS FOR POWERSHELL</strong> as they do things such as the SQL server client side report viewer control in VS.NET.</p>
<p>All in favor say so in a comment!</p>
<p>And come back for more in a day or two.</p>
<p>Over and Out,</p>
<p>Karl Prosser / ShellTools.</p>
<p style="display: inline; margin: 0px; padding: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:c5c3050e-9890-49e5-8b16-4d80f46f55bb" class="wlWriterSmartContent">Technorati Tags: <a rel="tag" href="http://technorati.com/tags/PowerShell">PowerShell</a>,<a rel="tag" href="http://technorati.com/tags/Portable%20PowerShell">Portable PowerShell</a>,<a rel="tag" href="http://technorati.com/tags/dotnet">dotnet</a>,<a rel="tag" href="http://technorati.com/tags/Server%20core">Server core</a>,<a rel="tag" href="http://technorati.com/tags/PowerShell%20Analyzer">PowerShell Analyzer</a></p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2008/06/17/portable-powershell-v1-and-v2-side-by-side-even-on-server-core/feed/</wfw:commentRss>
		<slash:comments>47</slash:comments>
		</item>
		<item>
		<title>generating a &quot;PropertyBag&quot; aka PScustomObject in C#</title>
		<link>http://karlprosser.com/coder/2008/06/12/generating-a-propertybag-aka-pscustomobject-in-c/</link>
		<comments>http://karlprosser.com/coder/2008/06/12/generating-a-propertybag-aka-pscustomobject-in-c/#comments</comments>
		<pubDate>Fri, 13 Jun 2008 04:27:24 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Bare Metal]]></category>
		<category><![CDATA[Gotchas Etc]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2008/06/12/generating-a-propertybag-aka-pscustomobject-in-c/</guid>
		<description><![CDATA[Based on the performance testing and work being done by myself , mow , Brandon Shell and others the question has come up what is the quickest way to generate a PSCustomObject, whether in script , on in C#, and how do you even do it in C#? Some typical ways of doing in PowerShell [...]]]></description>
			<content:encoded><![CDATA[<p>Based on the performance testing and work being done by <a href="http://karlprosser.com/coder/2008/06/12/getting-serious-about-performance-in-powershell/">myself</a> , <a href="http://thepowershellguy.com/blogs/posh/archive/2008/06/11/powershell-performance-series-part-1-warming-up.aspx">mow</a> , <a href="http://bsonposh.com/">Brandon Shell</a> and others the question has come up what is the quickest way to generate a PSCustomObject, whether in script , on in C#, and how do you even do it in C#?</p>
<p>Some typical ways of doing in PowerShell have been either something like the following trick:</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">$a = 1 | select a , b , c , d</pre>
<p>or with using the Add-member cmdlet as below:</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">$a | add-member -membertype noteproperty -name status -value done</pre>
<p>however both are really slow. There is another way to do it in script, and that is directly with the PSobject, but still PowerShell (especially version 1) has a huge overhead when creating new objects with new-object but below is an example none the less.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">$obj = new-Object system.Management.Automation.PSObject</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">$note = new-object System.Management.Automation.PSnoteproperty <span style="color: #006080">"karl"</span> , <span style="color: #006080">"a value"</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">$obj.psobject.members.add( $note );</pre>
<p>But if you really want to do speed, or if you have need to generate these objects in a cmdlet regardless of speed here is how you can do it in C#.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> PSObject newPsCustomObject2()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">        {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">            <span style="color: #008000">//Creating a PSobject without any parameters in the constructor creates a PSCustomObjectg</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">            PSObject obj = <span style="color: #0000ff">new</span> PSObject();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">            <span style="color: #008000">//PSNoteProperties are not strongly typed but do contain an explicit type.</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">            obj.Properties.Add(<span style="color: #0000ff">new</span> PSNoteProperty(<span style="color: #006080">"age"</span>,24));</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">            obj.Properties.Add(<span style="color: #0000ff">new</span> PSNoteProperty(<span style="color: #006080">"name"</span>,<span style="color: #006080">"jon"</span>));</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">            <span style="color: #008000">//Alias allow you to cast one property as another as well as just plain aliasing</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">            obj.Properties.Add(<span style="color: #0000ff">new</span> PSAliasProperty(<span style="color: #006080">"ageasstring"</span>,<span style="color: #006080">"age"</span>,<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">string</span>)));</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">            <span style="color: #0000ff">return</span> obj;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">        }</pre>
<p>Some notes about the above, I didn&#8217;t show how you could add ScriptProperties or ScriptMethods yet as I wanted to keep it simple and not cover creating scriptblocks. Before I go lets performance test this baby compared to creating this in pure PowerShell.</p>
<p>So in the:</p>
<p>1) first corner we have creating the object with select-object, then setting the properties.(but we can&#8217;t set the alias)</p>
<p>2) Creating the object with new-object, then using add-member to add all the properties.</p>
<p>3) calling our static method above.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #008000">#select-object version</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #0000ff">for</span>($i = 0;$i <span style="color: #cc6633">-lt</span> 50000;$i++) { $a = 1 |Select-Object age, name; $a.age = 24; $a.name = <span style="color: #006080">"john"</span> }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #008000">#add-member version</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #0000ff">for</span>($i = 0;$i <span style="color: #cc6633">-lt</span> 50000;$i++)</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">  { $a = new-Object psobject;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">    $a | add-member -membertype noteproperty -name age -value 24</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">    $a | add-member -membertype noteproperty -name name -value <span style="color: #006080">"john"</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">    $a | add-member -membertype aliasproperty -name <span style="color: #006080">"ageasstring"</span> -value <span style="color: #006080">"age"</span> -secondvalue <span style="color: #006080">"string"</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">  }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #008000">#Our fast version</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #0000ff">for</span>($i = 0;$i <span style="color: #cc6633">-lt</span> 50000;$i++) { $a = [snapinini.newobjecthelper]::newPsCustomObject2(); }</pre>
<p>so we are creating 50,000 objects and the results are.</p>
<table border="1" width="400" cellPadding="2" cellSpacing="0">
<tr>
<td width="200" vAlign="top">select-object</td>
<td width="200" vAlign="top">27.15 seconds.</td>
</tr>
<tr>
<td width="200" vAlign="top">add-member</td>
<td width="200" vAlign="top">118.79 seconds</td>
</tr>
<tr>
<td width="200" vAlign="top">C# method</td>
<td width="200" vAlign="top">1.9 seconds.</td>
</tr>
</table>
<p>and i used to complain with the performance hit of a address lookup for a method in a C++ virtual method table!!</p>
<p>at worst the official add-member technique is over 60 times slower than calling C#, and thats not really RAW C#, thats still powershell invoking a C# method 50,000 times, and powershell managing a loop.</p>
<p>if fact just to test i added another test</p>
<p>$a = [snapinini.newobjecthelper]::newPsCustomObject3();</p>
<p>where newPSCustomObject3() moves the 50,000 loop to inside C#.. and here the speed is 0.95 seconds, so about half the speed of invoking the C# method from powershell each time &#8211; this speed difference I am happy with though. The PowerShell team seem to have done a good job of invoking C# methods quickly.</p>
<p>Another day I should investigate the speed of creating objects that have been created with the extended type system.</p>
<p>I&#8217;d love if somebody can run these tests in v2.</p>
<p>Also sometime soon I shall share a helper function you can use to quickly generate a PScustomObject with properties and values you specify in script.</p>
<p>-Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2008/06/12/generating-a-propertybag-aka-pscustomobject-in-c/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Getting serious about performance in PowerShell.</title>
		<link>http://karlprosser.com/coder/2008/06/12/getting-serious-about-performance-in-powershell/</link>
		<comments>http://karlprosser.com/coder/2008/06/12/getting-serious-about-performance-in-powershell/#comments</comments>
		<pubDate>Thu, 12 Jun 2008 05:20:47 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Gotchas Etc]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2008/06/12/getting-serious-about-performance-in-powershell/</guid>
		<description><![CDATA[I&#8217;ve spend a lot of time in the past looking at the performance of PowerShell but have never gotten around to blogging about it. However it has become quite a hot button among MVPs and others in recent days and we&#8217;ve been busy testing and comparing the speeds different techniques in PowerShell in both V1 [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve spend a lot of time in the past looking at the performance of PowerShell but have never gotten around to blogging about it. However it has become quite a hot button among MVPs and others in recent days and we&#8217;ve been busy testing and comparing the speeds different techniques in PowerShell in both V1 and V2.</p>
<p>In V1 there seems to be extreme slowdowns when invoking cmdlet, functions, any type of scriptblock and when using the pipeline. If you write a one liner that is easy to read, very elegant, but uses a lot of &#8220;powershelly&#8221; techniques its performance is often terrible, compared to it you write it out as a longer script using more traditional imperative style with &#8220;C&#8221;ish loops as the like. This brings up the whole concept of what is cheaper and more valuable &#8211; CPU cycles that keep getting cheaper, or human time in writing and maintaining code &#8211; dynamic languages and especially shells will definitely answer that programmer productivity is more valuable, and thus performance can come second.(read about it in the <a href="http://www.artima.com/intv/prodperfP.html">context of python here</a>.) However 59 millisecond average to call an empty powershell function on a dual core machine is pushing this truth to an absurdity. PowerShell should as a language should NOT be slower than BASIC on my Commodore-64 &#8211; an 1MHZ 8 bit machine.</p>
<p>Here is some background of where we are coming from. <a href="http://bsonposh.com/archives/325">Brandon Shell Started it all here</a>. And after we spend hours running tests and bantering about the subject on the #powershell IRC room on freenode, <a href="http://thepowershellguy.com/blogs/posh/archive/2008/06/11/powershell-performance-series-part-1-warming-up.aspx">Mow covered some cool stuff here</a>.</p>
<p>Basically the results of my tests showed that new-object is very slow in V1, but calling any CMDLET, even a simple C# cmdlet with one line of code is extremely slow, and about 30 to 50 times slower than calling that <strong>SAME  </strong>line of code from powershell as a static method on a C# assembly. Additionally if you take that 50 times faster static method call, and wrap in it a simple powershell function, you loose all your spend gains and its even slower than calling the new-object CmdLet.</p>
<p>The great thing from Mows tests is that in <strong>V2</strong> it seems that on the language side of things, scriptblocks,functions and the pipelines have spend up drastically (in the magnitude of about 2000% to 3000%. And cmdlet invocation has spend up also, but is about 6 times slower than just calling C# static methods. GO V2 GO V2 , but is it enough?</p>
<p>Given that V1 is going to be important for a long time, I think that powershell scripters need to still try to script in a &#8220;PowerShelly&#8221; way, but when they determine that something really has to be performant , <strong>they need to know what workarounds they can do in PowerShell to speed things up, understanding where the bottlenecks in PowerShell are.</strong></p>
<p>But this post isn&#8217;t about those performance solutions &#8211; I&#8217;m sure that we will cover a lot of them over the coming of the months. I want to RANT.</p>
<p>One of the reasons I think PowerShell has so many language quirks (and thus related gotchas when learning to do advanced stuff and solving bugs) is because it is <strong><em>Defined by Implementation </em></strong>instead of being <strong><em>Defined by Specification</em></strong>. To be honest, PowerShell is more of a platform , than a language or even a shell, and as it brings some new ideas and melds existing ideas in totally new ways, almost experimental ways, I don&#8217;t think it could have been defined any other way. However its quirks and yes also its performance is a result of that. I believe it needs to be reviewed by traditional language designers and not be excused &#8220;because its a shell language&#8221;. I believe that the importance of PowerShell is growing phenomenally and being part of Microsoft&#8217;s common engineering requirement I strongly believe such close working with the CLR team should be done, and even if PowerShell is defined by Implementation and will likely be in version 2 also &#8211; SPEND THE TIME TO AT LEAST DEFINE THE SPECIFICATION, DOCUMENT THE INTENDED (and thus real) BEHAVIOUR, RELEASE A FULL GRAMMAR, RELEASE OFFICIAL XSD SCHEMAS of the XML ELEMENTS, and if specification is what defines it, and that specification is best represented in the automated unit tests &#8211; maybe , just maybe even release such tests  , as per other dynamic languages. I think some of this stuff should at least be done BEFORE V2 is released. I mean getting a V2 and not even having a V1 grammar. &lt;/end of rant&gt;</p>
<p><u>Disclaimer:</u></p>
<p>Despite the above concerns, I love PowerShell, and the general performance doesn&#8217;t bother me. Being able to code at the speed of thought, and do things with far less code than C#, and do things interactively and dynamically totally win out. PowerShell does introduce many new tangents on concepts and mash together some amazing things, its amazing they got it as right as they did the first time. I know if I had implemented such a platform/language it would be less consistent and probably slower than a ZX81. PowerShell V2, even though only in CTP2 already shows great performance enhancements.</p>
<p>If that disclaimer gave you the warm fuzzies, don&#8217;t get too comfortable, i have another pet peeve to blog about, and that is the fallacy called &#8220;Restricted Runspaces&#8221; and how the lack of being able to truly sandbox PowerShell has me running in the direction of IronRuby &#8211; But that&#8217;s for another day.</p>
<p>-Karl / Shell Tools</p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2008/06/12/getting-serious-about-performance-in-powershell/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>SnapInini &#8211; Lite portable SnapIns with no need of registration/installation.</title>
		<link>http://karlprosser.com/coder/2008/06/07/snapinini-lite-portable-snapins-with-no-need-of-registrationinstallation-2/</link>
		<comments>http://karlprosser.com/coder/2008/06/07/snapinini-lite-portable-snapins-with-no-need-of-registrationinstallation-2/#comments</comments>
		<pubDate>Sat, 07 Jun 2008 08:27:38 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Bare Metal]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2008/06/07/snapinini-lite-portable-snapins-with-no-need-of-registrationinstallation-2/</guid>
		<description><![CDATA[One thing that has bothered me about true cmdlets in contrast scripts is that they lived in SnapIns and couldn&#8217;t be deployed with xcopy as scripts can because SnapIns required Registration/Installation. I build my own way to deal with this need some time ago, and thought that I&#8217;d start a blog series covering it. I [...]]]></description>
			<content:encoded><![CDATA[<p>One thing that has bothered me about true cmdlets in contrast scripts is that they lived in SnapIns and couldn&#8217;t be deployed with xcopy as scripts can because SnapIns required Registration/Installation. I build my own way to deal with this need some time ago, and thought that I&#8217;d start a blog series covering it. I call them Snapininis or SnapIn-Lites. A good thing is you can achieve the same end result in PowerShell V2 with modules &#8211; but that is V2 and a while away from being released, and then even further away from being fully deployed.</p>
<p>So how does this work?</p>
<p>1) you have to load an assembly into memory in powershell that contains your snapin.<br />
2) you add the cmdlets directly into the runspace that is running and tell powershell to update its list of cmdlets.</p>
<p>Here is the C# code for a sample barebones SnapInini.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 500px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #0000ff">using</span> System;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #0000ff">using</span> System.Collections.Generic;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #0000ff">using</span> System.Text;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #0000ff">using</span> System.Management.Automation;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #0000ff">using</span> System.Management.Automation.Runspaces;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #0000ff">namespace</span> Snapinini</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">{</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> DynamicCmdLet</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">    {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">        <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> Load()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">        {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">            CmdletConfigurationEntry conf = <span style="color: #0000ff">new</span> CmdletConfigurationEntry(<span style="color: #006080">"dummy-cmdlet"</span>, <span style="color: #0000ff">typeof</span>(ForeachDictionaryCmdLet), <span style="color: #0000ff">null</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">            Runspace.DefaultRunspace.RunspaceConfiguration.Cmdlets.Append(conf);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">            Runspace.DefaultRunspace.RunspaceConfiguration.Cmdlets.Update();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">            Runspace.DefaultRunspace.CreateNestedPipeline(</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">                <span style="color: #006080">"new-alias dcmd dummy-cmdlet; write-host 'snapinini loaded'"</span>,</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">                <span style="color: #0000ff">false</span>).Invoke();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">        }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">    }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">    [Cmdlet(<span style="color: #006080">"dummy"</span>, <span style="color: #006080">"cmdlet"</span>)]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> ForeachDictionaryCmdLet : System.Management.Automation.PSCmdlet</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">    {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">        <span style="color: #0000ff">protected</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> EndProcessing()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">        {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">            WriteObject(<span style="color: #006080">"hello from the dummy cmdlet"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">        }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">    }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">}</pre>
<p>In the above sample I have a very very simple cmdlet. You can see that i get the defaultrunspace, go into its RunspaceConfiguration and add the cmdlets and update the list. I am additionally running some powershell script that adds an alias to the cmdlet and writes a message to the screen just as an example showing you that you can do more stuff if you wish. In the above code the load is a static method so its easy to call from powershell once you&#8217;ve loaded the assembly, but in all honesty the Load() code could just as well have been written in the calling PowerShell.</p>
<p>So how do we load and use this in PowerShell?</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">[system.Reflection.Assembly]::LoadFrom(<span style="color: #006080">"snapinini.dll"</span>)</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">[snapinini.DynamicCmdLet]::load()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">dummy-cmdlet</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">dcmd</pre>
<p>Where to from here? This example is very simple, you could easily add multiple cmdlets into the equation, specify help files, add custom type definitions etc. Another thing I had experimented with is taking a real snapin and using reflection to see the cmdlets in it and adding them directly, however unless you know exactly what a snapin does this is dangerous because in its registration it might set up a bunch of other things also that are important.</p>
<p>Another thing I should cover next time is a safe way to load assemblies from any location and ensure that all their references get resolved seamlessly.</p>
<p>-Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2008/06/07/snapinini-lite-portable-snapins-with-no-need-of-registrationinstallation-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SnapInini &#8211; Lite portable SnapIns with no need of registration/installation.</title>
		<link>http://karlprosser.com/coder/2008/06/07/snapinini-lite-portable-snapins-with-no-need-of-registrationinstallation/</link>
		<comments>http://karlprosser.com/coder/2008/06/07/snapinini-lite-portable-snapins-with-no-need-of-registrationinstallation/#comments</comments>
		<pubDate>Sat, 07 Jun 2008 08:19:19 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2008/06/07/snapinini-lite-portable-snapins-with-no-need-of-registrationinstallation/</guid>
		<description><![CDATA[One thing that has bothered me about true cmdlets in contrast scripts is that they lived in SnapIns and couldn&#8217;t be deployed with xcopy as scripts can because SnapIns required Registration/Installation. I build my own way to deal with this need some time ago, and thought that I&#8217;d start a blog series covering it. I [...]]]></description>
			<content:encoded><![CDATA[<p>One thing that has bothered me about true cmdlets in contrast scripts is that they lived in SnapIns and couldn&#8217;t be deployed with xcopy as scripts can because SnapIns required Registration/Installation. I build my own way to deal with this need some time ago, and thought that I&#8217;d start a blog series covering it. I call them Snapininis or SnapIn-Lites.</p>
<p>So how does this work?</p>
<p>1) you have to load an assembly into memory in powershell that contains your snapin.<br />
2) you add the cmdlets directly into the runspace that is running and tell powershell to update its list of cmdlets.</p>
<p>Here is the C# code for a sample barebones SnapInini.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 500px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #0000ff">using</span> System;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #0000ff">using</span> System.Collections.Generic;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #0000ff">using</span> System.Text;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"><span style="color: #0000ff">using</span> System.Management.Automation;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #0000ff">using</span> System.Management.Automation.Runspaces;</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px"> </pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #0000ff">namespace</span> Snapinini</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">{</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> DynamicCmdLet</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">    {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">        <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> Load()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">        {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">            CmdletConfigurationEntry conf = <span style="color: #0000ff">new</span> CmdletConfigurationEntry(<span style="color: #006080">"dummy-cmdlet"</span>, <span style="color: #0000ff">typeof</span>(ForeachDictionaryCmdLet), <span style="color: #0000ff">null</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">            Runspace.DefaultRunspace.RunspaceConfiguration.Cmdlets.Append(conf);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">            Runspace.DefaultRunspace.RunspaceConfiguration.Cmdlets.Update();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">            Runspace.DefaultRunspace.CreateNestedPipeline(</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">                <span style="color: #006080">"new-alias dcmd dummy-cmdlet; write-host 'snapinini loaded'"</span>,</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">                <span style="color: #0000ff">false</span>).Invoke();</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">        }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">    }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">    [Cmdlet(<span style="color: #006080">"dummy"</span>, <span style="color: #006080">"cmdlet"</span>)]</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> ForeachDictionaryCmdLet : System.Management.Automation.PSCmdlet</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">    {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">        <span style="color: #0000ff">protected</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> EndProcessing()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">        {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">            WriteObject(<span style="color: #006080">"hello from the dummy cmdlet"</span>);</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">        }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">    }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">}</pre>
<p>In the above sample I have a very very simple cmdlet. You can see that i get the defaultrunspace, go into its RunspaceConfiguration and add the cmdlets and update the list. I am additionally running some powershell script that adds an alias to the cmdlet and writes a message to the screen just as an example showing you that you can do more stuff if you wish. In the above code the load is a static method so its easy to call from powershell once you&#8217;ve loaded the assembly, but in all honesty the Load() code could just as well have been written in the calling PowerShell.</p>
<p>So how do we load and use this in PowerShell?</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">[system.Reflection.Assembly]::LoadFrom(<span style="color: #006080">"snapinini.dll"</span>)</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">[snapinini.DynamicCmdLet]::load()</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">dummy-cmdlet</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">dcmd</pre>
<p>Where to from here? This example is very simple, you could easily add multiple cmdlets into the equation, specify help files, add custom type definitions etc. Another thing I had experimented with is taking a real snapin and using reflection to see the cmdlets in it and adding them directly, however unless you know exactly what a snapin does this is dangerous because in its registration it might set up a bunch of other things also that are important.</p>
<p>Another thing I should cover next time is a safe way to load assemblies from any location and ensure that all their references get resolved seamlessly.</p>
<p>-Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2008/06/07/snapinini-lite-portable-snapins-with-no-need-of-registrationinstallation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Determining what version of PowerShell your script is running in.</title>
		<link>http://karlprosser.com/coder/2008/06/04/determining-what-version-of-powershell-your-script-is-running-in/</link>
		<comments>http://karlprosser.com/coder/2008/06/04/determining-what-version-of-powershell-your-script-is-running-in/#comments</comments>
		<pubDate>Wed, 04 Jun 2008 06:19:49 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2008/06/04/determining-what-version-of-powershell-your-script-is-running-in/</guid>
		<description><![CDATA[Many people recently have asked how to determine programatically what version of PowerShell their script is running in. Well in version two there is a $psversiontable variable, but this sadly isn&#8217;t in V1. All is not lost though, as you can write a simple function to return a version object for v1. Below is a [...]]]></description>
			<content:encoded><![CDATA[<p>Many people recently have asked how to determine programatically what version of PowerShell their script is running in. Well in version two there is a $psversiontable variable, but this sadly isn&#8217;t in V1. All is not lost though, as you can write a simple function to return a version object for v1. Below is a quick function that I wrote that I have been using for the last year or so.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #0000ff">function</span> get-psVersion</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">{</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px"><span style="color: #0000ff">if</span> ((get-Variable psversiontabl[e]) <span style="color: #cc6633">-eq</span> $null)</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">   {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">     new-Object system.Version <span style="color: #006080">"1.0.0.0"</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">   }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">   <span style="color: #0000ff">else</span></pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">    {</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">    $psversiontable.psversion</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">    }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">}</pre>
<p>-Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2008/06/04/determining-what-version-of-powershell-your-script-is-running-in/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>140,000 downloads</title>
		<link>http://karlprosser.com/coder/2008/02/26/140000-downloads/</link>
		<comments>http://karlprosser.com/coder/2008/02/26/140000-downloads/#comments</comments>
		<pubDate>Tue, 26 Feb 2008 06:23:38 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2008/02/26/140000-downloads/</guid>
		<description><![CDATA[Our tools PowerShell Analyzer and PowerShell Plus have been downloaded over 140,000 times. YAY. We are keen to see when it goes over 150,000 as we will soon release PowerShell Plus 1.0 as start implementing some real marketing rather than just word of mouth. http://www.powershell.com -Karl]]></description>
			<content:encoded><![CDATA[<p>Our tools PowerShell Analyzer and PowerShell Plus have been downloaded over 140,000 times. YAY. We are keen to see when it goes over 150,000 as we will soon release PowerShell Plus 1.0 as start implementing some real marketing rather than just word of mouth.</p>
<p><a href="http://www.powershell.com">http://www.powershell.com</a></p>
<p>-Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2008/02/26/140000-downloads/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Trying out the latest PowerShell Plus build</title>
		<link>http://karlprosser.com/coder/2008/02/15/trying-out-the-latest-powershell-plus-build/</link>
		<comments>http://karlprosser.com/coder/2008/02/15/trying-out-the-latest-powershell-plus-build/#comments</comments>
		<pubDate>Fri, 15 Feb 2008 07:51:22 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2008/02/15/trying-out-the-latest-powershell-plus-build/</guid>
		<description><![CDATA[We are interested in people testing the latest PowerShell Plus build as we move closer to our 1.0 release. You can get it here. http://www.powershell.com/downloads/psp1.zip and if you happen across any bugs, we love it if you took a minute to submit them here. Enjoy, Karl , Tobias and Eddie / Shell Tools, LLC]]></description>
			<content:encoded><![CDATA[<p>We are interested in people testing the latest PowerShell Plus build as we move closer to our 1.0 release. You can get it here.</p>
<p><a href="http://www.powershell.com/downloads/psp1.zip" title="http://www.powershell.com/downloads/psp1.zip">http://www.powershell.com/downloads/psp1.zip</a></p>
<p>and if you happen across any bugs, we love it if you took a minute to submit them <a href="http://psplus.bugs.powershell.com">here.</a></p>
<p>Enjoy,</p>
<p>Karl , Tobias and Eddie / Shell Tools, LLC</p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2008/02/15/trying-out-the-latest-powershell-plus-build/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Has Citrix purchased workflow studio from Full Armour?</title>
		<link>http://karlprosser.com/coder/2008/02/11/has-citrix-purchased-workflow-studio-from-full-armour/</link>
		<comments>http://karlprosser.com/coder/2008/02/11/has-citrix-purchased-workflow-studio-from-full-armour/#comments</comments>
		<pubDate>Mon, 11 Feb 2008 22:22:56 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2008/02/11/has-citrix-purchased-workflow-studio-from-full-armour/</guid>
		<description><![CDATA[We&#8217;ve just recently noticed that Citrix has a workflow studio that sounds eerily like that of Full Armour&#8217;s http://www.citrix.com/English/ps2/products/product.asp?contentID=1297816 and now i can&#8217;t find the page about Full Armor Workflow Studio on their website as before. Interesting stuff, Karl]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve just recently noticed that Citrix has a workflow studio that sounds eerily like that of Full Armour&#8217;s</p>
<p><a href="http://www.citrix.com/English/ps2/products/product.asp?contentID=1297816" title="http://www.citrix.com/English/ps2/products/product.asp?contentID=1297816">http://www.citrix.com/English/ps2/products/product.asp?contentID=1297816</a></p>
<p>and now i can&#8217;t find the page about Full Armor Workflow Studio on their website as before.</p>
<p>Interesting stuff,</p>
<p>Karl</p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2008/02/11/has-citrix-purchased-workflow-studio-from-full-armour/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Data view of current pipeline results in PowerShell Plus</title>
		<link>http://karlprosser.com/coder/2008/02/10/data-view-of-current-pipeline-results-in-powershell-plus/</link>
		<comments>http://karlprosser.com/coder/2008/02/10/data-view-of-current-pipeline-results-in-powershell-plus/#comments</comments>
		<pubDate>Sun, 10 Feb 2008 19:30:19 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Feature]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Powershell Analyzer]]></category>
		<category><![CDATA[Powershell Plus]]></category>
		<category><![CDATA[pscom]]></category>
		<category><![CDATA[Shell Tools]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2008/02/10/data-view-of-current-pipeline-results-in-powershell-plus/</guid>
		<description><![CDATA[One of our goals is to bring the most important functionality of PowerShell Analyzer over to PowerShell plus as we consolidate into one product. Here is one example. It looks a little different than in PowerShell Analyzer , but we feel its just as useful, and it has a few new features added to it. [...]]]></description>
			<content:encoded><![CDATA[<p>One of our goals is to bring the most important functionality of PowerShell Analyzer over to PowerShell plus as we consolidate into one product. Here is one example. It looks a little different than in PowerShell Analyzer , but we feel its just as useful, and it has a few new features added to it.</p>
<p>In PowerShell Plus you can see Variables and properties. by enabling it from the menu (Toolbars-&gt;Variables+Property) or easily toggle it with CTRL-T</p>
<p><a href="http://karlprosser.com/coder/wp-content/uploads/2008/02/image.png"><img border="0" width="304" src="http://karlprosser.com/coder/wp-content/uploads/2008/02/image-thumb.png" alt="image" height="370" style="border: 0px" /></a></p>
<p>You can see it has rich features where you can search and filter different variables, then when you click on one have it show up in the property grid. However we aren&#8217;t going deep into that today. we are covering the &#8220;View Current Pipeline&#8221; option</p>
<p><a href="http://karlprosser.com/coder/wp-content/uploads/2008/02/image1.png"><img border="0" width="218" src="http://karlprosser.com/coder/wp-content/uploads/2008/02/image-thumb1.png" alt="image" height="95" style="border: 0px" /></a></p>
<p>When you click this button, it toggles from showing the variables. to the actual results of the pipeline. So whenever you run something.. the actual results are shown as usual on the left as text, but also the actual dotnet objects that are returned by the command show up in the variable pane. and when you click on an item there, you can see all the properties for that particular object.</p>
<p><a href="http://karlprosser.com/coder/wp-content/uploads/2008/02/image2.png"><img border="0" width="684" src="http://karlprosser.com/coder/wp-content/uploads/2008/02/image-thumb2.png" alt="image" height="480" style="border: 0px" /></a></p>
<p>So in the above example I ran a command that on the first 5 processes in the system, and the current date. In the variable explorer you can see those 5 processes and the date and time. Also the 2nd process has been clicked on, and you can see all its properties in the property grid, including descriptions of the properties. You get to see a lot more data than PowerShell gives you as text.</p>
<p>You can download Powershell Plus from <a href="http://www.powershell.com">http://www.powershell.com</a></p>
<p>-Karl</p>
<p style="display: inline; margin: 0px; padding: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:80916a97-b157-49ef-9f5b-2e8ca32f4d81" class="wlWriterSmartContent">Technorati Tags: <a rel="tag" href="http://technorati.com/tags/powershell">powershell</a>,<a rel="tag" href="http://technorati.com/tags/powershell%20plus">powershell plus</a>,<a rel="tag" href="http://technorati.com/tags/shell%20Tools">shell Tools</a>,<a rel="tag" href="http://technorati.com/tags/IDE">IDE</a>,<a rel="tag" href="http://technorati.com/tags/scripting">scripting</a></p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2008/02/10/data-view-of-current-pipeline-results-in-powershell-plus/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Find out differences in properties between two objects</title>
		<link>http://karlprosser.com/coder/2008/02/09/find-out-differences-in-properties-between-two-objects/</link>
		<comments>http://karlprosser.com/coder/2008/02/09/find-out-differences-in-properties-between-two-objects/#comments</comments>
		<pubDate>Sun, 10 Feb 2008 03:29:00 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[pscom]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2008/02/09/find-out-differences-in-properties-between-two-objects/</guid>
		<description><![CDATA[The other day in the #powershell IRC channel on freenode, a regular wanted to know how to find out the difference in properties between two objects. He had an object with 100 properties and another with about 120 or so and wanted to know which ones were unique in the second object. Compare was the [...]]]></description>
			<content:encoded><![CDATA[<p>The other day in the #powershell IRC channel on freenode, a regular wanted to know how to find out the difference in properties between two objects. He had an object with 100 properties and another with about 120 or so and wanted to know which ones were unique in the second object. Compare was the natural first place to look, but it really is good for telling the difference in CONTENT rather than SCHEMA (the object properties). Here is an example of an easy way to do this.</p>
<p style="font-size: 8pt; margin: 20px 0px 10px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; height: 105px; background-color: #f4f4f4; border: gray 1px solid; padding: 4px">
<p style="font-size: 8pt; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; height: 64px; background-color: #f4f4f4; border-style: none; padding: 0px">
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">$a = 1 | <span style="color: #0000ff">select</span>-<span style="color: #0000ff">object</span> name, age , sex</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">$<span style="color: #0000ff">b</span> = 1 | <span style="color: #0000ff">select</span>-<span style="color: #0000ff">object</span> species, name , age</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: white; border-style: none; padding: 0px">$a<span style="color: #cc6633">.psobject</span><span style="color: #cc6633">.properties</span> | % { $_<span style="color: #cc6633">.name</span> } | ? {$($<span style="color: #0000ff">b</span><span style="color: #cc6633">.psobject</span><span style="color: #cc6633">.properties</span> | % { $_<span style="color: #cc6633">.name</span> } ) -notcontains $_ }</pre>
<pre style="font-size: 8pt; margin: 0em; overflow: visible; width: 100%; color: black; line-height: 12pt; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4; border-style: none; padding: 0px">$<span style="color: #0000ff">b</span><span style="color: #cc6633">.psobject</span><span style="color: #cc6633">.properties</span> | % { $_<span style="color: #cc6633">.name</span> } | ? {$($a<span style="color: #cc6633">.psobject</span><span style="color: #cc6633">.properties</span> | % { $_<span style="color: #cc6633">.name</span> } ) -notcontains $_ }</pre>
<p>Here we simply create a couple of objects that have some similar and different properties. then the first example shows the properties in A that aren&#8217;t in B, and the next shows the properties in B that aren&#8217;t in A.</p>
<p>The main trick here is .psobject &#8230; all objects have a &#8220;hidden&#8221; <strong>psobject</strong> property that contains some cool PowerShell related stuff, including the properties. There are some good blog entries around on psobject and its definitely worth a deeper look. This technique is also the basis on a script i will introduce soon, my join-object function.</p>
<p>-Karl</p>
<p style="display: inline; margin: 0px; padding: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:7fcb9b34-77bd-47cb-813d-c7e932b5cfe2" class="wlWriterSmartContent">Technorati Tags: <a rel="tag" href="http://technorati.com/tags/powershell">powershell</a></p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2008/02/09/find-out-differences-in-properties-between-two-objects/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerShell Analyzer 1.0 and PowerShell Plus Beta Available for free.</title>
		<link>http://karlprosser.com/coder/2007/12/08/powershell-analyzer-10-and-powershell-plus-beta-available-for-free/</link>
		<comments>http://karlprosser.com/coder/2007/12/08/powershell-analyzer-10-and-powershell-plus-beta-available-for-free/#comments</comments>
		<pubDate>Sat, 08 Dec 2007 09:41:23 +0000</pubDate>
		<dc:creator>Karl</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Powershell Analyzer]]></category>
		<category><![CDATA[Powershell Plus]]></category>
		<category><![CDATA[pscom]]></category>
		<category><![CDATA[Shell Tools]]></category>

		<guid isPermaLink="false">http://karlprosser.com/coder/2007/12/08/powershell-analyzer-10-and-powershell-plus-beta-available-for-free/</guid>
		<description><![CDATA[PowerShell Analyzer 1.0 is finally released. For a week or two we consider this a &#8220;soft&#8221; launch, just in case there is some major issue that eluded our testing, but we are pretty confident its stable. Additionally, if you have already used your 45 Day trial, we have EXTENDED it another 45 days. PowerShell Plus [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://powershell.com/analyzer">PowerShell Analyzer</a> 1.0 is finally released. For a week or two we consider this a &#8220;soft&#8221; launch, just in case there is some major issue that eluded our testing, but we are pretty confident its stable.</p>
<p>Additionally, if you have already used your 45 Day trial, we have EXTENDED it another 45 days.</p>
<p><a href="http://www.powershell.com/plus">PowerShell Plus</a> is now available with a 45 Day trial as well, and Additionally its available fully free for Non Commercial use as well.</p>
<p>So download both of these today and Enjoy</p>
<ul>
<li><a href="http://www.powershell.com/downloads/PSASetup.msi"><strong><a href="http://www.powershell.com/downloads/PSASetup.msi"><strong><br />
<h2><a href="http://www.powershell.com/downloads/PSASetup.msi"><strong>PowerShell Analyzer 1.0 &#8211; Direct Download</strong></a></h2>
<p></strong></a></strong></a></li>
<li><a href="http://www.powershell.com/downloads/psp1.zip"><strong><a href="http://www.powershell.com/downloads/psp1.zip"><strong><br />
<h2><a href="http://www.powershell.com/downloads/psp1.zip"><strong>PowerShell Plus Beta &#8211; Direct Download</strong></a></h2>
<p></strong></a></strong></a></li>
</ul>
<p>PowerShell Analyzer Screen-shots.</p>
<p><img src="http://www.powershell.com/images/psa.gif" alt="PowerShell Analyzer Screenshot" /></p>
<p>To get a grasp of what PowerShell Plus can do, <a href="http://www.powershell.com/plus/video1.html"><strong>Check out its trailer</strong></a><strong>. </strong>its about 4 minutes, and definitely worth the time in our opinion.</p>
<p style="display: inline; margin: 0px; padding: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:866a21ac-35c5-4790-bcbb-b1fd7e43a347" class="wlWriterSmartContent">Technorati Tags: <a rel="tag" href="http://technorati.com/tags/Powershell%20Analyzer">Powershell Analyzer</a>,<a rel="tag" href="http://technorati.com/tags/Powershell%20Plus">Powershell Plus</a>,<a rel="tag" href="http://technorati.com/tags/Powershell%20Debugging">Powershell Debugging</a></p>
]]></content:encoded>
			<wfw:commentRss>http://karlprosser.com/coder/2007/12/08/powershell-analyzer-10-and-powershell-plus-beta-available-for-free/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

