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

<channel>
	<title>Huddled Masses &#187; CodeSigning</title>
	<atom:link href="http://huddledmasses.org/tag/codesigning/feed/" rel="self" type="application/rss+xml" />
	<link>http://huddledmasses.org</link>
	<description>You can do more than breathe for free...</description>
	<lastBuildDate>Fri, 27 Apr 2012 05:42:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<cloud domain='huddledmasses.org' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
		<item>
		<title>Getting Started with PowerShell 2 &#8211; Part 3</title>
		<link>http://huddledmasses.org/getting-started-with-powershell-2-part-3/</link>
		<comments>http://huddledmasses.org/getting-started-with-powershell-2-part-3/#comments</comments>
		<pubDate>Thu, 24 Jul 2008 04:40:38 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[BestPractices]]></category>
		<category><![CDATA[CodeSigning]]></category>
		<category><![CDATA[GettingStarted]]></category>
		<category><![CDATA[Modules]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Profile]]></category>
		<category><![CDATA[WalkThrough]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/?p=561</guid>
		<description><![CDATA[My &#8220;getting started&#8221; series ran out of steam a bit partly because I didn&#8217;t get much feedback on them &#8212; maybe you&#8217;re not interested, or maybe it wasn&#8217;t easy enough, or was just too confusing. In any case, I want to put up at least this one last post to suggest that you get the [...]]]></description>
			<content:encoded><![CDATA[	<p>My &#8220;getting started&#8221; series ran out of steam a bit partly because I didn&#8217;t get much feedback on them &#8212; maybe you&#8217;re not interested, or maybe it wasn&#8217;t easy enough, or was just too confusing. In any case,  I want to put up at least this one last post to suggest that you get the <a href="http://PoshCode.org/">PowerShell Code Repository</a> set up, and to show you the final version of my profile script and how it loads the various pieces it needs, and then I&#8217;ll send you on your way. </p>

	<p>Once you&#8217;ve got your PowerShell <a href="/getting-started-with-powershell-2-part-1">all installed</a> and have set up <a href="/getting-started-with-powershell-2-part-2">your first profile</a> to auto-load &#8230; you&#8217;re going to want some scripts (well, maybe you&#8217;ll want to learn more about how to use PowerShell, but go with me on this)! </p>

	<p>One of the best places to look for scripts is the <a href="http://PoshCode.org/">PowerShell Code Repository</a>, and although you can browse and search on the website, you can also do it using the PoshCode <a href="http://PoshCode.org/PoshCode.psm1">module</a> (or the <span class="em2">version 1 compatible</span> <a href="http://PoshCode.org/PoshCode.ps1">script</a>).  These scripts include a <code>Get-PoshCode</code> cmdlet which you can use with search terms to get a list of scripts and cmdlets back, or with numeric IDs to download scripts (you&#8217;ll see what I mean later on, for now, go ahead and grab the appropriate version of that script).</p>

	<p>I&#8217;m going to assume you put it into your AutoModules folder. If you grabbed the module, it should be saved to  WindowsPowerShell\AutoModules\PoshCode\PoshCode.psm1 otherwise, to WindowsPowerShell\AutoModules\PoshCode.ps1 &#8230; but you may have run into a minor problem if you load the .ps1 version <span style="padding-left:1em;padding-right:1em;text-align:left;" class="em2">)</span>. Both the module and the script are signed, but they are signed by <a href="/JoelBennett_Code-Signing.crt">my self-issued code signing certificate</a> which your computer almost certainly doesn&#8217;t trust&#8230;  You can use the signature to verify that the file hasn&#8217;t been modified since I signed it, but that&#8217;s about all (and even that&#8217;s a bit of a trick). To actually use the script (module), you&#8217;ll need to sign the script yourself (see the steps and how to get a certificate <a href="/getting-started-with-powershell-2-part-2">in part 2</a>).</p>

	<p><strong>If you&#8217;re on CTP2</strong>, this would be a good time to get my Authenticode script module to help with signing, and to learn a little about those PoshCode cmdlets &#8230; <span id="more-561"></span></p>

	<h3>Using PoshCode to get a module.</h3>

	<p>Create a folder in your AutoModules folder named &#8220;Authenticode&#8221; ... and then inside it, try running <code>Get-PoshCode Authenticode</code> &#8230; You should get a list of 3 or more versions of my script, entitled &#8220;Get/Set Signature (CTP2)&#8221;.  You want the latest version, so pick the one with the biggest number for the ID, and run <code>Get-PoshCode 464</code>.  That should download it and save it. You&#8217;ll be able to load it using Add-Module (since Add-Module in the current <span class="caps">CTP</span> doesn&#8217;t care about code-signing), but <strong>first</strong> you need to create a settings file (it will tell you how, if you try to load it without setting it).  change the <strong>CertificateThumbprint</strong> that&#8217;s set in the first line of code in that script &#8212; set it to the thumbprint of your personal code-signing cert (which you&#8217;ve hopefully imported into your certificate store).</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #666666; font-style: italic;">#requires -version 2.0</span><br />
<span style="color: #660033;">cd</span> <span style="color: #660033; font-weight: bold;">$ProfileDir</span>\AutoModules<br />
<span style="color: #660033;">mkdir</span> Authenticode <span style="color: #66cc66;">|</span> <span style="color: #660033;">cd</span> <span style="color: #666666; font-style: italic;"># Skip this line if you're on v1</span><br />
<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">PoshCode</span></span> Authenticode <span style="color: #66cc66;">|</span> <span style="color: #660033;">ft</span> Id, Title, Author, Description <span style="color: #000066;">-auto</span><br />
<span style="color: #666666; font-style: italic;"># assuming the first hit is the newest one ... hit the up arrow, and add:</span><br />
<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">PoshCode</span></span> <span style="color: #009900;">&quot;Authenticode Signature CTP2&quot;</span> <span style="color: #66cc66;">|</span> <span style="color: #660033;">select</span> <span style="color: #000066;">-first</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">|</span> <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">PoshCode</span></span><br />
<br />
<span style="color: #666666; font-style: italic;"># Make a subdirectory for your LANGUAGE</span><br />
<span style="color: #660033;">mkdir</span> en <span style="color: #66cc66;">|</span> <span style="color: #660033;">cd</span> <br />
<span style="color: #666666; font-style: italic;"># And create a PowerShell Data file with my cert path ...</span><br />
<span style="color: #666666; font-style: italic;"># I loaded my certificate into my user store, but you can use a pfx file </span><br />
<span style="color: #0066cc; font-style: italic;">new-<span style="font-style: normal;">item</span></span> Authenticode.<span style="color: #003366;">psd1</span> <span style="color: #000066;">-type</span> file <span style="color: #000066;">-value</span> <span style="color: #009900;">'&quot;Cert:\CurrentUser\My\F05F583BB5EA4C90E3B9BF1BDD0B657701245BD5&quot;'</span><br />
<br />
<span style="color: #666666; font-style: italic;"># Load the module...</span><br />
<span style="color: #0066cc; font-style: italic;">Add-<span style="font-style: normal;">Module</span></span> Authenticode</div>

	<p>Now you&#8217;ll be able to sign without specifying the certificate each time, and you&#8217;ll be able to pipe files in too, so you could, for instance, sign all the script files in a whole folder tree like: </p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #660033;">ls</span> <span style="color: #660033; font-weight: bold;">$ProfileDir</span>\AutoModules\<span style="color: #66cc66;">*</span> <span style="color: #000066;">-recurse</span> <span style="color: #000066;">-include</span> <span style="color: #66cc66;">*</span>.<span style="color: #003366;">ps1</span>,<span style="color: #66cc66;">*</span>.<span style="color: #003366;">ps1xml</span> <span style="color: #66cc66;">|</span> <span style="color: #0066cc; font-style: italic;">Set-<span style="font-style: normal;">AuthenticodeSignature</span></span></div>

	<h3>So, here&#8217;s what I do.</h3>

	<p>First of all, I don&#8217;t <em>actually</em> put .ps1 scripts into the AutoModules folder, I have a separate AutoScripts folder, and I dot-source scripts from there, as well as loading ps1xml format files from it.  I also specifically use a series of scripts there: Aliases.ps1, Variables.ps1, and EyeCandy.ps1.  I assume that the functions of the first two are obvious, the last one is a modified version of the <span class="caps">PSCX</span> prompt and <acronym title="Message of the Day">MOTD</acronym> script to modify my prompt and startup message.</p>

	<p>On top of the PoshCode script module and the Authenticode script module I mentioned earlier, which I use for signing and resigning, and the new CTP2 version of the <a href="http://thepowershellguy.com/blogs/posh/pages/powertab-v2-alpha-1.aspx">PowerTab script module</a>, I also use a source build of the upcoming <span class="caps">PSCX</span> 1.2 release (which needs a bunch of scripts to be useful, so I just renamed their 3-line profile.ps1 to <span class="caps">PSCX</span>.psm1 and stuffed the whole build with all it&#8217;s sub-folders into my WindowsPowerShell\AutoModules\<span class="caps">PSCX</span>).  I also preload my PoshHttp module for downloading files from the web, and I a couple of functions (<a href="http://poshcode.org/477">ellipsis</a> and <a href="http://poshcode.org/424">Get-PerformanceHistory</a>).</p>

	<p>Almost everything else I use I write into scripts (I even use the in-line cmdlet syntax to get full-power parameter parsing in a script file) which I put in directories by category inside my main WindowsPowerShell\Scripts directory (in my profile directory, and add to my path so that I can just run a script named &#8220;Get-<span class="caps">GUID</span>.ps1&#8221; by typing <code>Get-GUID</code> on the command-line.</p>

	<p>Here&#8217;s the profile script off my laptop as an example &#8212; I basically use the same profile on all my PCs, and make changes to the &#8220;Variables&#8221; scripts on each PC to differentiate them.  In fact, I have a sub-directory of my &#8220;WindowsPowerShell\Scripts&#8221; called &#8220;Work&#8221; which I even keep around at home (although I practically never use those scripts at home &#8212; they&#8217;re mostly for resetting servers and doing db queries, and only work from home when my <span class="caps">VPN</span> connection is up).  Let me know if you have any questions.  <img src='http://huddledmasses.org/wordpress/wp-includes/' alt=';)' class='wp-smiley' /> </p>

	<p>Incidentally, I use &#8220;RemoteSigned for my Execution Policy &#8212; <span class="em1b">I wish there were a way to <strong>require</strong> signing for just my profile</span>, because then this system would basically protect me from tampering with my auto-run scripts.  However, I&#8217;m actually comfortable not worrying about it any more than I worry about viruses replacing the executable for Notepad++ on my thumbdrive or something &#8212; I <strong>do</strong> realize that this profile script could be simplified a lot if I replaced the signature checking with just using the &#8220;AllSigned&#8221; policy &#8230; but there&#8217;s two <strong>major</strong> problems with that:</p>

	<ol>
		<li>I&#8217;m a PowerShell-ed developer &#8212; I spend a lot of time editing scripts and running them, and re-signing scripts that I&#8217;m working on (even though it&#8217;s just a matter of typing &#8220;sign&#8221; before I run a script) becomes an annoyance, such that if I were working in that environment, I&#8217;d inevitably have a &#8220;Sign-and-Run&#8221; script, which would really make me less secure, rather than more &#8212; for the average <em>user</em>, I <strong>do</strong> think that if you&#8217;re not writing scripts yourself on a daily basis, you should consider using <strong>AllSigned</strong>.</li>
	</ol>
	<ol>
		<li><span class="em2b">PowerShell 2 CTP2 doesn&#8217;t check signatures on modules</span>, so even if I have it set to all-signed, it will load script modules and will <span class="em2">let you dot-source <strong>any</strong> script</span> using the add-module command, so I&#8217;d have to avoid modules altogether to really be 100% secure.</li>
	</ol>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #666666; font-style: italic;"># Set the profile directory first, so we can refer to it for the rest of the script...</span><br />
<span style="color: #0066cc; font-style: italic;">Set-<span style="font-style: normal;">Variable</span></span> ProfileDir &nbsp;<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;">$MyInvocation</span>.<span style="color: #003366;">MyCommand</span>.<span style="color: #003366;">Path</span> <span style="color: #000066;">-Parent</span><span style="color: #333;">&#41;</span> <span style="color: #000066;">-Scope</span> Global <span style="color: #000066;">-Option</span> AllScope<br />
<br />
<span style="color: #660033;">cd</span> <span style="color: #660033; font-weight: bold;">$ProfileDir</span><br />
<span style="color: #666666; font-style: italic;"># I have a JOIN function I need for massaging path variables ...</span><br />
<span style="color: #666699; font-weight: bold;">function</span> <span style="color: #333399; font-weight: bold; font-style: italic;">join</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">param</span> &nbsp; &nbsp;<span style="color: #333;">&#40;</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">string</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$sep</span>, <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">string</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$append</span>, <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">string</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$prepend</span> <span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">begin</span> &nbsp; &nbsp;<span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$ofs</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$sep</span>; <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">string</span><span style="color: #333;">&#91;</span><span style="color: #333;">&#93;</span><span style="color: #333;">&#93;</span></span><span style="color: #660033; font-weight: bold;">$items</span> <span style="color: #66cc66;">=</span> &nbsp;@<span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$prepend</span>.<span style="color: #333399; font-weight: bold; font-style: italic;">split</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$sep</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">process</span> &nbsp;<span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$items</span> <span style="color: #66cc66;">+=</span> <span style="color: #660033; font-weight: bold;">$_</span> <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">end</span> &nbsp; &nbsp; &nbsp;<span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$items</span> <span style="color: #66cc66;">+=</span> @<span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$append</span>.<span style="color: #333399; font-weight: bold; font-style: italic;">split</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$sep</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span>; <span style="color: #666699; font-weight: bold;">return</span> <span style="color: #009900;">&quot;$($items -ne '')&quot;</span> <span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span><br />
<br />
<span style="color: #666666; font-style: italic;">## If we're on version two, we HAVE to set the PsPackagePath (it doesn't matter on v1)</span><br />
<span style="color: #660033; font-weight: bold;">$ENV</span>:PSPACKAGEPATH <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;$ProfileDir\AutoModules;$ProfileDir\Modules&quot;</span> <span style="color: #666666; font-style: italic;">#| join &quot;;&quot; -append $ENV:PSPACKAGEPATH</span><br />
<span style="color: #666666; font-style: italic;">## We also want to add our scripts directory to the path</span><br />
<span style="color: #660033; font-weight: bold;">$ENV</span>:PATH <span style="color: #66cc66;">=</span> <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>\Script<span style="color: #333;">&#91;</span>s<span style="color: #333;">&#93;</span>,<span style="color: #660033; font-weight: bold;">$ProfileDir</span>\Scripts\<span style="color: #66cc66;">*</span> &nbsp;<span style="color: #66cc66;">|</span> ? <span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">PsIsContainer</span> <span style="color: #333;">&#125;</span> <span style="color: #66cc66;">|</span> <span style="color: #66cc66;">%</span> <span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">FullName</span> <span style="color: #333;">&#125;</span> <span style="color: #66cc66;">|</span> <span style="color: #333399; font-weight: bold; font-style: italic;">Join</span> <span style="color: #009900;">&quot;;&quot;</span> <span style="color: #000066;">-append</span> <span style="color: #660033; font-weight: bold;">$ENV</span>:PATH<br />
<br />
<span style="color: #666666; font-style: italic;">## Now, preload any module in AutoModules that is signed ...</span><br />
<span style="color: #666666; font-style: italic;">###################################################################################################</span><br />
<span style="color: #666666; font-style: italic;">##### &nbsp;NOTE: &nbsp; There's a bug which prevents signing or checking psm1 files</span><br />
<span style="color: #666666; font-style: italic;">##### &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;We work around that bug by using this module called &quot;Authenticode&quot; which </span><br />
<span style="color: #666666; font-style: italic;">##### &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Wraps the Get/Set cmdlets in scripts that check psm1 by renaming them to ps1</span><br />
<span style="color: #0066cc; font-style: italic;">Add-<span style="font-style: normal;">Module</span></span> Authenticode<br />
<span style="color: #666666; font-style: italic;">##### &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Now we can check signatures on .psm1 files ...</span><br />
<span style="color: #666666; font-style: italic;">##### &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;As long as they're in locations where we can rename them without problems</span><br />
<span style="color: #666666; font-style: italic;">## One last exception case:</span><br />
<span style="color: #666666; font-style: italic;">## If PSCX is available, load that FIRST, because others may depend on it.</span><br />
<span style="color: #0066cc; font-style: italic;">Add-<span style="font-style: normal;">Module</span></span> PSCX <span style="color: #000066;">-EA</span> <span style="color: #009900;">&quot;SilentlyContinue&quot;</span><br />
<br />
<span style="color: #666666; font-style: italic;">## Now automatically Add-Module the module subfolders ....</span><br />
<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Host</span></span> <span style="color: #009900;">&quot;AutoLoad Modules: &quot;</span> <span style="color: #000066;">-Fore</span> Cyan <span style="color: #000066;">-NoNewLine</span><br />
<span style="color: #660033; font-weight: bold;">$AutoModuleErrors</span> <span style="color: #66cc66;">=</span> @<span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span><br />
<span style="color: #666699; font-weight: bold;">ForEach</span><span style="color: #333;">&#40;</span> <span style="color: #660033; font-weight: bold;">$module</span> <span style="color: #666699; font-weight: bold;">in</span> <span style="color: #333;">&#40;</span><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: #66cc66;">|</span> ? <span style="color: #333;">&#123;</span> <span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">PsIsContainer</span> <span style="color: #333;">&#125;</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># Write-Host &quot;Test-Module $($module.Name) &quot; -fore Yellow</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">switch</span> <span style="color: #333;">&#40;</span><span style="color: #660033;">ls</span> <span style="color: #009900;">&quot;$($module.FullName)\*&quot;</span> <span style="color: #000066;">-include</span> <span style="color: #009900;">&quot;$($module.Name).psd1&quot;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&quot;$($module.Name).ps1&quot;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&quot;$($module.Name).psm1&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&quot;$($module.Name).dll&quot;</span> <span style="color: #66cc66;">|</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #660033;">sort</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">switch</span><span style="color: #333;">&#40;</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>IO.<span style="color: #003366;">Path</span><span style="color: #333;">&#93;</span></span>::<span style="color: #003366;">GetExtension</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">Name</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&quot;.psd1&quot;</span> <span style="color: #333;">&#123;</span> <span style="color: #cc66cc;">0</span> <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&quot;.ps1&quot;</span> &nbsp;<span style="color: #333;">&#123;</span> <span style="color: #cc66cc;">1</span> <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&quot;.psm1&quot;</span> <span style="color: #333;">&#123;</span> <span style="color: #cc66cc;">2</span> <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&quot;.dll&quot;</span> &nbsp;<span style="color: #333;">&#123;</span> <span style="color: #cc66cc;">3</span> <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span> <span style="color: #66cc66;">|</span> <span style="color: #660033;">Select</span> <span style="color: #000066;">-First</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">|</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">AuthenticodeSignature</span></span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">## If they're signed and valid, Add-Module</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#123;</span> &nbsp;<span style="color: #0066cc; font-style: italic;">Test-<span style="font-style: normal;">Signature</span></span> <span style="color: #660033; font-weight: bold;">$_</span> <span style="color: #333;">&#125;</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Add-<span style="font-style: normal;">Module</span></span> <span style="color: #660033; font-weight: bold;">$module</span>.<span style="color: #003366;">Name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Host</span></span> <span style="color: #009900;">&quot;$($module.Name) &quot;</span> <span style="color: #000066;">-fore</span> Cyan <span style="color: #000066;">-NoNewLine</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">continue</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;">## Otherwise, write an error, we don't want this to fail silently</span><br />
&nbsp; &nbsp; &nbsp; default <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$Global</span>:AutoModuleErrors <span style="color: #66cc66;">+=</span> @<span style="color: #333;">&#40;</span><span style="color: #009900;">&quot;&quot;</span> <span style="color: #66cc66;">|</span> <span style="color: #660033;">Select</span> @<span style="color: #333;">&#123;</span>n<span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;Name&quot;</span>;e<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span><span style="color: #660033; font-weight: bold;">$module</span>.<span style="color: #003366;">Name</span><span style="color: #333;">&#125;</span><span style="color: #333;">&#125;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;@<span style="color: #333;">&#123;</span>n<span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;Path&quot;</span>;e<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span><span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">Path</span><span style="color: #333;">&#125;</span><span style="color: #333;">&#125;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;@<span style="color: #333;">&#123;</span>n<span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;Error&quot;</span>;e<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span><span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">Status</span><span style="color: #333;">&#125;</span><span style="color: #333;">&#125;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;@<span style="color: #333;">&#123;</span>n<span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;StatusMessage&quot;</span>;e<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span><span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">StatusMessage</span><span style="color: #333;">&#125;</span><span style="color: #333;">&#125;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Host</span></span> <span style="color: #009900;">&quot;$($module.Name) &quot;</span> <span style="color: #000066;">-fore</span> Red <span style="color: #000066;">-NoNewLine</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span> <br />
<span style="color: #333;">&#125;</span><br />
<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Host</span></span><br />
<br />
<span style="color: #666666; font-style: italic;">## And then, preload any script in AutoScripts that is signed ...</span><br />
<span style="color: #666666; font-style: italic;">###################################################################################################</span><br />
<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Host</span></span> <span style="color: #009900;">&quot;AutoLoad Scripts: &quot;</span> <span style="color: #000066;">-Fore</span> Green <span style="color: #000066;">-NoNewLine</span><br />
<span style="color: #666699; font-weight: bold;">switch</span> <span style="color: #333;">&#40;</span><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>\AutoScripts\<span style="color: #66cc66;">*</span>.<span style="color: #660033;">ps</span><span style="color: #66cc66;">*</span> <span style="color: #000066;">-include</span> <span style="color: #66cc66;">*</span>.<span style="color: #003366;">ps1</span>,<span style="color: #66cc66;">*</span>.<span style="color: #003366;">ps1xml</span> <span style="color: #66cc66;">|</span> <span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">AuthenticodeSignature</span></span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## If they're signed and valid, load them based on type</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#123;</span> <span style="color: #0066cc; font-style: italic;">Test-<span style="font-style: normal;">Signature</span></span> <span style="color: #660033; font-weight: bold;">$_</span> <span style="color: #333;">&#125;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$Path</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">Path</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">switch</span> <span style="color: #333;">&#40;</span><span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>IO.<span style="color: #003366;">Path</span><span style="color: #333;">&#93;</span></span>::<span style="color: #003366;">GetExtension</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$Path</span><span style="color: #333;">&#41;</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> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">Add-<span style="font-style: normal;">Module</span></span> <span style="color: #660033; font-weight: bold;">$Path</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Host</span></span> <span style="color: #009900;">&quot;$([IO.Path]::GetFileNameWithoutExtension($Path)) &quot;</span> <span style="color: #000066;">-Fore</span> Green <span style="color: #000066;">-NoNewLine</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<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;">$Path</span> <span style="color: #333;">&#125;</span> <br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">continue</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## Otherwise, write an error, we don't want this to fail silently</span><br />
&nbsp; &nbsp;default <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$Name</span> <span style="color: #66cc66;">=</span> $<span style="color: #333;">&#40;</span><span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>IO.<span style="color: #003366;">Path</span><span style="color: #333;">&#93;</span></span>::<span style="color: #003366;">GetFileNameWithoutExtension</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">Path</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #660033; font-weight: bold;">$Global</span>:AutoModuleErrors <span style="color: #66cc66;">+=</span> @<span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$_</span> <span style="color: #66cc66;">|</span> <span style="color: #660033;">Select</span> @<span style="color: #333;">&#123;</span>n<span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;Name&quot;</span>;e<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span><span style="color: #660033; font-weight: bold;">$Name</span><span style="color: #333;">&#125;</span><span style="color: #333;">&#125;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @<span style="color: #333;">&#123;</span>n<span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;Error&quot;</span>;e<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span><span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">Status</span><span style="color: #333;">&#125;</span><span style="color: #333;">&#125;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @<span style="color: #333;">&#123;</span>n<span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;StatusMessage&quot;</span>;e<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span><span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">StatusMessage</span><span style="color: #333;">&#125;</span><span style="color: #333;">&#125;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @<span style="color: #333;">&#123;</span>n<span style="color: #66cc66;">=</span><span style="color: #009900;">&quot;Path&quot;</span>;e<span style="color: #66cc66;">=</span><span style="color: #333;">&#123;</span><span style="color: #660033; font-weight: bold;">$_</span>.<span style="color: #003366;">Path</span><span style="color: #333;">&#125;</span><span style="color: #333;">&#125;</span><span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Host</span></span> <span style="color: #009900;">&quot;$Name &quot;</span> <span style="color: #000066;">-fore</span> Red <span style="color: #000066;">-NoNewLine</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span><br />
<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Host</span></span><br />
<span style="color: #666666; font-style: italic;"># Write out the error messages if we missed loading any modules</span><br />
<span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$AutoModuleErrors</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$AutoModuleErrors</span> <span style="color: #66cc66;">|</span> <span style="color: #0066cc; font-style: italic;">Format-<span style="font-style: normal;">Table</span></span> <span style="color: #66cc66;">*</span> <span style="color: #000066;">-auto</span> <span style="color: #66cc66;">|</span> <span style="color: #0066cc; font-style: italic;">Out-<span style="font-style: normal;">Host</span></span><br />
<span style="color: #333;">&#125;</span></div>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/getting-started-with-powershell-2-part-3/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<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">IRC</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">IRC</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">SSL</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">PGP</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>
	</ol>
	<ol>
		<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.<span id="more-562"></span></p>

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

	<h3>The <a href="http://PoshCode.org"><b>Po</b>wer<b>Sh</b>ell Code repository</a> 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 url 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>
	</ul>
	<ul>
		<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">IRC</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">PGP</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>
	</ul>
	<ul>
		<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">PGP</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">PGP</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>
	</ul>
	<ul>
		<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">PGP</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">PGP</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">PGP</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">PGP</span> signing that&#8217;s compatible with <span class="caps">XML</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">PGP</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>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Started with PowerShell 2 &#8211; 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 set of [...]]]></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.<span id="more-559"></span></p>

	<p> <img src='http://huddledmasses.org/wordpress/wp-includes/' 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> <img src='http://huddledmasses.org/wordpress/wp-includes/' alt='[new]' class='wp-smiley' />  <strong>Edit</strong>: I&#8217;ve simplified this a bit, and modified the script to import the certificate to the <em>Current User</em> certificate store if you aren&#8217;t running in an elevated console (in Vista) &#8212; which should work fine if you&#8217;re the only user on your machine that needs to run the scripts &#8212; if you need them in the <em>Local Machine</em> store, you need to be running as administrator.  The script will let you know which it does, so you&#8217;ll know, one way or another.</p>

	<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\PoshCerts\bin.</p>

	<p><strong>Step 2.</strong> 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="posh 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></div>

	<p> <img src='http://huddledmasses.org/wordpress/wp-includes/' alt='[new]' class='wp-smiley' />  <strong>Edit</strong>: I came up with a <strong>Step 3.</strong> Under most circumstances (that is, unless you were planning on running a corporate Certificate Authority), you&#8217;ll have no further use for the CA certificate, If you want to make sure that nobody can abuse your root CA &#8230; you can and should just delete the private certificates, like so: <code>Remove-Item *Root-CA.* -exclude *.crt</code></p>

	<h4>Signing Scripts</h4>

	<p>You can now sign scripts at will using the <strong>pfx</strong> file generated in step 2 with the Get-PfxCertificate cmdlet, or the Cert: provider (you have use -ImportAll when you call New-CodeSigningCert, not just -Import &#8212; that causes the import of your code-signing certificate to the &#8220;My&#8221; store &#8230; then you can do <code>Get-ChildItem &#34;Cert:\CurrentUser\My\$thumbprint&#34;</code> where $thumbprint is your certificate&#8217;s thumbprint).  </p>

	<p>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="posh 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\<span style="color: #66cc66;">*</span>Code<span style="color: #66cc66;">-</span>Signing.<span style="color: #003366;">pfx</span><br />
&nbsp; &nbsp; <span style="color: #333;">&#41;</span> .\Profile.<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 />
<span style="color: #660033;">mv</span> .\Profile.<span style="color: #003366;">ps1</span> .\AutoModules\PSCX.<span style="color: #003366;">ps1</span><br />
&nbsp;</div>

	<p> <img src='http://huddledmasses.org/wordpress/wp-includes/' alt='[new]' class='wp-smiley' />  <strong>Edit</strong>: The simplest</p>

	<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="posh code posh" style="font-family:monospace;"><br />
<span style="color: #660033; font-weight: bold;">$ProfileDir</span> <span style="color: #66cc66;">=</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: #66cc66;">=</span> <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: #66cc66;">*</span> <span style="color: #000066;">-include</span> <span style="color: #66cc66;">*</span>.<span style="color: #003366;">ps1</span> <span style="color: #000066;">-recurse</span> <span style="color: #66cc66;">|</span> <br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">AuthenticodeSignature</span></span> <span style="color: #66cc66;">|</span> <br />
&nbsp; &nbsp;Where<span style="color: #66cc66;">-</span>Object <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> <span style="color: #66cc66;">|</span> <br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">ChildItem</span></span> <span style="color: #66cc66;">|</span> <span style="color: #66cc66;">&amp;</span><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;default &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></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 <a href="http://huddledmasses.org/getting-started-with-powershell-2-part-3/">Part 3</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/getting-started-with-powershell-2-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</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; ">
<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="posh 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></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-includes/' 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> <img src='http://huddledmasses.org/wordpress/wp-includes/' alt='[new]' class='wp-smiley' />  I actually realized recently that you can use System.Security.Cryptography.X509certificates.X509Store to load certificates, rather than the old <span class="caps">COM</span> object, which makes this even easier. The most basic step is to just import the new <code>CA.crt</code> certificate into the Root Store.</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #660033; font-weight: bold;">$lm</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">new-<span style="font-style: normal;">object</span></span> System.<span style="color: #003366;">Security</span>.<span style="color: #003366;">Cryptography</span>.<span style="color: #003366;">X509certificates</span>.<span style="color: #003366;">X509Store</span> <span style="color: #009900;">&quot;root&quot;</span>, <span style="color: #009900;">&quot;LocalMachine&quot;</span><br />
<span style="color: #660033; font-weight: bold;">$lm</span>.<span style="color: #003366;">Open</span><span style="color: #333;">&#40;</span><span style="color: #009900;">&quot;ReadWrite&quot;</span><span style="color: #333;">&#41;</span><br />
<span style="color: #660033; font-weight: bold;">$lm</span>.<span style="color: #003366;">Add</span><span style="color: #333;">&#40;</span> <span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">Get-<span style="font-style: normal;">PfxCertificate</span></span> <span style="color: #009900;">&quot;$pwd\CA.crt&quot;</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#41;</span><br />
<span style="color: #666699; font-weight: bold;">if</span><span style="color: #333;">&#40;</span>$?<span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Host</span></span> <span style="color: #009900;">&quot;Successfully imported root certificate to trusted root store&quot;</span> <span style="color: #000066;">-fore</span> green<br />
<span style="color: #333;">&#125;</span><br />
<span style="color: #660033; font-weight: bold;">$lm</span>.<span style="color: #003366;">Close</span><span style="color: #333;">&#40;</span><span style="color: #333;">&#41;</span></div>

	<p>You no longer need to use 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 even though it&#8217;s basically available everywhere now, and <a href="http://go.microsoft.com/fwlink/?linkid=84567">is redistributable</a> &#8230; </p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #666666; font-style: italic;"># This is the COM way, if you can't get X509Store to work...</span><br />
<span style="color: #660033; font-weight: bold;">$Store</span> <span style="color: #66cc66;">=</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></div>

	<p>In either case, 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="posh code posh" style="font-family:monospace;"><br />
<span style="color: #660033; font-weight: bold;">$cert</span> <span style="color: #66cc66;">=</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 />
&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 <del>attached</del> uploaded the <a href="http://poshcode.org/1049">New-CodeSigningCert</a> script to PoshCode.org, 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 so you can hopefully figure it out, learn it, and modify as you see fit.</p>

	<p>I had also attached the script packaged with the OpenSSL,  <img src='http://huddledmasses.org/wordpress/wp-includes/' alt='[new]' class='wp-smiley' />  but as this post has aged, that seems like not so great an idea, since you really want the newer releases with bug fixes, particularly if you have a 64bit machine &#8230; the script needs to be stored in the same folder with OpenSSL.exe, and you can just unpack OpenSSL (there&#8217;s no need for an installer), but I just can&#8217;t be trusted to keep my local copy here up to date, sorry. :&#8217;(</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-includes/' alt=';)' class='wp-smiley' /> </p>

	<div class="posh 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: #66cc66;">=</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: #66cc66;">|</span> <span style="color: #66cc66;">%</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></div>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/code-signing-with-openssl-and-powershell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

