<?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>PowerShell Station &#187; Tools</title>
	<atom:link href="http://powershellstation.com/tag/tools/feed/" rel="self" type="application/rss+xml" />
	<link>http://powershellstation.com</link>
	<description>Mike&#039;s PowerShell Musings</description>
	<lastBuildDate>Wed, 14 Dec 2011 04:37:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>The PowerShell Bug That Wasn&#8217;t, and More Package Management</title>
		<link>http://powershellstation.com/2010/01/20/the-powershell-bug-that-wasnt-and-more-package-management/</link>
		<comments>http://powershellstation.com/2010/01/20/the-powershell-bug-that-wasnt-and-more-package-management/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 05:04:26 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[V2.0 Features]]></category>
		<category><![CDATA[Package]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Require]]></category>

		<guid isPermaLink="false">http://powershellstation.com/?p=255</guid>
		<description><![CDATA[Have you ever tracked down a bug, been confident that you had found the root of your problems, only to realize shortly afterwords that you missed it completely? What I posted yesterday as a bug in PowerShell (having to do with recursive functions, dot-sourcing, and parameters) seemed during my debugging session to clearly be a [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever tracked down a bug, been confident that you had found the root of your problems, only to realize shortly afterwords that you missed it completely?</p>
<p>What I posted yesterday as a bug in PowerShell (having to do with recursive functions, dot-sourcing, and parameters) seemed during my debugging session to clearly be a bug.  After all, I watched the parameter value change from b to a, didn&#8217;t I?  Sure did.  And in almost every language I&#8217;ve ever used, that would be a bug.  On the other hand, PowerShell is the only language that I know of that has dot-sourcing.  Here&#8217;s a much simpler code example which shows my faulty thinking:</p>
<pre class="brush: powershell">function f($x){
   if ($x -eq 1){
      write-host $x
      . f ($x+1)
      write-host $x
   }
}

f 1</pre>
<p>Here, we have a simple &#8220;recursive function&#8221; which uses dot-sourcing to call itself.  In my mind, how this would have worked is as follows:</p>
<ul>
<li>We call the function, passing 1 for $x</li>
<li>The if condition is true, so it prints 1 and calls the function, passing 2 for $x</li>
<li>In the inner call, the if condition is false, so nothing happens</li>
<li>We pop back to the calling frame, where $x is 1 and print it</li>
</ul>
<p>If it weren&#8217;t for that pesky dot operator, that would have been accurate.</p>
<p>The problem is, the dot operator changes the scoping of the inner call.  Here&#8217;s what the about_operators help topic, has to say about the dot sourcing operator:</p>
<pre>        Description: Runs a script so that the items in the script are part of the calling scope.</pre>
<p>Which is not a surprise&#8230;really.  The reason I was using the dot operator in my package management code was to make sure that functions defined in the scripts it was calling would be included in the existing scope, rather than their script scope.  The problem was one of nearsightedness.  I was so focused on the fact that the dot sourcing was making the functions part of the caller&#8217;s scope that I didn&#8217;t consider that variable declarations (including parameters) would also be in the caller&#8217;s scope.</p>
<p>So, the correct interpretation of the above script is:</p>
<ul>
<li>We call the function, passing 1 for $x</li>
<li>The if condition is true, so it prints 1 and calls the function, passing 2 for $x</li>
<li>The parameter is named $x, so $x in is set to 2 (overwriting the $x that was set to 1)</li>
<li>In the inner call, the if condition is false, so nothing happens</li>
<li>We pop back to the calling frame, where $x is 2 and print 2.</li>
</ul>
<p>The trick here is that the function f dot-sourced something that set $x to 2.  The fact that it was f is incidental.  It didn&#8217;t have to be.</p>
<p>Maybe this example will make it more clear:</p>
<pre class="brush:powershell">function f($x){
    write-host $x
    . g
    write-host $x
 }

function g{
   $x = "Hello, World!"
}
f 1</pre>
<p>If we were doing this without dot-sourcing, we would expect to see the number 1 printed out twice.  However, since we dot-sourced g, the assignment in the function body of g happens in the scope of f.  In other words, it&#8217;s as if the $x=&#8221;Hello, World!&#8221; were executed inside f.  Thus, the output of this script is 1, followed by &#8220;Hello, World!&#8221;.</p>
<p>So, it wasn&#8217;t a bug, it was just me not being thorough in applying my understanding of dot-sourcing.</p>
<p>Now, on with Package Management.<br />
First, to fix the problem caused by the parameter being overwritten (which it is, it&#8217;s just that it&#8217;s expected to be).  I hadn&#8217;t worked out a way to fix the problem before I went to bed last night, but as I was rolling this stuff around in my head (which is when I figured out that it wasn&#8217;t really a <em>bug</em>), I thought of a simple solution.  Since we can expect that sometimes the $filename parameter in the require (and reload) function will be overwritten by the a value in the dot-sourced script, we just need to make sure we&#8217;re done using it at that point.  So, I simply made the assignment to the dictionary before dot-sourcing.   Here&#8217;s the updated code:</p>
<pre class="brush: powershell">$global:loaded_scripts=@{pkg_utils='INITIAL'}

function require($filename){
	if (!$global:loaded_scripts[$filename]){
	   $global:loaded_scripts[$filename]=get-date
	   . scripts:$filename.ps1
	}
}
function reload($filename){
	$global:loaded_scripts[$filename]=get-date
	. scripts:$filename.ps1
}</pre>
<p>To add modules, we need to do a few extra things:</p>
<ul>
<li>We need to detect if we&#8217;re running in 2.0 or not</li>
<li>We need to see if there is a module with the given name</li>
<li>We need to see if the module is already loaded or not (in the case of require&#8230;it won&#8217;t matter for reload</li>
</ul>
<p>Fortunately, none of those are very difficult.  Here&#8217;s the updated code (including modules).  I even added some comments to make the flow more clear:</p>
<pre class="brush:powershell">
$global:loaded_scripts=@{pkg_utils='INITIAL'}

function require($filename){
    if ($global:loaded_scripts[$filename]){
          # this function has already loaded this (script or module)
          return
    }
    if ($psversiontable){
       # we're in 2.0
       if (get-module $filename -listavailable){
               #the module exists in the module path
         	   $global:loaded_scripts[$filename]=get-date
               import-module $filename
               return
       }
    }
    #it wasn't a module...so dot-source the script
    $global:loaded_scripts[$filename]=get-date
    . scripts:$filename.ps1

}
function reload($filename){
    if ($psversiontable){
        # we're in 2.0
        if (get-module $filename -listavailable){
           #the module exists in the module path
           $global:loaded_scripts[$filename]=get-date
           import-module $filename
           return
        }
    }
    # it wasn't a module...so dot-source the script.
  	$global:loaded_scripts[$filename]=get-date
	. scripts:$filename.ps1
}
</pre>
<p>That&#8217;s it for today.  Let me know what you think.</p>
<p>-Mike</p>
]]></content:encoded>
			<wfw:commentRss>http://powershellstation.com/2010/01/20/the-powershell-bug-that-wasnt-and-more-package-management/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>SQL PowerShell Extensions (SQLPSX) 2.0 Released</title>
		<link>http://powershellstation.com/2010/01/05/sql-powershell-extensions-sqlpsx-2-0-released/</link>
		<comments>http://powershellstation.com/2010/01/05/sql-powershell-extensions-sqlpsx-2-0-released/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 00:39:17 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Scripts]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Script]]></category>

		<guid isPermaLink="false">http://powershellstation.com/?p=233</guid>
		<description><![CDATA[The first module-based release of the SQL PowerShell Extensions (SQLPSX) was released recently on CodePlex.  It features very handy wrappers for most of the SMO objects used to manipulate SQL Server metadata, SSIS packages, Replication, and (new in the 2.0 release) an ADO.NET module which I wrote based on the code in this post.  There&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>The first module-based release of the SQL PowerShell Extensions (SQLPSX) was released recently on CodePlex.  It features very handy wrappers for most of the SMO objects used to manipulate SQL Server metadata, SSIS packages, Replication, and (new in the 2.0 release) an ADO.NET module which I wrote based on the code in this <a href="http://powershellstation.com/2009/09/15/executing-sql-the-right-way-in-powershell/">post</a>.  There&#8217;s also a data-collection process and Reporting Services reports to help you get your SQL Server installations under control.</p>
<p>Chad Miller, the driving force behind SQLPSX, has put a lot of effort into this release, and you&#8217;ll find really good examples of advanced functions (with comment-based help, even).</p>
<p>If you deal with SQL Server in any way, you&#8217;ll almost certainly be able to use this set of modules to streamline your scripting experience (and probably learn something about SMO in the process).</p>
<p>You can find the release <a href="http://sqlpsx.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=38047">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://powershellstation.com/2010/01/05/sql-powershell-extensions-sqlpsx-2-0-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerShell Tools and Books That I Use</title>
		<link>http://powershellstation.com/2009/09/10/powershell-tools-and-books-that-i-use/</link>
		<comments>http://powershellstation.com/2009/09/10/powershell-tools-and-books-that-i-use/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 05:13:19 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Books]]></category>

		<guid isPermaLink="false">http://powershellstation.com/?p=8</guid>
		<description><![CDATA[Tools I Use (note&#8230;these are all free!): PowerGUI Script Editor (I haven&#8217;t ever gotten the hang of PowerGUI itself) Powershell Community Extensions 1.2  (PSCX) PowerTab SQL PowerShell Extensions 1.61 (SQLPSX) PrimalForms Community Edition Books: PowerShell In Action by Bruce Payette Professional Windows PowerShell Programming: Snapins, Cmdlets, Hosts and Providers by  Arul Kumaravel et. al. Mastering [...]]]></description>
			<content:encoded><![CDATA[<p>Tools I Use (note&#8230;these are all free!):</p>
<ul>
<li>PowerGUI Script Editor (I haven&#8217;t ever gotten the hang of PowerGUI itself)</li>
<li>Powershell Community Extensions 1.2  (PSCX)</li>
<li>PowerTab</li>
<li>SQL PowerShell Extensions 1.61 (SQLPSX)</li>
<li>PrimalForms Community Edition</li>
</ul>
<p>Books:</p>
<ul>
<li>PowerShell In Action by Bruce Payette</li>
<li>Professional Windows PowerShell Programming: Snapins, Cmdlets, Hosts and Providers by  Arul Kumaravel et. al.</li>
<li>Mastering PowerShell by Dr. Tobias Weltner</li>
</ul>
<p>I&#8217;ve tried a lot of other tools (several IDE&#8217;s, for example), but this is the list I keep returning to.</p>
]]></content:encoded>
			<wfw:commentRss>http://powershellstation.com/2009/09/10/powershell-tools-and-books-that-i-use/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- This Quick Cache file was built for (  powershellstation.com/tag/tools/feed/ ) in 0.60677 seconds, on Feb 5th, 2012 at 3:52 am UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on Feb 6th, 2012 at 3:52 am UTC -->
<!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<!-- Quick Cache Is Fully Functional :-) ... A Quick Cache file was just served for (  powershellstation.com/tag/tools/feed/ ) in 0.00049 seconds, on Feb 5th, 2012 at 9:52 pm UTC. -->
