<?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"
	>

<channel>
	<title>Huddled Masses</title>
	<atom:link href="http://www.huddledmasses.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://HuddledMasses.org</link>
	<description>You can do more than breathe for free...</description>
	<pubDate>Fri, 04 Jul 2008 13:40:21 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>PowerShell Script Repository and Code Signing</title>
		<link>http://HuddledMasses.org/powershell-script-repository-and-code-signing/</link>
		<comments>http://HuddledMasses.org/powershell-script-repository-and-code-signing/#comments</comments>
		<pubDate>Fri, 04 Jul 2008 03:56:39 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
		
		<category><![CDATA[Huddled]]></category>

		<category><![CDATA[CodeSigning]]></category>

		<category><![CDATA[Cryptography]]></category>

		<category><![CDATA[PowerShell]]></category>

		<category><![CDATA[Trust]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/powershell-script-repository-and-code-signing/</guid>
		<description><![CDATA[There&#8217;s been a lot of discussion on the #PowerShell IRC channel about code signing lately &#8212; mostly in response to my earlier posts (which I won&#8217;t link to here, because I should probably retract some of it after the discussions we&#8217;ve had). The discussion mostly revolves around how code signing applies to the PowerShell script [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s been a lot of discussion on the #PowerShell <span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Internet Relay Chat --Instant Messaging chat rooms' );"><abbr class="uttInitialism">IRC</abbr></span></span> channel about code signing lately &#8212; mostly in response to my earlier posts (which I won&#8217;t link to here, because I should probably retract some of it after the discussions we&#8217;ve had). The discussion mostly revolves around how code signing applies to the PowerShell script repository and users&#8217; ability to trust scripts that they download.</p>

	<p>In order to keep the conversation going, and hopefully, include some of the Microsoft MVPs and PowerShell developers that don&#8217;t participate in the <span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Internet Relay Chat --Instant Messaging chat rooms' );"><abbr class="uttInitialism">IRC</abbr></span></span> channel at all, I&#8217;m going to post a summary of the conclusions we&#8217;ve drawn so far, and then outline a proposal for the repository.</p>

	<p>In case you don&#8217;t know, PowerShell implements code-signing for scripts using x509 Certificates (basically, <span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'An encrypted network protocol','caption', 'Secure Sockets Layer' );"><abbr class="uttInitialism">SSL</abbr></span> (Secure Sockets Layer)</span> certs with &#8220;Extended&#8221; use properties), but the signatures are just embedded in the script as a comment, much like <span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Public/private key encryption','caption', 'Pretty Good Privacy' );"><abbr class="uttInitialism">PGP</abbr></span> (Pretty Good Privacy)</span> signatures in email.  Depending on your settings, the engine will actually check the signature on a script before executing it, and refuse to execute it if the signature isn&#8217;t valid, for instance, if the script has been modified, or the certificate used to sign it can&#8217;t be traced to a trusted Certificate Authority.</p>

	<blockquote>
		<p>PowerShell code-signing is inconvenient, and expensive. Scripts are only <strong>Valid</strong> if they are signed, unmodified, <em>and</em> the certificate traces back to a CA(Certificate Authority) that is in your Trusted Roots store (by default, basically, Microsoft&#8217;s, VeriSign, Thawte, and Comodo).</p>
		<p>You can create your own &#8220;test&#8221; certificate (that is, one that you sign yourself), but scripts signed by that certificate will only work on that computer.  This system works fine for large companies which typically have either a subscription for purchasing certificates, or their own in-house trusted CA, but not for small private developers or open source script sharing communities without financial motivation.</p>
	</blockquote>

	<p>Because of this, to take advantage of PowerShell&#8217;s code-signing on your computer (that is, to set your ExecutionPolicy to &#8220;AllSigned&#8221; or &#8220;RemoteSigned&#8221;) you must do one of these things:</p>

	<ol>
		<li>Make sure that all script authors rent and use code-signing certs which cost more than $150 a year.</li>
		<li>Add a non-commercial root CA certificate (like <a href="http://CACert.org">CACert</a>) to (all of) your computer(s), and offer your authors the option of going through the process of getting one of those instead.</li>
		<li>Create a &#8220;community&#8221; CA &#8230; and try to figure out how to make sure the certificate is secure enough to convince people to use it (yeah, ok, this was partly my idea, and it&#8217;s <em>really</em> a bad idea).</li>
		<li>Generate your own code-signing certificate (which can be self-signed) and just sign every script that you trust.</li>
	</ol>

	<p>So far, it seems like that last option is the only one that&#8217;s going to fly, because although some developers are willing to buy certificates to sign software they&#8217;re going to sell &#8230; most scripters  and sys-admins aren&#8217;t willing to buy one to share their certificates for free.</p>

	<p>So. Here&#8217;s the base fact:</p>

	<h3>The <b>Po</b>wer<b>Sh</b>ell Code repository is a repository of user-provided code.</h3>

	<p>We can&#8217;t actually afford to audit all of the code that users submit, nor take responsibility for verifying the identity of every contributor, but we&#8217;d like to have a way to do so. The <strong>best</strong> way would be to give everyone a free CodeSigning certificate from Microsoft or one of the established CAs, but we can&#8217;t afford to do that, so here&#8217;s our proposal (although it may sound like it, <em>none of this is written yet</em>, I&#8217;m just trying to get some feedback on the ideas):</p>

	<p><span class="em2">Rather than rely strictly on user login authentication, we will require that all (non anonymous) submissions be <span class="caps">SIGNED</span>, and the signing certificate (key) will be the user authentication mechanism.</span>  Essentially, any unsigned code will show up as written by &#8220;anonymous&#8221; ... and any signed code will show up with the identity from the signing certificate &#8212; the certificate must include an email address, and the first post by each key will be held back until the email address can be authenticated.</p>

	<p>In addition to the <em>author&#8217;s</em> signature on a script, other users who have used the code (or read through it without finding any issues), can also sign it as a show of trust &#8212; they simply submit the exact same script as a modification, but with their signature in place of the author&#8217;s.  </p>

	<p>So users will sign scripts to say they trust them, and when you browse or search the repository, you&#8217;ll see a lists of the users who have signed each code-snippet.  You can download a copy of the code with any of the signatures and verify the signature yourself&#8230;</p>

	<h3>Additionally, there will be a <code>Get-PoshCode</code> cmdlet which probably should:</h3>

	<ul>
		<li>Mark the downloaded scripts as &#8216;remote&#8217;.</li>
		<li>Add the download permalink <span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Uniform Resource Locator' );"><abbr class="uttInitialism">url</abbr></span> in a comment upon download (to aid in discovering other signatures and in adding <em>your</em> signature).</li>
		<li>Handle a cache of &#8220;trusted&#8221; key/certs and choose a trusted author (if there is one) from multiple available downloads, and ask you if you want to add any of the signers to your trusted list &#8212; particularly if there isn&#8217;t already a trusted signature available for the script.</li>
		<li>Validate the signature(s) after download, and provide a report (eg: valid/invalid).</li>
		<li>Offer to replace the signature (with yours) if it&#8217;s not a trusted x509 authenticode signature.</li>
	</ul>

	<h2>What certificate system should we use?</h2>

	<p>You may have assumed that we&#8217;re planning on using Microsoft&#8217;s code signing which is built into PowerShell, but when we were discussing this in the <span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Internet Relay Chat --Instant Messaging chat rooms' );"><abbr class="uttInitialism">IRC</abbr></span></span> channel, one of the things that kept coming up is that one way or another, we&#8217;re essentially creating an alternative way for people to &#8220;trust&#8221; the certificate &#8212; since we&#8217;re assuming that most of these certificates will be self-signed. </p>

	<p>That is, if we use x509, we&#8217;ll <span class="caps">STILL</span> be creating an alternate way for people to say that they trust the x509 certs, and thus, using them in a way they weren&#8217;t intended. If we use <span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Public/private key encryption','caption', 'Pretty Good Privacy' );"><abbr class="uttInitialism">PGP</abbr></span></span>, we&#8217;ll basically be using them as intended, and will have peer key-signing as a trust mechanism, but we&#8217;re <span class="caps">STILL</span> introducing a secondary way for users to establish trust for PowerShell scripts which doesn&#8217;t integrate with the engine&#8217;s policy settings, thus making things more complicated.</p>

	<p>Let me sum up the positive and negative sides of what I see as our two options.</p>

	<h3>x509 (aka &#8220;Authenticode&#8221;) signatures &#8212; supported by Microsoft.</h3>

	<ul>
		<li>Probably self-signed and therefore won&#8217;t &#8220;work&#8221; properly in PowerShell anyway.</li>
		<li>Some of them would probably be commercial certificates issued by trusted CAs like Thawte or Comodo, giving you instant trust in the identity of the author. In that case, they would additionally be:</li>
		<li>Verifiable by PowerShell natively, and therefore, they: </li>
		<li>Don&#8217;t require a separate signature in order to execute when the <code>ExecutePolicy</code> is set to <strong>AllSigned</strong>.</li>
	</ul>

	<h3><span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Public/private key encryption','caption', 'Pretty Good Privacy' );"><abbr class="uttInitialism">PGP</abbr></span></span> signatures (supported by the Open Source community and used in Debian, etc)</h3>

	<ul>
		<li>Just as (un)trustworthy as any other <span class="em1">self-signed certificate</span> ... except that:</li>
		<li><span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Public/private key encryption','caption', 'Pretty Good Privacy' );"><abbr class="uttInitialism">PGP</abbr></span></span> certificates (keys) are inherently user-signable. The community can vouch for each other&#8217;s identities, and create a web-of-trust for authentication purposes (which is all x509 really accomplishes anyway &#8212; you trust that Verisign makes sure that they are who they say they are, and live where they say they live).</li>
		<li>Not inherently usable by PowerShell.</li>
		<li>AllSigned mode requires re-signing (probably with a self-signed cert). This also means that if you have an x509 authenticode-signed script to submit, we would still need you to re-sign it with a <span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Public/private key encryption','caption', 'Pretty Good Privacy' );"><abbr class="uttInitialism">PGP</abbr></span></span> certificate when you wanted to upload it.</li>
	</ul>

	<h2>Final thoughts</h2>

	<p>Of course, there&#8217;s a lot of outstanding issues with this idea.  But I wanted to put it out there for some broader feedback, particularly because we really are thinking about using <span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Public/private key encryption','caption', 'Pretty Good Privacy' );"><abbr class="uttInitialism">PGP</abbr></span></span> certificates since they can be counter-signed by other users, and since the general consensus opinion is that actually expecting scripters to buy code-signing certificates is just out of the question.</p>

	<p>So the first question is, can we do <span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Public/private key encryption','caption', 'Pretty Good Privacy' );"><abbr class="uttInitialism">PGP</abbr></span></span> signing in pure .Net for a cmdlet (maybe using <a href="http://www.bouncycastle.org/csharp/index.html">bouncy castle</a>), and can we easily create a Set-PGPSignature cmdlet? </p>

	<p>Has there been any progress on a way to do <span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Public/private key encryption','caption', 'Pretty Good Privacy' );"><abbr class="uttInitialism">PGP</abbr></span></span> signing that&#8217;s compatible with <span class="caps"><a href="http://www.w3.org/XML/" class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'eXtensible Markup Language' );"><abbr class="uttInitialism">XML</abbr></a></span> files (eg: ps1xml files)? </p>

	<p>Can we do signature checking in-memory, so we can download the script with <em>many</em> signatures embedded and stitch them together for verification without creating multiple temporary files?</p>

	<p><strong>Regardless</strong>, if you trust a signature, but the signature isn&#8217;t Authenticode (<span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Public/private key encryption','caption', 'Pretty Good Privacy' );"><abbr class="uttInitialism">PGP</abbr></span></span>) or isn&#8217;t Valid (self-issued), the PowerShell security measures will require <strong>you</strong> (the end user) to sign the script in order to allow it to execute &#8212; essentially, every signed script on your system will be signed by you (or your sysadmin) and so, signing essentially becomes the administrator&#8217;s equivalent of blessing a script, and is somewhat like setting the eXecute flag on a linux script &#8212; except that you have to re-set it every time you edit the script.</p>

	<h5>We need to make signing slightly easier.</h5>

	<p>It&#8217;s a pain to find your certificate, and the built-in AuthenticodeSignature cmdlets are <strong>horrible</strong> at parsing parameters.</p>

	<h5>We need to make generating these self-signing certs trivial for non-<span class="caps">SDK</span> machines</h5>

	<p>It&#8217;s really pretty easy with MakeCert, but that&#8217;s not redistributable, and the Windows <span class="caps">SDK</span> is a ridiculously large download for someone who just wants to sign their scripts.  I&#8217;ve written a script to <a href="http://huddledmasses.org/code-signing-with-openssl-and-powershell/#more-551">generate code-signing certs</a> using OpenSSL, which <em>is</em> redistributable, but it&#8217;s still not great.</p>]]></content:encoded>
			<wfw:commentRss>http://HuddledMasses.org/powershell-script-repository-and-code-signing/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Getting Started with PowerShell 2 - Part 2</title>
		<link>http://HuddledMasses.org/getting-started-with-powershell-2-part-2/</link>
		<comments>http://HuddledMasses.org/getting-started-with-powershell-2-part-2/#comments</comments>
		<pubDate>Mon, 30 Jun 2008 04:50:05 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
		
		<category><![CDATA[Huddled]]></category>

		<category><![CDATA[CodeSigning]]></category>

		<category><![CDATA[GettingStarted]]></category>

		<category><![CDATA[Modules]]></category>

		<category><![CDATA[PowerShell]]></category>

		<category><![CDATA[WalkThrough]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/?p=559</guid>
		<description><![CDATA[This continues a short series of posts about getting started with PowerShell &#8230; with a few tips about things you can do to keep your PowerShell profile safe and organized.  Your &#8220;profile&#8221; is the script that is automatically loaded when you start up PowerShell.  Really, I should say that your profile is the [...]]]></description>
			<content:encoded><![CDATA[<p>This continues a short series of posts about getting started with PowerShell &#8230; with a few tips about things you can do to keep your <a href="http://www.microsoft.com/technet/scriptcenter/topics/winpsh/manual/profile.mspx">PowerShell profile</a> safe and organized.  Your &#8220;profile&#8221; is the script that is automatically loaded when you start up PowerShell.  Really, I <em>should</em> say that your profile is the <em>set</em> of scripts which are loaded <em>by default</em> when you start up PowerShell.  &#8220;By default&#8221; because you can always skip loading them by passing the -NoProfile switch to PowerShell.exe, and a set because PowerShell does, in fact, attempt to load <em>at least</em> four scripts when you run it:</p>

	<p>PowerShell loads &#8220;machine&#8221; profile scripts (which are located in the PowerShell folder) and &#8220;user&#8221; profile scripts (located in your Documents\WindowsPowerShell folder). But there&#8217;s a little more to it than that: PowerShell is a scripting engine which can be hosted inside any app, PowerShell.exe is a DOS-style console which is the default host.  There are several third-party hosts available such as <a href="http://PowerShell.com/">PowerShell Plus</a> and <a href="http://PowerGUI.org/">PowerGUI</a> and several open source hosts such as <a href="http://CodePlex.com/BgShell/">BgShell</a> and <a href="http://CodePlex.com/PoshConsole/">PoshConsole</a> &#8230; in order to support this ecosystem of hosts, the default PowerShell behavior is to load a host-specific profile script (for both the machine settings and the local-user settings).  Not all hosts will do that, but anyway &#8230; the default host loads <code>Microsoft.PowerShell_profile.ps1</code> and <code>Profile.ps1</code> from both the user and machine locations. </p>

	<p>By default, none of those profiles actually exist. Once you&#8217;ve <a href="/getting-started-with-powershell-2-part-1">installed everything as in Part 1</a>, you should have a Profile.ps1 file provided by <acronym title="PowerShell Community Extensions">PSCX</acronym>. This profile defines a whole bunch of values that are used by various <span class="caps">PSCX</span> cmdlets and scripts, so you may want to change some of it, but you should be careful about just deleting things until you&#8217;re well acquainted with the <span class="caps">PSCX</span> cmdlets.  Over time, I&#8217;ve added settings to my profile for other snapins as well, and there gets to be a lot of noise in there that&#8217;s specific to different snapins, so instead of just leaving all of that in my main profile, I rename the Profile.ps1 file provided by <span class="caps">PSCX</span> and then dot-source it from a new blank profile script.</p>

	<p>In fact, and I found that I started collecting a lot of scripts in my WindowsPowerShell folder so I created a sub-folder for them, and I automatically load everything that&#8217;s in that folder, so I don&#8217;t have to manually dot-source things when I add a new snapin profile. </p>

	<h3>Authenticode Signing your auto-load scripts</h3>

	<p>In order to make sure that automatically loading scripts doesn&#8217;t become a way for people to attack my computer, I made a decision awhile ago that I would only auto-load signed scripts. The how and why of this is a bit much to get into, and I wrote about <a href="http://huddledmasses.org/code-signing-with-openssl-and-powershell/">Generating Windows Authenticode Code-Signing Certificates with OpenSSL</a> a while back, so you can read that if you want more details, I want to review the simplest steps.</p>

	<p><img src='http://HuddledMasses.org/wordpress/wp-content/plugins/smilingmasses/new.gif' alt='[new]' class='wp-smiley' /> <strong>Edit</strong>: I should take a moment here to point out, in case you&#8217;re really new to PowerShell, that the first thing you&#8217;ll have to do is fix the error &#8220;File &#8230; cannot be loaded because the execution of scripts is disabled on this system.&#8221;  I originally was just assuming you would have figured that out &#8212; it tells you to read the about_signing help, so you can just execute <code>get-help about_signing</code> and it explains in there what you need to do.  In case you haven&#8217;t gotten that far, before you can execute the New-CodeSigningCert you&#8217;re going to need to run PowerShell as administrator (&#8220;elevated&#8221;) and execute this command: <code>Set-ExecutionPolicy RemoteSigned</code> &#8230; that will let you execute most scripts that you have saved locally without having signed them.  You may want to tighten that up later and set it to &#8220;AllSigned,&#8221; but first you have to be able to sign scripts.</p>

	<h4>Generating a code-signing certificate</h4>

	<p><strong>Step 1.</strong> Download my <a href="http://huddledmasses.org/?attachment_id=554">PoshCerts package</a> and unpack it in your WindowsPowerShell folder &#8212; lets say in, WindowsPowerShell\Certs\bin.</p>

	<p><strong>Step 2.</strong> In an <span class="em2b">elevated console</span>, run the New-CodeSigningCert script to generate into the Certs folder. So if you&#8217;re in the WindowsPowerShell directory, you can just run it and you&#8217;ll be prompted for a few pieces of information that the certificates require, plus two passwords &#8212; and all of the keys will be generated into the Certs folder as files, and imported to your local store.  Make sure you make a note of those passwords.</p>

	<div class="code posh" style="font-family: monospace;"><br />
<span style="color: #660033;">cd</span> <span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">Split-<span style="font-style: normal;">Path</span></span> <span style="color: #660033; font-weight: bold;">$Profile</span><span style="color: #333;">&#41;</span>\PoshCerts\<br />
.\bin\<span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">CodeSigningCert</span></span>.<span style="color: #003366;">ps1</span> <span style="color: #660033; font-weight: bold;">$pwd</span> <span style="color: #009900;">&quot;[Your Name]&quot;</span> <span style="color: #009900;">&quot;[Your Email]&quot;</span> <span style="color: #000066;">-ImportAll</span><br />
&nbsp;</div>

	<h4>Signing Scripts</h4>

	<p><strong>Step 3.</strong> Actually, there&#8217;s really no step three. You can now sign scripts at will using the <strong>pfx</strong> file generated in step 2 with the Get-PfxCertificate cmdlet, or the <span class="caps">PSCX</span> Cert: provider (more on that later).  Let&#8217;s rename our Profile.ps1 script and then sign it.  We&#8217;ll create create a folder called &#8220;AutoModules&#8221; to stick your <span class="caps">PSCX</span> profile (and any future such scripts) in. If you&#8217;re still on PowerShell 1, you&#8217;ll just put the .ps1 files into that folder, and we&#8217;ll dot-source them. </p>

	<div class="code posh" style="font-family: monospace;"><br />
<span style="color: #660033;">cd</span> <span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">Split-<span style="font-style: normal;">Path</span></span> <span style="color: #660033; font-weight: bold;">$Profile</span><span style="color: #333;">&#41;</span><br />
<span style="color: #660033;">mkdir</span> AutoModules<br />
<span style="color: #666666; font-style: italic;"># Sign it (you'll reuse this exact code in a moment)</span><br />
<span style="color: #0066cc; font-style: italic;">Set-<span style="font-style: normal;">AuthenticodeSignature</span></span> <span style="color: #000066;">-Cert</span> <span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># You'll be prompted for your code-signing cert password here:</span><br />
&nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">PfxCertificate</span></span> .\PoshCerts\*Code-Signing.<span style="color: #003366;">pfx</span><br />
&nbsp; &nbsp; <span style="color: #333;">&#41;</span> .\<span style="color: #660033;">Profile</span>.<span style="color: #003366;">ps1</span><br />
<span style="color: #666666; font-style: italic;"># Now move it (the signature doesn't care about the file name).</span><br />
mv .\<span style="color: #660033;">Profile</span>.<span style="color: #003366;">ps1</span> .\AutoModules\PSCX.<span style="color: #003366;">ps1</span><br />
<br />
&nbsp;</div>

	<h4>Checking for valid signatures</h4>

	<p>Once you&#8217;ve got that set up, we need to create the new profile script and modify it to load not just the <span class="caps">PSCX</span> module, but any other <strong>signed</strong> scripts we put in there.  Paste this into your new Profile.ps1, and don&#8217;t forget to sign it.</p>

	<div class="code posh" style="font-family: monospace;"><br />
<span style="color: #660033; font-weight: bold;">$ProfileDir</span> = <span style="color: #0066cc; font-style: italic;">Split-<span style="font-style: normal;">Path</span></span> <span style="color: #660033; font-weight: bold;">$MyInvocation</span>.<span style="color: #003366;">MyCommand</span>.<span style="color: #003366;">Path</span><br />
<br />
<span style="color: #666666; font-style: italic;">## If we're on version two, we need to set the PsPackagePath (it doesn't hurt anything anyway)</span><br />
<span style="color: #660033; font-weight: bold;">$ENV</span>:PSPACKAGEPATH = <span style="color: #009900;">&quot;$ProfileDir\AutoModules&quot;</span><br />
<br />
<span style="color: #666666; font-style: italic;">## Now, preload any script in AutoModules that is signed ...</span><br />
<span style="color: #666666; font-style: italic;">##### Problem 1:&nbsp; There's a bug which prevents signing or checking psm1 files</span><br />
<span style="color: #666666; font-style: italic;">##### I'll show you how to work around that in Part 3</span><br />
<span style="color: #666666; font-style: italic;">##### For now you don't have any, so this is quite simple:</span><br />
<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">ChildItem</span></span> <span style="color: #660033; font-weight: bold;">$ProfileDir</span>\AutoModules\* <span style="color: #000066;">-include</span> *.<span style="color: #003366;">ps1</span> <span style="color: #000066;">-recurse</span> | <br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">AuthenticodeSignature</span></span> | <br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Where-<span style="font-style: normal;">Object</span></span> <span style="color: #333;">&#123;</span><span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">Status</span> <span style="color: #000066;">-eq</span> <span style="color: #009900;">&quot;Valid&quot;</span><span style="color: #333;">&#125;</span> | <br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">ChildItem</span></span> | &amp;<span style="color: #333;">&#123;</span> <span style="color: #666699; font-weight: bold;">PROCESS</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">switch</span> <span style="color: #000066;">-regex</span> <span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$_</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&quot;.*\.ps1$&quot;</span>&nbsp; &nbsp; <span style="color: #333;">&#123;</span> . <span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">FullName</span>; <span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Verbose</span></span> <span style="color: #009900;">&quot;Loaded $_&quot;</span> <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&quot;.*\.ps1xml$&quot;</span> <span style="color: #333;">&#123;</span> <span style="color: #0066cc; font-style: italic;">Update-<span style="font-style: normal;">TypeData</span></span> <span style="color: #000066;">-PrependPath</span> <span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">FullName</span>&nbsp; <span style="color: #333;">&#125;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">default</span>&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #333;">&#123;</span> <span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Verbose</span></span> <span style="color: #009900;">&quot;Not sure what to do with: $($_.Name)&quot;</span> <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span> <span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p><span class="em2b">If you&#8217;re testing PowerShell 2</span>, you&#8217;ll want to treat these scripts as <a href="/powershell-modules/">Modules</a> &#8230; SnapIns themselves can be loaded as modules in PowerShell 2, but so can any script which needs to be dot-sourced. In this case, the easiest thing is to create a subfolder for each one and then use Add-Module with the folder name. There are some problems with that, which I&#8217;ll go into in Part 3 (no link until I&#8217;ve written it this time, I learned my lesson).</p>]]></content:encoded>
			<wfw:commentRss>http://HuddledMasses.org/getting-started-with-powershell-2-part-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Getting Started with PowerShell 2 - Part 1</title>
		<link>http://HuddledMasses.org/getting-started-with-powershell-2-part-1/</link>
		<comments>http://HuddledMasses.org/getting-started-with-powershell-2-part-1/#comments</comments>
		<pubDate>Sat, 28 Jun 2008 21:29:56 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
		
		<category><![CDATA[Huddled]]></category>

		<category><![CDATA[GettingStarted]]></category>

		<category><![CDATA[PowerShell]]></category>

		<category><![CDATA[WalkThrough]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/getting-started-with-powershell-2-part-1/</guid>
		<description><![CDATA[I&#8217;ve decided to spend part of this weekend organizing my sock drawer PowerShell profile, and since there doesn&#8217;t seem to be a lot of best practices or prescriptive advice on setting up your PowerShell profile, I thought I&#8217;d write about how I do it, to help any new users out there get started.  

	If [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve decided to spend part of this weekend organizing my <del>sock drawer</del> <ins>PowerShell profile</ins>, and since there doesn&#8217;t seem to be a lot of best practices or prescriptive advice on setting up your PowerShell profile, I thought I&#8217;d write about how I do it, to help any new users out there get started.  </p>

	<p>If you are a .Net developer or a Computer Science researcher, and haven&#8217;t started using PowerShell, let me just make this argument for learning it:</p>

	<blockquote>
		<p>PowerShell cmdlets are simple to write. The additional code required to make a .Net class into a cmdlet is very minor (at a minimum, a single method with a line of code to <code>Write-Output</code> something). Since cmdlets must derive from either Cmdlet or PSCmdlet you can&#8217;t just write every class as a cmdlet, but even non-cmdlet classes can be instantiated via <code>New-Object</code> and their methods and properties can be exercised. </p>
		<p>After writing portions of a recent research project as PowerShell cmdlets, I would say that the ability to write a simple class and then use/execute from the command line and in scripts &#8212; plus the built in automatic argument parsing (PowerShell assigns pipeline input and command line parameters to object properties for you) makes PowerShell cmdlets quite useful for research and development. Because the overhead is so minimal, it minimizes the distractions of creating a user interface and allows you to focus your actual research goals. Additionally, because the PowerShell-specific code can be restricted to attributes and a method or two, the actual classes are still usable for other purposes.  That is, your class is invokable within PowerShell, but it&#8217;s also reusabe within any .Net application, whether Windows.Forms, <span class="caps">WPF</span>, or even web apps.</p>
	</blockquote>

	<p>Of course, since I&#8217;m primarily using PowerShell for research and development, I&#8217;m using the current <span class="caps">CTP</span> 2 release of PowerShell v2, some of what I&#8217;m doing in my profile won&#8217;t work until PowerShell 2 is released (next year?).  I&#8217;ll try to mark the <span class="em2b">CTP-only</span> features appropriately and offer PowerShell 1-compatible workarounds.</p>

	<p>The first step, of course, is to install the software.  To take full advantage of PowerShell 2, you need to have the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=333325FD-AE52-4E35-B531-508D977D32A6">.Net Framework 3.5</a> although you could use the <a href="http://www.microsoft.com/downloads/details.aspx?familyid=79BC3B77-E02C-4AD3-AACF-A7633F706BA5&#38;amp;displaylang=en">.Net Framework 2.0</a> instead if you&#8217;re just using PowerShell 1.0.  PowerShell 1 is only available as a &#8220;patch&#8221; so you have to choose the correct download for your platform through the <a href="http://go.microsoft.com/fwlink/?LinkId=79444">Microsoft Download Center</a>. However, since it&#8217;s still in <span class="caps">CTP</span> release, there is an installer for <a href="http://www.microsoft.com/downloads/details.aspx?familyid=7c8051c2-9bfc-4c81-859d-0864979fa403">PowerShell 2 CTP2</a>.</p>

	<p>I also use the <a href="http://www.codeplex.com/PowerShellCX" title="PSCX">PowerShell Community Extensions</a> and recommend them, although there&#8217;s a lot in there you may not use, there&#8217;s also a lot of extremely useful things &#8212; some of which are practically requirements.  <span class="dem1">This package needs updating to work <em>well</em> with PowerShell 2</span>, because PowerShell 2 has implemented natively some of the most popular features in <span class="caps">PSCX</span>, but it&#8217;s just a few minor changes. If you&#8217;re just getting started (or want to follow along with this series of posts), you should let <span class="caps">PSCX</span> install it&#8217;s profile (if you already have a profile, then in order to follow along with these posts, you should <span class="caps">MOVE</span> your profile out of the way before you install <span class="caps">PSCX</span>, and go ahead and let it create a profile from scratch).  </p>

	<p><a href="/getting-started-with-powershell-2-part-2">Part 2</a></p>]]></content:encoded>
			<wfw:commentRss>http://HuddledMasses.org/getting-started-with-powershell-2-part-1/feed/</wfw:commentRss>
		</item>
		<item>
		<title>PowerShell Authenticode Signatures and trust&#8230;</title>
		<link>http://HuddledMasses.org/powershell-authenticode-signatures-and-trust/</link>
		<comments>http://HuddledMasses.org/powershell-authenticode-signatures-and-trust/#comments</comments>
		<pubDate>Wed, 25 Jun 2008 03:44:55 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
		
		<category><![CDATA[Huddled]]></category>

		<category><![CDATA[Apt-Get]]></category>

		<category><![CDATA[Authenticode]]></category>

		<category><![CDATA[Certificates]]></category>

		<category><![CDATA[Code Signing]]></category>

		<category><![CDATA[PowerShell]]></category>

		<category><![CDATA[Repository]]></category>

		<category><![CDATA[Scripting]]></category>

		<category><![CDATA[SSL]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/powershell-authenticode-signatures-and-trust/</guid>
		<description><![CDATA[The cool thing about the way authenticode signatures are implemented is that even if a script is signed with a self-issued certificate, you can still tell if the script has been tampered with&#8230; Check this out:


[1]:ls SCRIPTS:\UnknownCert\Sample*.ps1,SCRIPTS:\TrustedCert\Sample*.ps1 &#124; gas


    Directory: SCRIPTS:\UnknownCert\


SignerCertificate            [...]]]></description>
			<content:encoded><![CDATA[<p>The cool thing about the way authenticode signatures are implemented is that even if a script is signed with a self-issued certificate, you can still tell if the script has been tampered with&#8230; Check this out:</p>

<div class="code posh" style="background: black; color: #ccc; font-weight:bold; line-height:0.5em;">
<span style="color:#ffcc00;">[1]:</span>ls SCRIPTS:\UnknownCert\Sample*.ps1,SCRIPTS:\TrustedCert\Sample*.ps1 | gas<br />
<br />

    Directory: SCRIPTS:\UnknownCert\<br />
<br />

SignerCertificate                         Status        Path<br />

&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-                         &#8212;&#8212;&#8212;        &#8212;&#8212;<br />

0DA3A2A2189CD74AE371E6C57504FEB9A59BB22E  UnknownError  Sample.ps1<br />

0DA3A2A2189CD74AE371E6C57504FEB9A59BB22E  HashMismatch  SampleBAD.ps1<br />
<br />

    Directory: SCRIPTS:\TrustedCert\<br />
<br />

SignerCertificate                         Status        Path<br />

&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-                         &#8212;&#8212;&#8212;        &#8212;&#8212;<br />

B658C20AAD070B9FF105C69BBC47ADCF56FD5576  Valid         Sample.ps1<br />

B658C20AAD070B9FF105C69BBC47ADCF56FD5576  HashMismatch  SampleBAD.ps1
</div>

	<p>As you can see, in the case of a <span class="caps">UNTRUSTED</span>, but correct, signature, you get the <strong>UnknownError</strong> status. If you checked the output object, it has a <code>StatusMessage</code> which says <em>&#8220;A certificate chain could not be built to a trusted root authority&#8221;</em>. If the script has been altered (as in my SampleBAD.ps1 scripts) then the signature is incorrect, you get the <strong>HashMismatch</strong> status, and the corresponding <code>StatusMessage</code> is: <em>&#8220;The contents of file SCRIPTS:\TrustedCert\SampleBAD.ps1 may have been tampered because the hash of the file does not match the hash stored in the digital signature. The script will not execute on the system&#8230;&#8221;</em></p>

	<p>One odd thing is that the messages are inaccurate about not executing the script: if you have your execution policy set to Unrestricted, the signatures aren&#8217;t checked at all, and if you have it set to RemoteSigned they are only checked for remote scripts. Furthermore: if you do have your execution policy set to AllSigned, neither the <strong>UnknownError</strong> nor the <strong>HashMismatch</strong> script will execute &#8212; only the one <strong>Valid</strong> scripts will.</p>

	<h3>So what?</h3>

	<p>The bottom line is: you can verify that nothing has happened to the script &#8212; even if you don&#8217;t trust the person who signed it <em>nor</em> the person, group, or company that issued a certificate to them.  Why does this matter? Well, I recently wrote a post about <a href="http://huddledmasses.org/code-signing-with-openssl-and-powershell/">generating self-signed code-signing certificates</a> which can be used for signing PowerShell scripts, and if you chose to distribute scripts signed with one of those certificates, nobody would be able to verify the root CA(Certificate Authority) and so the signatures would never come out as valid.</p>

	<p>Is there any usefulness in this? Well, I guess that depends on your perspective, but basically, <span style="font-size: 1.1em; font-weight: bold; color:#cc3399;">I think that if I published my scripts signed and tell you on my blog what my certificate thumbprint is &#8230; that you&#8217;d be more able to trust those scripts than you are now (when they&#8217;re not signed at all)</span>.  Of course, I could go one step further, and publish my own self-signed root CA certificate so you could choose to trust that &#8230;</p>

	<p>I was recently having a conversation about the future of the <a href="http://PowerShellCentral.com/scripts/">PowerShell Script Repository</a> and it involved some discussion of whether it would be safe to use the <a href="http://huddledmasses.org/automating-the-powershell-script-repository/">Repository Scripts</a> to download dependencies automatically&#8230; The answer, obviously, is <strong>no</strong>. </p>

	<p>But it started me thinking again about scripts being signed. If you had already chosen to run a script provided by me (which was signed by a certificate you couldn&#8217;t verify), maybe you&#8217;d be willing to trust other scripts signed by the same certificate, so we <em>could</em> automatically download them.  Well, maybe even then you wouldn&#8217;t want to trust it, but lets assume that you were running a copy of the PowerShell Script Repository internally at your company &#8230;</p>

	<h3>Would you use automatic dependency downloading?</h3>

	<p>We could easily have a function that takes the script name and verifies that you have that script available &#8212; and if not, it could fetch the script from your designated repository and verify that the signature is valid even if the certificate isn&#8217;t signed by a root certificate authority you trust.</p>

	<p>Of course, such automatically downloaded scripts would need to be marked as &#8220;Remote&#8221; so if you had your Execution Policy set to AllSigned or Remote Signed, then the script would only run if you had trusted it&#8217;s author (and you wouldn&#8217;t even be offered the option if you hadn&#8217;t trusted the CA(Certificate Authority) that issued his script.  In that case you would need to review the script and re-sign it yourself &#8212; or manually remove the &#8220;remote&#8221; bit.</p>

	<p>Imagine something like this:</p>

	<div class="code posh" style="font-family: monospace;"><br />
<span style="color: #666666; font-style: italic;"># Get-Paste.ps1</span><br />
<span style="color: #666699; font-weight: bold;">function</span> <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Paste</span></span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Resolve-<span style="font-style: normal;">Dependency</span></span> <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Webfile</span></span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># lots of code here that uses the Get-Webfile function ...</span><br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Webfile</span></span> http://HuddledMasses.<span style="color: #003366;">org</span>/<br />
<span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>When you tried to execute Get-Paste, it would check for Get-Webfile, and if it couldn&#8217;t find it, would attempt to download it (presumably this would involve asking your permission, and placing it in some specific location that was in your <span class="caps">PATH</span>, so that the script could find it when it tried to execute it on the next line).</p>

	<h4>Or maybe, an Apt-Get?</h4>

	<p>Perhaps instead of this mechanism, we could use the new embeddable &#8220;Data Language&#8221; to provide a list of dependencies, like: <code>DATA Dependencies { scripts = Get-WebFile }</code> and run a <code>Resolve-Dependencies</code> function against each script before trying to execute it &#8212; this way, if you downloaded a script from the repository using <code>Get-Paste</code>, it could automatically <code>Resolve-Dependencies</code> and offer to download the other scripts at the same time.</p>

	<p>The fact is that doing this <em>correctly</em> will require some major reworking of the script repository to allow tracking new versions of scripts better, and to let the script repository track dependencies explicitly so that you don&#8217;t have to download the whole script to find out what it&#8217;s dependencies are, but this could be done, if people are actually interested in it.</p>

	<h3>A web of trust?</h3>

	<p>Ad I&#8217;m thinking about this, I&#8217;m wondering again about the possibility of creating an informal web-of-trust style code-signing certificate tree.  The idea would be that <span style="font-size: 1.05em; font-weight: bold; color:#cc3399;">the Script Repository would have a CA certificate of it&#8217;s own, and would issue code-signing certificates to PowerShell developers</span> <em>cheaply</em> (free?) by skipping over some of the usual verification steps. In an ideal world, Microsoft would issue the PowerShell Community a &#8220;SubCA&#8221; certificate signed by their root &#8212; in the interests of promoting code signing for PowerShell &#8230; </p>

	<p>However, if we couldn&#8217;t get a SubCA certificate for &#8220;free&#8221; or cheap, we could simply generate and self-sign our own, and publish it on the Script Repository website, requiring users to download and import it into their trusted roots if they wanted to use trust permissions. Regardless of whether they chose to trust it or not, they could still verify the scripts were valid, which is better than what we have now &#8212; the rest would be up to the user.</p>

	<p>Of course, if we were issuing certificates that were self-signed anyway, we could go a step further and sign SubCAs and distribute them to, say, the Microsoft PowerShell MVPs and trusted community leaders after verifying email addresses and physical mailing addresses etc &#8230; trusting <strong>them</strong> further to issue (less trusted) code-signing certificates to additional developers.</p>

	<h4>Call to action</h4>

	<p>All of this is extra work for the people maintaining the script repository web site (right now, that&#8217;s me), but it might be worth it if it makes it easier to use the script repository, easier to trust the scripts on it, and easier to verify that an author <strong>is</strong> who he says he is &#8230; what do <em>you</em> think?</p>

	<ol>
		<li>Should we put in the work to set up a web of trust or should we leave it up to individual developers to self-sign and generate their certificates (and publish their public roots on their websites <em>or something</em>)?</li>
		<li>Should we just leave it at that (scripters can sign their scripts if they feel like it), or should we push and promote script signing? As an incomplete example of <em>promoting</em> code-signing, I mean:
	<ol>
		<li>We can use certificates as the primary (or only) way for authors to identify themselves (that is: no log-ins, unsigned scripts are marked &#8220;anonymous&#8221; ... but we track the thumbprints and allow you to browse scripts signed by the same author, etc).</li>
		<li>We can include the signature thumbprint with the short descriptions output on the search results and from the scripts which interact with repository.</li>
		<li>We can restrict &#8220;latest version&#8221; updates to only scripts which are signed, and optionally to new versions signed by the same certificate.</li>
	</ol></li>
		<li>Is there any point (or hope) in trying to get a <em>signed</em> CA certificate? Can Microsoft help us out? Do any of you work at a certificate authority?</li>
	</ol>]]></content:encoded>
			<wfw:commentRss>http://HuddledMasses.org/powershell-authenticode-signatures-and-trust/feed/</wfw:commentRss>
		</item>
		<item>
		<title>SysAdmins, scripters, developers and memes</title>
		<link>http://HuddledMasses.org/sysadmins-scripters-developers-and-memes/</link>
		<comments>http://HuddledMasses.org/sysadmins-scripters-developers-and-memes/#comments</comments>
		<pubDate>Thu, 19 Jun 2008 03:29:15 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
		
		<category><![CDATA[Huddled]]></category>

		<category><![CDATA[AboutMe]]></category>

		<category><![CDATA[Memes]]></category>

		<category><![CDATA[Personal]]></category>

		<category><![CDATA[Profile]]></category>

		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/?p=555</guid>
		<description><![CDATA[So, I&#8217;ve been called out on this latest meme posting by /\/\o\/\/ and although I usually just ignore these things,

	As with any curious developer, I had to trace this thing back to it&#8217;s root cause &#8230; it turns out this started as a Software Development thing, and it was altered into a sort of SysAdmin [...]]]></description>
			<content:encoded><![CDATA[<p>So, I&#8217;ve been <a href="http://thepowershellguy.com/blogs/posh/archive/2008/06/17/scripting-sysadmin-meme.aspx">called out</a> on this latest <a href="http://en.wikipedia.org/wiki/Meme">meme</a> posting by <a href="http://thepowershellguy.com/">/\/\o\/\/</a> and although I usually just ignore these things,</p>

	<p>As with any curious developer, I had to <a href="http://get-powershell.com/">trace</a> <a href="http://scriptolog.blogspot.com/2008/06/scripting-sysadmin-meme.html">this</a> <a href="http://www.mindofroot.com/2008/06/10/scriptingsysadmin-meme/">thing</a> <a href="http://larryclarkin.com/2008/06/10/SoftwareDevelopmentMemeOrTagIAmNext.aspx">back</a> <a href="http://www.joshholmes.com/2008/06/06/SoftwareDevelopmentMeme.aspx">to</a> <a href="http://www.jeffblankenburg.com/2008/06/software-development-meme.html">it&#8217;s</a> <a href="http://www.codinggeekette.com/2008/06/sarahs-steps-into-software-development.aspx">root</a> <a href="http://www.michaeleatonconsulting.com/blog/archive/2008/06/04/how-did-you-get-started-in-software-development.aspx">cause</a> &#8230; it turns out this started as a Software Development thing, and it was altered into a sort of SysAdmin thing.</p>

	<p>So, since I&#8217;m putting up with this in the first place, I think I&#8217;ll go back to that original developer-oriented list of questions, if you don&#8217;t mind. <img src='http://HuddledMasses.org/wordpress/wp-content/plugins/smilingmasses/wink.gif' alt=';-)' class='wp-smiley' /></p>

	<p><span id="more-555"></span></p>

	<h4>How old were you when you started programming?</h4>

	<p>I got my first computer shortly after my family moved back to the <span class="caps">USA</span> from Costa Rica, just in time for 9th grade &#8230; before that I&#8217;d never seen a computer better than my Atari 6400 game machine.</p>

	<h4>How did you get started in programming?</h4>

	<p>I bought that &#8220;computer&#8221; second-hand &#8212; it was an Atari 800XL, and it came with a cartridge for Atari <span class="caps">BASIC</span>, and a stack of magazines with code in them. That&#8217;s pretty much all there is to it, I was hooked.</p>

	<h4>What was your first language?</h4>

	<p><span class="caps">BASIC</span>. First Atari, then QW, then &#8230; well, Visual Basic Script, believe it or not.</p>

	<h4>What was the first real program you wrote?</h4>

	<p>You mean BlackJack for the Atari doesn&#8217;t count?  I guess the first <em>real</em> program I wrote was one I wrote at work to randomize test cases &#8230;</p>

	<h4>What languages have you used since you started programming? </h4>

	<p>Basic, Visual Basic, C/C++, C#, Java, Perl, <span class="caps"><a href="http://www.php.net" class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'PHP: Hypertext Preprocessor' );"><abbr class="uttInitialism">PHP</abbr></a> (PHP: Hypertext Preprocessor)</span>, a bunch of automation languages like batch and shell scripts, <span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Visual Basic' );"><abbr class="uttInitialism">VB</abbr></span> (Visual Basic) script and <span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Visual Basic' );"><abbr class="uttInitialism">VB</abbr></span> for Applications, <span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Sometimes also: Microsoft','caption', 'Masters (degree)' );"><abbr class="uttInitialism">MS</abbr></span> Test Basic, Rational&#8217;s SQABasic, AutoIt, AutoHotkey, ScriptIt, and a slew of web languages like JavaScript, <span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Visual Basic' );"><abbr class="uttInitialism">VB</abbr></span> Script, <span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Link to the spec: (&lt;a href=&quot;http://www.w3.org/MarkUp/&quot;&gt;link&lt;/a&gt;)','caption', 'HyperText Markup Language' );"><abbr class="uttInitialism">HTML</abbr></span></span>, <span class="caps"><a href="http://www.w3.org/XML/" class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'eXtensible Markup Language' );"><abbr class="uttInitialism">XML</abbr></a></span> ... and of course, lets not forget <span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Structured Query Language for databases' );"><abbr class="uttInitialism">SQL</abbr></span></span> (although I kind-of wish I could).</p>

	<h4>What was your first professional programming gig?</h4>

	<p>Not counting a few tiny web-sites I did in college &#8230; my first programming job was at Xerox, where I started out doing software testing, started automating the testing, and then moved to writing and maintaining apps, web sites etc.</p>

	<h4>If you knew then what you know now, would you have started programming?</h4>

	<p>Absolutely.  I love what I do, and I love that I work in a job where every year there&#8217;s new languages, new tools, new challenges, and new and more clever solutions.</p>

	<h4>If there is one thing you learned along the way that you would tell new developers, what would it be? </h4>

	<p>There&#8217;s really only three kinds of programmers: Web developers, Database developers, System developers.  Take a database class and a web-design class early on and figure out what you want to be &#8212; then work hard to make sure you don&#8217;t end up being the wrong kind of programmer <img src='http://HuddledMasses.org/wordpress/wp-content/plugins/smilingmasses/wink.gif' alt=';)' class='wp-smiley' /></p>

	<h4>What&#8217;s the most fun you&#8217;ve ever had &#8230; programming?</h4>

	<p>I think I&#8217;d have to say that the memory that stands out the most was working on the open source project <a href="http://www.geoshell.org"><a href="http://www.geoshell.org/" class="ubernym uttJustLink" onmouseover="domTT_activate(this, event, 'content', 'Geoshell is a Windows shell replacement that takes a minimalist approach','caption', 'GeoShell' );">GeoShell</a></a> &#8230; it&#8217;s mostly died off now (although I&#8217;m still threatening to ressurect it later this year), but at it&#8217;s height it was a near ideal interaction of passionate users, laid back developers, and <em>cool</em> software that made everyone ask: &#8220;whoah, what&#8217;s that you&#8217;re running?&#8221;</p>

	<p>I guess I should call someone else out, right? That&#8217;s how these silly posts become memes. How about <a href="http://www.leeholmes.com/blog/">Lee Holmes</a>, <a href="http://blog.vyvojar.cz/jachymko/">Jachymko</a> and <a href="http://cmschill.net/stringtheory/">Mark Schill</a> &#8230;</p>]]></content:encoded>
			<wfw:commentRss>http://HuddledMasses.org/sysadmins-scripters-developers-and-memes/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Code Signing with OpenSSL and PowerShell</title>
		<link>http://HuddledMasses.org/code-signing-with-openssl-and-powershell/</link>
		<comments>http://HuddledMasses.org/code-signing-with-openssl-and-powershell/#comments</comments>
		<pubDate>Tue, 17 Jun 2008 04:17:17 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
		
		<category><![CDATA[Huddled]]></category>

		<category><![CDATA[Certificates]]></category>

		<category><![CDATA[CodeSigning]]></category>

		<category><![CDATA[OpenSSL]]></category>

		<category><![CDATA[PowerShell]]></category>

		<category><![CDATA[Scripting]]></category>

		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/?p=551</guid>
		<description><![CDATA[One of the major security features of PowerShell is the support for code signing of scripts, so that you can set an execution policy that requires scripts to be signed before they can be run. Of course, it goes a bit further than that. When a script has been signed by a certificate with a [...]]]></description>
			<content:encoded><![CDATA[<p>One of the major security features of PowerShell is the support for code signing of scripts, so that you can set an execution policy that requires scripts to be signed before they can be run. Of course, it goes a bit further than that. When a script has been signed by a certificate with a root Certificate Authority (CA) that you don&#8217;t already &#8220;know&#8221; or trust it can&#8217;t be run at all until you add the root CA to the system&#8217;s certificate store.</p>

	<p>Even after you trust a specific authority, you haven&#8217;t trusted a script author &#8212; so any signed script you run will prompt you whether you want to allow it or not, like so:</p>

<div class="code posh" style="background: black; color: #ccc; font-weight:bold; line-height:0.5em;">
<span style="color:#ffcc00;">[19]:</span> .\test-script.ps1<br />
<br />

<span style="color:#fff;">Do you want to run software from this untrusted publisher?</span><br />

File C:\Users\Joel\Documents\WindowsPowerShell\test-script.ps1 is published by<br />

E=NoUser@HuddledMasses.org, O=Huddled Masses, L=Rochester, S=New York, C=US<br />

and is not trusted on your system. Only run scripts from trusted publishers.<br />

<span style="color:#fff;">[V] Never run  </span><span style="color:#ffcc00;">[D] Do not run</span><span style="color:#fff;">  [R] Run once  [A] Always run  [?] Help (default is &#8220;D&#8221;):</span><br />

</div>

	<p>The important thing to note here is that you&#8217;re really being asked not about the script, but about the author.  If you choose the <b>Ne<u>v</u>er<b> or <b><u>A</u>lways</b> options, the certificate that was used to sign the script is added to the appropriate certificate store (&#8220;Untrusted Certificates&#8221; or &#8220;Trusted Publishers&#8221;, respectively).  To be clear: this happens for each every new author certificate, regardless of whether it&#8217;s signed by a self-signed cert (where you&#8217;ve already installed the root certificate in your root store) or a certificate issued by a commercial CA &#8212; there&#8217;s no loophole, no matter what anyone may have said <a href="http://blogs.technet.com/industry_insiders/pages/software-restriction-policies-and-powershell-code-signing.aspx">in the past</a>.  </p>

	<p>So, you see &#8230; the support for code signing is built into the core of PowerShell &#8212; and it&#8217;s really a shame not to <a href="http://technetmagazine.com/issues/2008/01/PowerShell">take advantage of it</a>.  There are plenty of articles out there about <a href="http://technet.microsoft.com/en-us/magazine/cc434702.aspx">how to sign your scripts</a>, and more, so I&#8217;m not going to get into that much &#8212; I want to address the question of how hard it is to create the certificates in the first place (and finish by giving you a sample script which will generate and import them to your dev box with a single line command).</p>

	<p><span id="more-551"></span></p>

	<h3>Generating Code Signing Certificates with OpenSSL</h3>

	<p>I&#8217;ve been talking up automatic code-signing for awhile now &#8212; basically, I think that any script editor that pretends to be a PowerShell script editor should be able to sign scripts at the push of a button, even every time you save the file.  On top of that, I think that (like Microsoft&#8217;s <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=fad62198-220c-4717-b044-829ae4f7c125&#38;displaylang=en">Speech Macros</a> app) they should be able to generate a self-signed code-signing script for you.</p>

	<p>Someone emailed me the other day to ask how I proposed to do this, since <a href="http://msdn.microsoft.com/en-us/library/aa386968(VS.85">MakeCert</a>).aspx isn&#8217;t redistributable, and can&#8217;t be counted on to be installed&#8230; Well, as an answer I wrote a script which I&#8217;ll share here, using the open source <a href="http://www.openssl.org/">OpenSSL</a> <a href="http://www.slproweb.com/products/Win32OpenSSL.html">for Windows</a> to generate the certificates.  It&#8217;s a bit more complicated than using MakeCert, but still not a huge thing. Basically, it&#8217;s six lines of code &#8212; each calling the OpenSSL executable.</p>

	<div class="code posh" style="font-family: monospace;"><br />
<span style="color: #666666; font-style: italic;"># Generate the private root CA key and convert it into a self-signed certificate (crt)</span><br />
OpenSsl genrsa <span style="color: #000066;">-out</span> <span style="color: #009900;">&quot;CA.key&quot;</span> <span style="color: #000066;">-des3</span> <span style="color: #cc66cc;">4096</span><br />
OpenSsl req <span style="color: #000066;">-new</span> <span style="color: #000066;">-x509</span> <span style="color: #000066;">-days</span> <span style="color: #cc66cc;">3650</span> <span style="color: #000066;">-key</span> <span style="color: #009900;">&quot;CA.key&quot;</span> <span style="color: #000066;">-out</span> <span style="color: #009900;">&quot;CA.crt&quot;</span><br />
<span style="color: #666666; font-style: italic;"># Generate the private code-signing key and a certificate signing request (csr)</span><br />
OpenSsl genrsa <span style="color: #000066;">-out</span> <span style="color: #009900;">&quot;signing.key&quot;</span> <span style="color: #000066;">-des3</span> <span style="color: #cc66cc;">4096</span><br />
OpenSsl req <span style="color: #000066;">-new</span> <span style="color: #000066;">-key</span> <span style="color: #009900;">&quot;signing.key&quot;</span> <span style="color: #000066;">-out</span> <span style="color: #009900;">&quot;signing.csr&quot;</span><br />
<span style="color: #666666; font-style: italic;"># Use the root CA key to process the CSR and sign the code-signing key in one step...</span><br />
OpenSsl x509 <span style="color: #000066;">-req</span> <span style="color: #000066;">-days</span> <span style="color: #cc66cc;">365</span> <span style="color: #000066;">-in</span> <span style="color: #009900;">&quot;signing.csr&quot;</span> <span style="color: #000066;">-CA</span> <span style="color: #009900;">&quot;CA.crt&quot;</span> <span style="color: #000066;">-CAcreateserial</span> <span style="color: #000066;">-CAkey</span> <span style="color: #009900;">&quot;CA.key&quot;</span> <span style="color: #000066;">-out</span> <span style="color: #009900;">&quot;signing.crt&quot;</span><br />
<span style="color: #666666; font-style: italic;"># Combine the signed certificate and the private key into a single file </span><br />
OpenSsl pkcs12 <span style="color: #000066;">-export</span> <span style="color: #000066;">-out</span> <span style="color: #009900;">&quot;signing.pfx&quot;</span> <span style="color: #000066;">-inkey</span> <span style="color: #009900;">&quot;signing.key&quot;</span> <span style="color: #000066;">-in</span> <span style="color: #009900;">&quot;signing.crt&quot;</span><br />
&nbsp;</div>

	<p>There are two problems: first, half of those lines actually cause interactive prompts: asking you for your country and state, and email address, various passwords, etc.  On top of that, the default OpenSSL.cnf file distributed with Windows doesn&#8217;t really give you a way to create certificates that can code sign, so if you went through all of those steps &#8212; you <em>still</em> wouldn&#8217;t be able to sign scripts <img src='http://HuddledMasses.org/wordpress/wp-content/plugins/smilingmasses/wink.gif' alt=';-)' class='wp-smiley' /></p>

	<p>My solution to both problems is pretty straight-forward: customize the config file and run the <code>req</code> requests in <code>-batch</code> mode.  Normally that would mean creating a custom OpenSSL.cnf config file with the specific values necessary &#8212; but in this case, I&#8217;ve made a PowerShell script to do it.</p>

	<p><code>New-CodeSigningCert.ps1</code> can generate both the CA certificate and the code-signing certificate, and you can set it up to prompt you as little as possible, however, the point of this isn&#8217;t really to provide a <em>solution</em>, but to provide an <em>example</em> for the developers of editors and IDEs &#8212; so it&#8217;s still a bit rough, and it doesn&#8217;t try to guess your user name, email, and organization information from the environment.</p>

	<h3>Importing Certificates</h3>

	<p>Importing certificates into the Windows Certificate Store can be done with the graphical &#8220;CertMgr.msc&#8221;, but also with any of several command-line tools including <a href="http://msdn.microsoft.com/en-us/library/aa384088.aspx">WinHttpCertCfg.exe</a> from the Windows Server Resource Kit, and <a href="http://msdn.microsoft.com/en-us/library/aa376553.aspx">CertMgr.exe</a> from the Windows <span class="caps">SDK</span>... which of course, aren&#8217;t redistributable. Someone really needs to tell Microsoft to get on the ball with this stuff.</p>

	<p>However, the <a href="http://msdn.microsoft.com/en-us/library/aa388127.aspx"><span class="caps">CAPICOM</span>.Store</a> <span class="caps">COM</span> object is basically available everywhere now, and <a href="http://go.microsoft.com/fwlink/?linkid=84567">is redistributable</a> &#8230; so we can use that.  It&#8217;s really very simple.  The most basic step is to just import the new <code>CA.crt</code> certificate into the Root Store.</p>

	<div class="code posh" style="font-family: monospace;"><br />
<span style="color: #660033; font-weight: bold;">$Store</span> = <span style="color: #0066cc; font-style: italic;">new-<span style="font-style: normal;">object</span></span> <span style="color: #000066;">-COM</span> CAPICOM.<span style="color: #003366;">Store</span><br />
<span style="color: #666666; font-style: italic;"># Open the LocalMachine Root store in ReadWrite mode</span><br />
<span style="color: #660033; font-weight: bold;">$Store</span>.<span style="color: #003366;">Open</span><span style="color: #333;">&#40;</span> <span style="color: #cc66cc;">1</span>, <span style="color: #009900;">&quot;Root&quot;</span>, <span style="color: #cc66cc;">129</span> <span style="color: #333;">&#41;</span><br />
<span style="color: #666666; font-style: italic;"># Import the crt file</span><br />
<span style="color: #660033; font-weight: bold;">$Store</span>.<span style="color: #003366;">Load</span><span style="color: #333;">&#40;</span> <span style="color: #009900;">&quot;$pwd\CA.crt&quot;</span>, <span style="color: #660033; font-weight: bold;">$Null</span>, <span style="color: #cc66cc;">0</span><span style="color: #333;">&#41;</span><br />
&nbsp;</div>

	<p>After that, you can sign PowerShell scripts using the <code>Get-PfxCertificate</code> cmdlet on the pfx file we generated earlier&#8230;</p>

	<div class="code posh" style="font-family: monospace;"><br />
<span style="color: #660033; font-weight: bold;">$cert</span> = <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">PfxCertificate</span></span> <span style="color: #009900;">&quot;signing.pfx&quot;</span><br />
<span style="color: #0066cc; font-style: italic;">Set-<span style="font-style: normal;">AuthenticodeSignature</span></span> <span style="color: #000066;">-Cert</span> <span style="color: #660033; font-weight: bold;">$cert</span> <span style="color: #000066;">-File</span> <span style="color: #0066cc; font-style: italic;">Test-<span style="font-style: normal;">Script</span></span>.<span style="color: #003366;">ps1</span><br />
<br />
&nbsp;</div>

	<p>Of course, you could also use the <span class="caps">CAPICOM</span>.Store method to import the pfx certificate into the CurrentUser&#8217;s &#8220;My&#8221; store.  In either case, if you try to execute a signed script, you can choose <strong>always</strong> from the prompt and the certificate will be imported to the current user&#8217;s &#8220;trusted publisher&#8221; store. Alternatively, you could import the certificate to the local machine&#8217;s &#8220;trusted publisher&#8221; store using the <span class="caps">CAPICOM</span>.Store again and now you won&#8217;t receive a prompt at all.</p>

	<h3>Using New-CodeSigningCert</h3>

	<p>I&#8217;ve attached the <a href="http://HuddledMasses.org/?attachment_id=552">New-CodeSigningCert</a> script, which includes all the features mentioned so far.  It&#8217;s about 111 lines of code, and 41 lines of the config file, plus 69 and 56 lines of comments in each &#8230; all wrapped up into a single file you can hopefully figure it out, learn it, and modify as you see fit.  </p>

	<p>I&#8217;ve also attached the script packaged with the OpenSSL (<a href="http://HuddledMasses.org/?attachment_id=554">zip</a>, <a href="http://HuddledMasses.org/?attachment_id=553">7z</a>), so you can just unpack the archive and run the script to start generating certificates.  The script needs to be stored in the same folder with OpenSSL.exe anyway, so if you don&#8217;t already have it installed, this might be the easiest way for now.</p>

	<p>Once you&#8217;ve got it installed, and have customized the default parameters in the script, you should be able to easily generate scripts for multiple developers, and/or import those certificates to thousands of computers using PowerShell Remoting <img src='http://HuddledMasses.org/wordpress/wp-content/plugins/smilingmasses/wink.gif' alt=';)' class='wp-smiley' /></p>

	<div class="code posh" style="font-family: monospace;"><br />
<span style="color: #666666; font-style: italic;">## Because I have hard-coded the company information</span><br />
<span style="color: #666666; font-style: italic;">## I can use this to generate certs for all my devs (using the same CA root)</span><br />
<span style="color: #660033; font-weight: bold;">$CertsFolder</span> = <span style="color: #009900;">&quot;\Server\PoshCerts\CodeSigningCerts&quot;</span><br />
<br />
\Server\PoshCerts\<span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">CodeSigningCert</span></span>.<span style="color: #003366;">ps1</span> <span style="color: #660033; font-weight: bold;">$CertsFolder</span> <span style="color: #009900;">&quot;FirstName Last&quot;</span> User1@Domain.<span style="color: #003366;">com</span> <span style="color: #000066;">-CAPassword</span> MyCleverRootPassword <span style="color: #000066;">-CodeSignPassword</span> SimplePassword<br />
\Server\PoshCerts\<span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">CodeSigningCert</span></span>.<span style="color: #003366;">ps1</span> <span style="color: #660033; font-weight: bold;">$CertsFolder</span> <span style="color: #009900;">&quot;First LastName&quot;</span> User2@Domain.<span style="color: #003366;">com</span> <span style="color: #000066;">-CAPassword</span> MyCleverRootPassword <span style="color: #000066;">-CodeSignPassword</span> AnotherPassword<br />
\Server\PoshCerts\<span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">CodeSigningCert</span></span>.<span style="color: #003366;">ps1</span> <span style="color: #660033; font-weight: bold;">$CertsFolder</span> <span style="color: #009900;">&quot;User LastName&quot;</span> User3@Domain.<span style="color: #003366;">com</span> <span style="color: #000066;">-CAPassword</span> MyCleverRootPassword <span style="color: #000066;">-CodeSignPassword</span> LastPassword<br />
<br />
<span style="color: #666666; font-style: italic;">## And then I can import the scripts on end-user PCs:</span><br />
<span style="color: #009900;">&quot;FirstName Last&quot;</span>,<span style="color: #009900;">&quot;First LastName&quot;</span>,<span style="color: #009900;">&quot;User LastName&quot;</span> | <span style="color: #666699; font-weight: bold;">%</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp;\Server\PoshCerts\<span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">CodeSigningCert</span></span>.<span style="color: #003366;">ps1</span> <span style="color: #660033; font-weight: bold;">$CertsFolder</span> <span style="color: #000066;">-import</span> <br />
<span style="color: #333;">&#125;</span><br />
&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://HuddledMasses.org/code-signing-with-openssl-and-powershell/feed/</wfw:commentRss>
		</item>
		<item>
		<title>RSS Feed for PowerShell Script Repository</title>
		<link>http://HuddledMasses.org/rss-feed-for-powershell-script-repository/</link>
		<comments>http://HuddledMasses.org/rss-feed-for-powershell-script-repository/#comments</comments>
		<pubDate>Wed, 04 Jun 2008 04:31:52 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
		
		<category><![CDATA[Huddled]]></category>

		<category><![CDATA[Feed]]></category>

		<category><![CDATA[Pastebin]]></category>

		<category><![CDATA[PowerShell]]></category>

		<category><![CDATA[Recent]]></category>

		<category><![CDATA[Repository]]></category>

		<category><![CDATA[RSS]]></category>

		<category><![CDATA[Scripting]]></category>

		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/?p=549</guid>
		<description><![CDATA[There are two requests that I get with overwhelming regularity for the PowerShell script repository: first, that I would add some sort of &#8220;browsing&#8221; functionality, and second, that it should have an RSS (Really Simple Syndication) feed. Well, browsing may have to wait until a future iteration of the repository, but feeds are easy, because [...]]]></description>
			<content:encoded><![CDATA[<p>There are two requests that I get with overwhelming regularity for the PowerShell script repository: first, that I would add some sort of &#8220;browsing&#8221; functionality, and second, that it should have an <span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Really Simple Syndication' );"><abbr class="uttInitialism">RSS</abbr></span> (Really Simple Syndication)</span> feed. Well, browsing may have to wait until a future iteration of the repository, but feeds are easy, because they&#8217;re basically just a hack-up of the &#8220;recent&#8221; items that are in the repository sidebar already, so I did it this evening.</p>

	<h2>Presenting &#8230;</h2>

	<p><a href="http://PowerShellCentral.com/scripts/feed">PowerShellCentral.com/scripts/feed</a></p>

	<p>Right now the number of items is limited to <em>about</em> ten, but if traffic picks up I can increase that easily &#8212; you can limit the count by passing the number of items you want to list like this: <a href="http://powershellcentral.com/scripts/feed.php?list=2">?list=2</a>.</p>

	<p>You can also create a feed for specific search results (the feed will show items in relevance order, but the date is in the <span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Really Simple Syndication' );"><abbr class="uttInitialism">RSS</abbr></span></span> so if you want to sort by that, you can).  For instance, if you wanted to keep up to date on scripts that used SecureStrings, you would append your search terms like this: <a href="http://powershellcentral.com/scripts/feed?q=*securestring*">?q=*securestring*</a>.  <img src='http://HuddledMasses.org/wordpress/wp-content/plugins/smilingmasses/smile.gif' alt=':)' class='wp-smiley' /></p>

	<p>As usual, my modifications to the PasteBin.com site are available <a href="http://PowerShellCentral.com/scripts/pastebin.7z">on the repository site</a>, and without much in the way of documentation.  I will say this: in addition to creating the feed.php file, I moved some of the common translation functions into a <em>translate.php</em> file, and modified the dates that were being returned from <em>db.mysql.class.php</em> &#8212; it&#8217;s all under the <a href="http://www.affero.org/oagpl.html">Affero General Public License</a> that <a href="http://blog.dixo.net/category/pastebin/">Paul Dixon</a> wrote <a href="http://PasteBin.com">PasteBin</a> under in the first place.</p>]]></content:encoded>
			<wfw:commentRss>http://HuddledMasses.org/rss-feed-for-powershell-script-repository/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Automating the PowerShell Script Repository</title>
		<link>http://HuddledMasses.org/automating-the-powershell-script-repository/</link>
		<comments>http://HuddledMasses.org/automating-the-powershell-script-repository/#comments</comments>
		<pubDate>Fri, 30 May 2008 04:16:39 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
		
		<category><![CDATA[Huddled]]></category>

		<category><![CDATA[CPAN]]></category>

		<category><![CDATA[Download]]></category>

		<category><![CDATA[PowerShell]]></category>

		<category><![CDATA[Repository]]></category>

		<category><![CDATA[Scripting]]></category>

		<category><![CDATA[Scripts]]></category>

		<category><![CDATA[wGet]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/?p=547</guid>
		<description><![CDATA[So, people keep talking about a better PowerShell script repository, and there&#8217;s at least 3 or 4 different people working on improvements, but for now, the one we have is working ok, and already has hundreds of scripts in it &#8212; but there hasn&#8217;t been a way to add or retrieve scripts from within PowerShell.

	So [...]]]></description>
			<content:encoded><![CDATA[<p>So, people keep talking about a better PowerShell script repository, and there&#8217;s at least 3 or 4 different people working on improvements, but for now, the one we have is working ok, and already has hundreds of scripts in it &#8212; but there hasn&#8217;t been a way to add or retrieve scripts from within PowerShell.</p>

	<p>So while I was taking a break from working on my own replacement script repository <img src='http://HuddledMasses.org/wordpress/wp-content/plugins/smilingmasses/wink.gif' alt=';)' class='wp-smiley' /> I whipped up some scripts to <code>Send-Paste</code>, <code>Get-Paste</code> and <code>Find-Paste</code>.  These scripts still need some work, but I think you&#8217;ll find them useful, so I&#8217;ve posted a version that is compatible with PowerShell v1 (and works fine on the 2.0 <span class="caps">CTP</span>) and doesn&#8217;t need any additional scripts (it <em>includes</em> the latest <a href="http://powershellcentral.com/scripts/417">Get-WebFile</a> script for downloading the files).</p>

	<p>The <code>Find-Paste</code> function takes a search string, and adds wildcards &#8212; but otherwise performs the same search as you can already do on the web page. It returns the results in a PowerShell friendly PSObject which by default is just displayed in the host.  </p>

	<p>In order to download a script using <code>Get-Paste</code>, you must know the ID of the script &#8212; which you can get from the output of Find-Paste.  Note that because Find-Paste does a full-text search, you may get results that are not the script you&#8217;re looking for (if they call that script, for instance), and you may get many versions of the script (and newer versions are not necessarily at the top of the search results).</p>

	<p>The <code>Send-Paste</code> script is most useful for sending things to the <a href="http://posh.Jaykul.com/p/">temporary PowerShell pastebin on my site</a> but can be used successfully to send scripts to the permanent <a href="http://PowerShellCentral.com/scripts/">PowerShell Script Repository</a> &#8230; in fact, that&#8217;s how I uploaded the <a href='http://HuddledMasses.org/automating-the-powershell-script-repository/pastebin/' rel='attachment wp-att-550'>PowerShell Pastebin Functions</a> <a href="http://powershellcentral.com/scripts/421">to the repository</a> &#8230; you just have to be careful to specify the title and description when you do that. <strong>Edit</strong>: I attached the script <a href="http://huddledmasses.org/wordpress/wp-content/uploads/2008/06/pastebin.ps1">here on my site</a> also because I made a mistake and deleted the original copy from the repository. <img src='http://HuddledMasses.org/wordpress/wp-content/plugins/smilingmasses/new.gif' alt='[new]' class='wp-smiley' /></p>

	<p>So, you now have something a little bit more like a proper script repository.  Hopefully the <em>Usage</em> comments in the script will be enough to help you figure out how to use the various commands, (and I did blog about the <a href="http://huddledmasses.org/powershell-send-paste-script/">Send-Paste</a> script about a month ago) but just in case you need help, let me give you a simple example.</p>

	<p>Suppose I need to find a script to encrypt text so I can store some SecureString objects (like the passwords in a PSCredential object) in a file&#8230;</p>

	<div class="code posh" style="font-family: monospace;"><br />
<span style="color: #333;">&#91;</span><span style="color: #cc66cc;">100</span><span style="color: #333;">&#93;</span>: Find-Paste encrypt<br />
<br />
Id&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : <span style="color: #cc66cc;">116</span><br />
Title&nbsp; &nbsp; &nbsp; &nbsp;: <span style="color: #0066cc; font-style: italic;">Start-<span style="font-style: normal;">Encryption</span></span><br />
Description : Functions to encrypt <span style="color: #333399; font-weight: bold; font-style: italic;">and</span> decrypt strings using the Rijndael symmetric key algorithm<br />
Author&nbsp; &nbsp; &nbsp; : Joel Bennett<br />
Date&nbsp; &nbsp; &nbsp; &nbsp; : <span style="color: #cc66cc;">133</span> days ago<br />
Link&nbsp; &nbsp; &nbsp; &nbsp; : http://powershellcentral.<span style="color: #003366;">com</span>/scripts/<span style="color: #cc66cc;">116</span><br />
<br />
Id&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : <span style="color: #cc66cc;">416</span><br />
Title&nbsp; &nbsp; &nbsp; &nbsp;: Pastebin Functions<br />
Description : <span style="color: #0066cc; font-style: italic;">Send-<span style="font-style: normal;">Paste</span></span>, <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Paste</span></span>, <span style="color: #333399; font-weight: bold; font-style: italic;">and</span> Find-Paste ... <span style="color: #003366;">to</span> let you use PowerShellCentral.<span style="color: #003366;">com</span>/Scripts a little bit <span style="color: #660033;">more</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #333399; font-weight: bold; font-style: italic;">like</span> CPAN <span style="color: #666699; font-weight: bold;">while</span> you wait <span style="color: #666699; font-weight: bold;">for</span> us to get our act together <span style="color: #333399; font-weight: bold; font-style: italic;">and</span> give you something better. :<span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IMPORTANT NOTE: the <span style="color: #0066cc; font-style: italic;">Send-<span style="font-style: normal;">Paste</span></span> script defaults to our *temporary* pastebin site because we <span style="color: #666699; font-weight: bold;">do</span> <span style="color: #333399; font-weight: bold; font-style: italic;">not</span> want <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; you to fill up the central pastebin site with snippets ... <span style="color: #003366;">but</span> the other two <span style="color: #666699; font-weight: bold;">default</span> to the main long-term <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; script repository.<br />
<span style="color: #003366;">Author</span>&nbsp; &nbsp; &nbsp; : Joel Bennett<br />
Date&nbsp; &nbsp; &nbsp; &nbsp; : <span style="color: #cc66cc;">1</span> hour ago<br />
Link&nbsp; &nbsp; &nbsp; &nbsp; : http://powershellcentral.<span style="color: #003366;">com</span>/scripts/<span style="color: #cc66cc;">416</span><br />
&nbsp;</div>

	<p>It looks like I found two, but clearly the second one is not the right one (I mentioned this in one of my examples in the pastebin scripts, and amusingly enough, that screwed up my example). So to download the script I want, I just do:</p>

	<div class="code posh" style="font-family: monospace;"><br />
<span style="color: #333;">&#91;</span><span style="color: #cc66cc;">101</span><span style="color: #333;">&#93;</span>: <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Paste</span></span> <span style="color: #cc66cc;">116</span> <span style="color: #0066cc; font-style: italic;">Start-<span style="font-style: normal;">Encryption</span></span>.<span style="color: #003366;">ps1</span><br />
<br />
&nbsp; &nbsp; Directory: <span style="color: #003366; font-weight: bold;">Microsoft</span>.<span style="color: #003366;">PowerShell</span>.<span style="color: #003366;">Core</span>\FileSystem::<span style="color: #003366;">C</span>:\Users\Joel\Documents\WindowsPowerShell\Scripts<br />
<br />
Mode&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LastWriteTime&nbsp; &nbsp; &nbsp; &nbsp;Length Name<br />
----&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-------------&nbsp; &nbsp; &nbsp; &nbsp;------ ----<br />
-a---&nbsp; &nbsp; &nbsp;<span style="color: #cc66cc;">5</span>/<span style="color: #cc66cc;">30</span>/<span style="color: #cc66cc;">2008</span> <span style="color: #cc66cc;">12</span>:<span style="color: #cc66cc;">23</span> AM&nbsp; &nbsp; &nbsp;<span style="color: #cc66cc;">2.378</span> KB <span style="color: #0066cc; font-style: italic;">Start-<span style="font-style: normal;">Encryption</span></span>.<span style="color: #003366;">ps1</span><br />
&nbsp;</div>

	<p>Simple enough, right? I could have used the -Passthru option to <em>see</em> the script in the console, but since I was pretty sure it was the only one that might be useful (and since using -Passthrough just to display it on the console would mean downloading it a second time, if I actually wanted it).  Another option would be to use the Tee-Object cmdlet, which would let us download it, show it in the host, and also save it in the file, all at once! <img src='http://HuddledMasses.org/wordpress/wp-content/plugins/smilingmasses/smile.gif' alt=':)' class='wp-smiley' /></p>

	<div class="code posh" style="font-family: monospace;"><br />
<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Paste</span></span> <span style="color: #cc66cc;">116</span> <span style="color: #000066;">-Passthru</span> | tee <span style="color: #000066;">-file</span> <span style="color: #0066cc; font-style: italic;">Start-<span style="font-style: normal;">Encryption</span></span>.<span style="color: #003366;">ps1</span><br />
&nbsp;</div>

	<p>Incidentally, I have a version of this which uses my <a href="http://huddledmasses.org/get-web-another-round-of-wget-for-powershell/">PoshHttp snapin and Get-Web cmdlet</a>, but it&#8217;s also written as a module and therefore requires PowerShell 2.0 CTP2 &#8212; for various reasons, I&#8217;m choosing to release that one separately later.  If you <strong>are</strong> using the <span class="caps">CTP</span>, you could take advantage of the <span class="caps">WPF</span> UI abilities and try piping <code>Find-Script ... | &#34;Select-Grid&#34;:http://huddledmasses.org/wpf-from-powershell-select-grid/ | Get-Script</code> to pick the script you want visually. <img src='http://HuddledMasses.org/wordpress/wp-content/plugins/smilingmasses/bigsmile.gif' alt=':-D' class='wp-smiley' /></p>]]></content:encoded>
			<wfw:commentRss>http://HuddledMasses.org/automating-the-powershell-script-repository/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ideas for Writing Composable PowerShell scripts</title>
		<link>http://HuddledMasses.org/ideas-for-writing-composable-powershell-scripts/</link>
		<comments>http://HuddledMasses.org/ideas-for-writing-composable-powershell-scripts/#comments</comments>
		<pubDate>Wed, 28 May 2008 13:33:07 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
		
		<category><![CDATA[Huddled]]></category>

		<category><![CDATA[Pipeline]]></category>

		<category><![CDATA[PowerShell]]></category>

		<category><![CDATA[PowerTips]]></category>

		<category><![CDATA[Scripting]]></category>

		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/ideas-for-writing-composable-powershell-scripts/</guid>
		<description><![CDATA[I was just having some fun with some recent blog posts&#8230;

	WPF &#38; PowerShell &#8211; Part 5 has a script for &#8220;Get-Listbox&#8221; and for &#8220;Show-Control&#8221; and Halr9000 wrote a script he called Get-PSBlogroll 

	I had modified the example from the WPF post to create a listbox which will &#8220;start&#8221; whatever you double click &#8230;

	
Get-Listbox Title &#124; [...]]]></description>
			<content:encoded><![CDATA[<p>I was just having some fun with some recent blog posts&#8230;</p>

	<p><a href="http://blogs.msdn.com/powershell/archive/2008/05/26/wpf-powershell-part-5-using-wpf-powershell-modules.aspx"><span class="caps">WPF</span> &amp; PowerShell &#8211; Part 5</a> has a script for &#8220;Get-Listbox&#8221; and for &#8220;Show-Control&#8221; and Halr9000 wrote a script he called <a href="http://halr9000.com/article/487">Get-PSBlogroll</a> </p>

	<p>I had modified the example from the <span class="caps">WPF</span> post to create a listbox which will &#8220;start&#8221; whatever you double click &#8230;</p>

	<div class="code posh" style="font-family: monospace;"><br />
<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Listbox</span></span> Title | Show-Control @<span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&quot;MouseDoubleClick&quot;</span> = <span style="color: #333;">&#123;</span> <span style="color: #333;">&#91;</span>Diagnostics.<span style="color: #666699; font-weight: bold;">Process</span><span style="color: #333;">&#93;</span>::<span style="color: #003366;">Start</span><span style="color: #333;">&#40;</span> <span style="color: #660033; font-weight: bold;">$window</span>.<span style="color: #003366;">Content</span>.<span style="color: #003366;">SelectedItem</span> <span style="color: #333;">&#41;</span> <span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>And I tried something like this to let me launch links from hal9000&#8217;s blogroll:</p>

	<div class="code posh" style="font-family: monospace;"><br />
<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">PsBlogRoll</span></span> | <span style="color: #666699; font-weight: bold;">%</span> <span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">HtmlUrl</span> <span style="color: #333;">&#125;</span> | <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Listbox</span></span> | Show-Control @<span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&quot;MouseDoubleClick&quot;</span> = <span style="color: #333;">&#123;</span> <span style="color: #333;">&#91;</span>Diagnostics.<span style="color: #666699; font-weight: bold;">Process</span><span style="color: #333;">&#93;</span>::<span style="color: #003366;">Start</span><span style="color: #333;">&#40;</span> <span style="color: #660033; font-weight: bold;">$window</span>.<span style="color: #003366;">Content</span>.<span style="color: #003366;">SelectedItem</span> <span style="color: #333;">&#41;</span> <span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>Of course, what I&#8217;d like is to <em>see</em> the titles, instead of the <span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Uniform Resource Locator' );"><abbr class="uttInitialism">URL</abbr></span></span>, but because of how Get-ListBox was written, it only accepts strings, and therefore only returns strings.  I tried adding the <span class="caps"><span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Uniform Resource Locator' );"><abbr class="uttInitialism">URL</abbr></span></span> as a NoteProperty on the title string, but there&#8217;s <a href="https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=345387&#38;amp;SiteID=99">a bug</a> in the script cmdlet implementation that strips <acronym title="Extended Type System">ETS</acronym> properties. So if you specify your parameter type as a [string], you loose the NoteProperty.</p>

	<h2>Idea 1: Use [PsObject] for your pipeline parameter</h2>

	<p>Of course, if they <a href="https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=345387&#38;amp;SiteID=99">fix the bug</a> this tip will go away, but in the meantime, you&#8217;re better off not casting the input from the PowerShell native <code>[PsObject]</code> type, because you loose any extended type system attributes (and if you cast <span class="caps"><a href="http://www.w3.org/XML/" class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'eXtensible Markup Language' );"><abbr class="uttInitialism">XML</abbr></a></span> to a string, it comes out yucky).</p>

	<h2>Idea 2: Don&#8217;t output <a href="http://www.w3.org/XML/" class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'eXtensible Markup Language' );"><abbr class="uttInitialism">xml</abbr></a> nodes</h2>

	<p>Even after fixing the Get-Listbox script so it outputs what it gets in without casting it, I still have to craft PsObjects with the output from Halr9000&#8217;s script, because otherwise Get-ListBox just outputs the <code>.ToString()</code> representation of the <a href="http://www.w3.org/XML/" class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'eXtensible Markup Language' );"><abbr class="uttInitialism">xml</abbr></a> node, which is invariably useless &#8212; I could data-bind to the <a href="http://www.w3.org/XML/" class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'eXtensible Markup Language' );"><abbr class="uttInitialism">xml</abbr></a> attributes, but it requires a separate syntax in the <span class="caps">XAML</span> &#8212; which means you&#8217;d have to have separate code for <a href="http://www.w3.org/XML/" class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'eXtensible Markup Language' );"><abbr class="uttInitialism">xml</abbr></a> vs objects.  So basically, you&#8217;re better off with a <code> | Select *</code> at the end of your Get-PsBlogRoll.</p>

	<h2>Idea 3: Display scripts should take a property (or a property list)...</h2>

	<p>What I eventually ended up doing is rewriting Get-Listbox to take a &#8220;Properties&#8221; parameter so that I could specify which of the attributes of an object I wanted to use &#8230; that way, I can pass in the almost unmodified output from Get-PSBlogRoll into the new Get-ListBox, and run with it.  In the end, it looks something like this:</p>

	<div class="code posh" style="font-family: monospace;"><br />
cmdlet <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Listbox</span></span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">param</span><span style="color: #333;">&#40;</span>&nbsp; &nbsp;<br />
&nbsp; &nbsp; <span style="color: #333;">&#91;</span>Parameter<span style="color: #333;">&#40;</span>ValueFromPipeline=<span style="color: #660033; font-weight: bold;">$true</span>, Mandatory=<span style="color: #660033; font-weight: bold;">$true</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><span style="color: #660033; font-weight: bold;">$Input</span>,<br />
&nbsp; &nbsp; <span style="color: #333;">&#91;</span>Parameter<span style="color: #333;">&#40;</span>Position=<span style="color: #cc66cc;">0</span>,Mandatory=<span style="color: #660033; font-weight: bold;">$false</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">string</span><span style="color: #333;">&#91;</span><span style="color: #333;">&#93;</span><span style="color: #333;">&#93;</span><span style="color: #660033; font-weight: bold;">$Properties</span><br />
&nbsp; &nbsp; <span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">Begin</span><span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$listItems</span> = @<span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">Process</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span> <span style="color: #660033; font-weight: bold;">$input</span> <span style="color: #000066;">-is</span> <span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">type</span><span style="color: #333;">&#93;</span> <span style="color: #000066;">-and</span> <span style="color: #660033; font-weight: bold;">$input</span>.<span style="color: #003366;">IsEnum</span> <span style="color: #333;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$listItems</span>+= <span style="color: #333;">&#91;</span>Enum<span style="color: #333;">&#93;</span>::<span style="color: #003366;">GetValues</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$input</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">elseif</span><span style="color: #333;">&#40;</span> <span style="color: #660033; font-weight: bold;">$input</span>.<span style="color: #003366;">GetType</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span>.<span style="color: #003366;">IsEnum</span> <span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$listItems</span>+= <span style="color: #333;">&#91;</span>Enum<span style="color: #333;">&#93;</span>::<span style="color: #003366;">GetValues</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$input</span>.<span style="color: #003366;">GetType</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">else</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$listItems</span> += <span style="color: #660033; font-weight: bold;">$input</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">End</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$listbox</span> = <span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Object</span></span> <span style="color: #003366; font-weight: bold;">System</span>.<span style="color: #003366;">Windows</span>.<span style="color: #003366;">Controls</span>.<span style="color: #003366;">Listbox</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$listBox</span>.<span style="color: #003366;">ItemsSource</span> = <span style="color: #660033; font-weight: bold;">$listItems</span> <span style="color: #666666; font-style: italic;"># | Select -unique</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># An optional DataTemplate, if they specified which properties they want to see</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Properties</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$xml</span> = <span style="color: #009900;">&quot;&lt;DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'&gt;&lt;StackPanel&gt;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">foreach</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$property</span> <span style="color: #666699; font-weight: bold;">in</span> <span style="color: #660033; font-weight: bold;">$Properties</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$xml</span> += <span style="color: #009900;">&quot;&lt;TextBlock Text='{Binding Path=$($property)}'/&gt;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">XML</span><span style="color: #333;">&#93;</span><span style="color: #660033; font-weight: bold;">$xml</span> = <span style="color: #660033; font-weight: bold;">$xml</span> + <span style="color: #009900;">&quot;&lt;/StackPanel&gt;&lt;/DataTemplate&gt;&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$listBox</span>.<span style="color: #003366;">ItemTemplate</span> = <span style="color: #333;">&#91;</span>Windows.<span style="color: #003366;">Markup</span>.<span style="color: #003366;">XamlReader</span><span style="color: #333;">&#93;</span>::<span style="color: #003366;">Load</span><span style="color: #333;">&#40;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">New-<span style="font-style: normal;">Object</span></span> <span style="color: #003366; font-weight: bold;">System</span>.<span style="color: #003366; font-weight: bold;">Xml</span>.<span style="color: #003366;">XmlNodeReader</span> <span style="color: #660033; font-weight: bold;">$xml</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$listBox</span><br />
&nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span><br />
<br />
<span style="color: #666699; font-weight: bold;">function</span> <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">PsBlogRoll</span></span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$webClient</span> = <span style="color: #0066cc; font-style: italic;">new-<span style="font-style: normal;">object</span></span> <span style="color: #003366; font-weight: bold;">System</span>.<span style="color: #003366;">Net</span>.<span style="color: #003366;">WebClient</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">xml</span><span style="color: #333;">&#93;</span><span style="color: #660033; font-weight: bold;">$Opml</span> = <span style="color: #660033; font-weight: bold;">$webClient</span>.<span style="color: #003366;">DownloadString</span><span style="color: #333;">&#40;</span><span style="color: #009900;">&quot;http://bloglines.com/export?id=halr9000&quot;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$PsBlogroll</span> = <span style="color: #660033; font-weight: bold;">$Opml</span>.<span style="color: #003366;">opml</span>.<span style="color: #003366;">body</span>.<span style="color: #003366;">outline</span> | <span style="color: #0066cc; font-style: italic;">Where-<span style="font-style: normal;">Object</span></span> <span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">text</span> <span style="color: #000066;">-eq</span> <span style="color: #009900;">'@Powershell'</span> <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## The Select statement outputs a custom PSObject instead of the original (XmlNode) object</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$PsBlogroll</span>.<span style="color: #003366;">Outline</span> | <span style="color: #0066cc; font-style: italic;">Select-<span style="font-style: normal;">Object</span></span> title, text, htmlUrl, xmlUrl<br />
<span style="color: #333;">&#125;</span><br />
<br />
<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">PSBlogRoll</span></span> | <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">Listbox</span></span> title | Show-Control @<span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&quot;MouseDoubleClick&quot;</span> = <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># But now I can use the &quot;HtmlUrl&quot; property to launch it in my browser</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#91;</span>Diagnostics.<span style="color: #666699; font-weight: bold;">Process</span><span style="color: #333;">&#93;</span>::<span style="color: #003366;">Start</span><span style="color: #333;">&#40;</span> <span style="color: #660033; font-weight: bold;">$window</span>.<span style="color: #003366;">Content</span>.<span style="color: #003366;">SelectedItem</span>.<span style="color: #003366;">HtmlUrl</span> <span style="color: #333;">&#41;</span> <br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<p>Of course, because of how I wrote the DataTemplate for the properties (using a StackPanel and a loop to output multiple TextBlock objects) you could choose to show the <span class="ubernym uttInitialism" onmouseover="domTT_activate(this, event, 'content', 'Uniform Resource Locator' );"><abbr class="uttInitialism">Url</abbr></span> as well, and all you&#8217;d have to do is change the call to Get-Listbox like this: <code>Get-Listbox title,htmlUrl</code> &#8230; which is pretty cool.  Does anyone else have any ideas for making these even easier to compose?  </p>

	<p>A <em>really</em> nice trick would be if the wpf cmdlet could use <code>Write-Output</code> in the click handler and actually <code>yield</code> to allow the rest of the pipeline to process that item, but so far, I haven&#8217;t been able to find a way to do that (short of closing the <span class="caps">WPF</span> window, of course).</p>]]></content:encoded>
			<wfw:commentRss>http://HuddledMasses.org/ideas-for-writing-composable-powershell-scripts/feed/</wfw:commentRss>
		</item>
		<item>
		<title>WPF From PowerShell - The Missing Walkthrough</title>
		<link>http://HuddledMasses.org/wpf-from-powershell-the-missing-walkthrough/</link>
		<comments>http://HuddledMasses.org/wpf-from-powershell-the-missing-walkthrough/#comments</comments>
		<pubDate>Tue, 27 May 2008 13:53:19 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
		
		<category><![CDATA[Huddled]]></category>

		<category><![CDATA[CTP]]></category>

		<category><![CDATA[PowerShell]]></category>

		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/?p=545</guid>
		<description><![CDATA[If you&#8217;ve been reading my series of articles about using WPF from PowerShell and wishing I had started with the basics about what WPF is &#8230; you&#8217;re in luck.  Following my series of posts, the PowerShell team has written their own series &#8212; with a much more methodical approach.  Starting with an introduction [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve been reading my series of articles about using <span class="caps">WPF</span> from PowerShell and wishing I had started with the basics about what <span class="caps">WPF</span> is &#8230; you&#8217;re in luck.  Following my series of posts, the PowerShell team has written their own series &#8212; with a much more methodical approach.  Starting with <a href="http://blogs.msdn.com/powershell/archive/2008/05/22/wpf-powershell-part-1-hello-world-welcome-to-the-week-of-wpf.aspx">an introduction to <span class="caps">WPF</span> and PowerShell</a> followed by a great overview of how to use some of the <a href="http://blogs.msdn.com/powershell/archive/2008/05/23/wpf-powershell-part-2-exploring-wpf-and-the-rest-of-net-with-scripts.aspx"><span class="caps">WPF</span> controls from PowerShell</a> and how to <a href="http://blogs.msdn.com/powershell/archive/2008/05/24/wpf-powershell-part-3-handling-events.aspx">handle <span class="caps">WPF</span> events</a> , they have now moved beyond the basics of <a href="http://blogs.msdn.com/powershell/archive/2008/05/25/wpf-powershell-part-4-xaml-show-control.aspx"><span class="caps">XAML</span> and PowerShell</a> to show you how you can <a href="http://blogs.msdn.com/powershell/archive/2008/05/26/wpf-powershell-part-5-using-wpf-powershell-modules.aspx">make <span class="caps"><span class="ubernym uttAcronym" onmouseover="domTT_activate(this, event, 'content', 'Graphical User Interface' );"><acronym class="uttAcronym">GUI</acronym></span></span> a part of your PowerShell pipeline</a> like I did with my <a href="/wpf-from-powershell-select-grid/">Select-Grid</a> post.  With their most recent post, they explain <a href="http://blogs.msdn.com/powershell/archive/2008/05/27/wpf-powershell-part-6-running-functions-in-the-background.aspx">how to run <span class="caps">WPF</span> in a background runspace</a>  and they promise tomorrow they&#8217;ll expand on that to &#8220;make controls in the background stream data and talk to the main runspace&#8221; &#8212; these two topics are what I was going get to next, so this frees me up to play with something more interesting <img src='http://HuddledMasses.org/wordpress/wp-content/plugins/smilingmasses/bigsmile.gif' alt=':-D' class='wp-smiley' /> &#8230;.</p>]]></content:encoded>
			<wfw:commentRss>http://HuddledMasses.org/wpf-from-powershell-the-missing-walkthrough/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
