<?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; Discussion</title>
	<atom:link href="http://powershellstation.com/category/discussion/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>Aggregation In PowerShell (and another pointless function)</title>
		<link>http://powershellstation.com/2011/12/14/aggregation-in-powershell-and-another-pointless-function/</link>
		<comments>http://powershellstation.com/2011/12/14/aggregation-in-powershell-and-another-pointless-function/#comments</comments>
		<pubDate>Wed, 14 Dec 2011 04:37:42 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://powershellstation.com/?p=371</guid>
		<description><![CDATA[I&#8217;ve been doing a lot of thinking about &#8220;idiomatic PowerShell&#8221; since my last post and my thinking led me to an idea that I haven&#8217;t actually used, but seems like the kind of thing that people would do in PowerShell. If I were writing a script that needed to get a &#8220;bunch of things&#8221; from [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been doing a lot of thinking about &#8220;idiomatic PowerShell&#8221; since my <a title="PowerShell’s Problem with Return" href="http://powershellstation.com/2011/08/26/powershell%e2%80%99s-problem-with-return/">last post</a> and my thinking led me to an idea that I haven&#8217;t actually used, but seems like the kind of thing that people would do in PowerShell.</p>
<p>If I were writing a script that needed to get a &#8220;bunch of things&#8221; from somewhere (perhaps several different sources) and return all of them, I might be tempted to do something like this. Please forgive my PowerShell pseudocode:</p>
<pre class="brush: powershell">function get-stuff{
param($parm1 )
    $results=@()
    foreach ($source in $sources){
        $results += ($source | where { $_ -and "Some condition exists"  })
    }
    foreach ($source in $someothersources){
        $results += ($source | where { $_ -and "Some condition exists"  })
    }
 return $results
}</pre>
<p>I&#8217;ve used several permutations of that kind of code using arrays of some sort to collect the results as I go along and eventually return the collection from the function. I&#8217;m not sure that there&#8217;s anything wrong with doing it this way. That is, I&#8217;m not sure that you&#8217;re likely to have issues with doing it this way.</p>
<p>On the other hand, it&#8217;s more idiomatic (i.e more in the style of the PowerShell language) to do something like this (again, pardon the pseudocode):</p>
<pre class="brush: powershell">function get-stuff{
param($parm1 )
    foreach ($source in $sources){
        $source | where { $_ -and "Some condition exists"  }
    }
    foreach ($source in $someothersources){
        $source | where { $_ -and "Some condition exists"  }
    }

}</pre>
<p>All I&#8217;m doing here is sending the output of the inner statements (which are pipelines) to the output stream of the function. Note that there isn&#8217;t any need for anything to accumulate the results into.  Using the output stream makes this function work more like the built-in cmdlets in PowerShell as it won&#8217;t be blocking the pipeline.</p>
<p>The only thing that I have against this code is that it goes against rule #2 that I wrote last time about writing values to the output stream.  I said there that if you were going to write to the output stream, you should explicitly use <strong>write-output</strong>.  We could modify the code above to use <strong>write-output</strong>, but that would involve using parentheses (around the pipelines), messing up the flow of the code, and even blocking the pipeline while the expressions in the parentheses were collected (as an argument to write-output).  </p>
<p>That brings me to what I was saying about &#8220;another pointless function&#8221;.  About a year ago I wrote a <a href="http://powershellstation.com/2010/08/01/the-identity-function/" title="The Identity Function">post</a> about the identity function, which doesn&#8217;t really do anything except return the input.  It is a really useful function for creating lists and such, allowing you to skip on providing a bunch of punctuation.  It&#8217;s not a pointless function, but it&#8217;s not one that is getting much press, either.  I was thinking about how to make the &#8220;pipeline&#8221; version of the code work nicely and not make it ugly and thought of the following function.</p>
<pre class="brush: powershell">
function out-output{
    process{ $_ }
}
</pre>
<p>Like the identity function (or ql, as I&#8217;ve seen it referred to), out-output doesn&#8217;t do anything but emit values that are provided.  Out-output, however, gets its values from the pipeline rather than the argument list.  This function allows us to be explicit about our intent to use the output stream.</p>
<pre class="brush: powershell">function get-stuff{
param($parm1 )
    foreach ($source in $sources){
        $source | where { $_ -and "Some condition exists"  } | out-output
    }
    foreach ($source in $someothersources){
        $source | where { $_ -and "Some condition exists"  } | out-output
    }
}
</pre>
<p>I&#8217;m not sure if this is a good idea, and I know that it&#8217;s just adding a tiny bit of processing to the script.  My thought is that making the operation of the script explicit is worth it in the long run.</p>
<p>What do you think?</p>
<p>-mike</p>
]]></content:encoded>
			<wfw:commentRss>http://powershellstation.com/2011/12/14/aggregation-in-powershell-and-another-pointless-function/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerShell’s Problem with Return</title>
		<link>http://powershellstation.com/2011/08/26/powershell%e2%80%99s-problem-with-return/</link>
		<comments>http://powershellstation.com/2011/08/26/powershell%e2%80%99s-problem-with-return/#comments</comments>
		<pubDate>Fri, 26 Aug 2011 22:29:36 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://powershellstation.com/wordpress/?p=331</guid>
		<description><![CDATA[I think that PowerShell is a fairly readable language, once you’re used to its unique features. Naming functions (cmdlets) with an embedded hyphen, using -eq instead of the equals sign (and similarly for other operators) and not using commas to delimit parameters in a function call (but using them in a method call) are all [...]]]></description>
			<content:encoded><![CDATA[<p>I think that PowerShell is a fairly readable language, once you’re used to its unique features. Naming functions (cmdlets) with an embedded hyphen, using -eq instead of the equals sign (and similarly for other operators) and not using commas to delimit parameters in a function call (but using them in a method call) are all things that you get used to pretty quickly. There is one feature of PowerShell, however, that I don’t think will ever come naturally to me, and that’s how it handles return values from functions.</p>
<p>In most languages, if you see “return 1″ as the only return in a function, you can know that the function is going to the value 1 to the caller. In fact, I’m not sure I’ve ever seen a language that didn’t work that way. That is, until I found PowerShell. Generally speaking, the return statement works just as expected. In the absence of any statements writing to the output stream (with write-output) or “dropping” their values, “return 1″ will cause the caller to receive the value “1″. Using write-output is pretty obvious, and I’d recommend using it explicitly if you intend to add objects to the output stream (thereby including them in the eventual function value). Expressions that don’t capture their return values, however, are not quite so easy to spot.</p>
<p>For example, examine this code to add a parameter to an ADO.NET command object looks fine:</p>
<pre class="brush:powershell">$cmd.Parameters.AddWithValue('@demographics','$demoXML)</pre>
<p>This is a straightforward translation of one of the lines of code in the example code <a href="http://here/">here</a>.  The problem with the code is that AddWithValue not only adds a parameter, it also returns the parameter.  Since we didn’t assign it to a variable, cast it to [void] or pipe it to out-null, the output of this function (AddWithValue) gets added to the output of the function it’s in.</p>
<p>Several “add” functions in the .net framework follow this pattern, either returning the object that was added or the index of that object in the collection.  The DBConnection.Open method (inherited by SQLConnection, among others) returns the opened connection.  I’m sure that with time I could find more examples than I’d feel like sharing.</p>
<p>Another way that I’ve seen the output stream getting messed up is when a function uses strings to output information without using write-host.  For example, this function outputs “progress” information as it goes:</p>
<pre class="brush:powershell">
function get-filelength{
param($filename)
	"reading file"
	$len=0
	$file=get-content $filename
	foreach($line in $file){
	   "adding a line"
	   $len+=$line.length
	}
	return $len
}
</pre>
<p>I realize that this is not the best way to find the length of a file, but it works for the purpose of illustration. If you simply call the function (without assigning it to a variable), you’ll see a bunch of text, followed by the “value” of the function. The “returned value” of the function is clearly intended to be $len, but instead all of the text is included. The type of the function output is Object[], rather than a number.</p>
<p>There are some good reasons to use the output stream in a function (the next post will examine one such use), but it’s very easy to accidentally put something in the stream without intending to. When this happens, it often leads to unexpected results and long debugging sessions.</p>
<p>Here are my recommendations for avoiding this kind of error:</p>
<ol start="1">
<li>Use one of the “write” functions to provide text messages to the user (write-host, write-debug, write-verbose)</li>
<li>Use write-output if your intent is to add something to the output stream</li>
<li>Check msdn to see if the methods you use have output. If you’re looking at the C# version, methods that return void do not need to be “handled”. In the VB.NET version, they’ll be declared as Sub, rather than Function.</li>
<li>Be consistent with how you “handle” methods or functions whose values you want to discard. Options are to cast the result as [void] or pipe it to out-null</li>
<li>If you’re using write-output to put objects in the output stream, use return with no value (i.e., don’t return $val). Seeing a value returned explicitly implies that that is the only value returned.</li>
<li>If all else fails, use write-host to output the type of variables when debugging (or look at their values in the watch window if you’re using an IDE with a debugger).</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://powershellstation.com/2011/08/26/powershell%e2%80%99s-problem-with-return/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Verifying Automation</title>
		<link>http://powershellstation.com/2011/01/06/verifying-automation/</link>
		<comments>http://powershellstation.com/2011/01/06/verifying-automation/#comments</comments>
		<pubDate>Fri, 07 Jan 2011 00:59:16 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[Scheduled Tasks]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://powershellstation.com/?p=317</guid>
		<description><![CDATA[If you&#8217;re anything like me, you&#8217;ve been bitten by the PowerShell bug and are using it among other automation sources to make you life in IT much more enjoyable. If this is not the case&#8230;you need to get started!&#160; There&#8217;s no time like the present, and a PowerShell New Year&#8217;s resolution should be something to [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re anything like me, you&#8217;ve been bitten by the PowerShell bug and are using it among other automation sources to make you life in IT much more enjoyable.  If this is not the case&#8230;you need to get started!&nbsp; There&#8217;s no time like the present, and a PowerShell New Year&#8217;s resolution should be something to consider.</p>
<p>For those of you that are with me in the PowerShell camp, I have something that I&#8217;d like to discuss.&nbsp; You probably have hundreds (dozens?) of scripts scheduled on multiple servers, possibly in multiple domains or geographical locations to perform things like these:</p>
<ul>
<li>Gather information about servers</li>
<li>Generate reports about application usage</li>
<li>Copy information from one place to another</li>
<li>Validate security setup</li>
<li>Start and Stop processes</li>
<li>Scan log files for error conditions</li>
<li>Lots of other things (you get the point)</li>
</ul>
<p>How do you know that the scripts that you have written carefully and scheduled are actually running successfully?&nbsp; At first, this seems like a silly question.&nbsp; When you deployed the script, surely you ran it once to make sure it worked.&nbsp; What could have gone wrong?</p>
<p>Here are some examples that come to mind:</p>
<ul>
<li>A policy was pushed which set the execution policy to Restricted</li>
<li>The credentials you scheduled the script with have been revoked</li>
<li>A file share that the scripts depend on is unavailable</li>
<li>Firewall rules change and now WMI queries aren&#8217;t working</li>
<li>The Task Scheduler service is stopped</li>
</ul>
<p>You can probably think of a lot more examples of things that would keep scripts from working, but you get the idea.&nbsp; I&#8217;ve given some thought to how to do this, but haven&#8217;t come to any real conclusions.&nbsp; Obviously, having your scripts log results is helpful, but only if you monitor the logs for success/failure.&nbsp; Also, if you have a script which is supposed to run every 10 minutes, it doesn&#8217;t help if you don&#8217;t get alerted when it only runs once in a day, even if&nbsp; it runs successfully.&nbsp; Also, if there is more than one person writing scripts, how do you make sure that everyone is using the same techniques to log progress?</p>
<p>Here are some of my thoughts:</p>
<ul>
<li>Use a &#8220;launcher&#8221; to run scripts (see below)</li>
<li>Keep a database of processes with an expected # of runs per day</li>
<li>Monitor matching start/end of scripts</li>
<li>Log all output streams (<a title="example" href="http://www.nivot.org/2009/08/19/PowerShell20AConfigurableAndFlexibleScriptLoggerModule.aspx">example</a>)</li>
</ul>
<p>The first item in the list (the launcher) has been something I&#8217;ve been considering because it&#8217;s not trivial to run a PowerShell script in a scheduled task.&nbsp; Even with the -file parameter which was added in PowerShell 2.0, it can involve a fairly long command-line.&nbsp; With the added difficulty of trying to capture output streams (most of which are not exposed to the command shell) it becomes a process that is almost hard to get right every time.&nbsp; Some features I&#8217;m planning for the launcher are:</p>
<ul>
<li>Load appropriate profiles</li>
<li>Log all output streams (with timestamps) to file or database</li>
<li>Log application start/end times</li>
<li>Email owner of script if there are unhandled exceptions</li>
</ul>
<p>I know this topic is not specific to PowerShell, but as Windows administrators get more used to scripting solutions to their automation problems with PowerShell (which I am confident that they are doing), it&#8217;s something that every organization will need to consider.&nbsp; I&#8217;ll try to follow up with some posts that have some actual code to address some of these points.</p>
<p>Mike</p>
<p>P.S.  I&#8217;m specifically not discussing &#8220;enterprise job scheduling&#8221; solutions like JAMS because of the high cost involved.  I&#8217;d like to see the community come up with something a little more budget-friendly.</p>
]]></content:encoded>
			<wfw:commentRss>http://powershellstation.com/2011/01/06/verifying-automation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Happy (Belated) Anniversary!</title>
		<link>http://powershellstation.com/2010/10/07/happy-belated-anniversary/</link>
		<comments>http://powershellstation.com/2010/10/07/happy-belated-anniversary/#comments</comments>
		<pubDate>Fri, 08 Oct 2010 03:06:50 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://powershellstation.com/?p=309</guid>
		<description><![CDATA[I didn’t manage to post anything on the 1 year anniversary of powershellstation.com, but I did remember.  I was hoping to have posted more, but all in all, it wasn’t a bad year.  I have some plans for this year: Write a post or 2 about remoting Kill off the powershellworkbench project (I can’t stand writing [...]]]></description>
			<content:encoded><![CDATA[<p>I didn’t manage to post anything on the 1 year anniversary of powershellstation.com, but I did remember.  I was hoping to have posted more, but all in all, it wasn’t a bad year.  I have some plans for this year:</p>
<ul>
<li>Write a post or 2 about remoting</li>
<li>Kill off the powershellworkbench project (I can’t stand writing WPF)</li>
<li>Start a new host project using Windows Forms and the Puzzle.SyntaxBox edit control (probably using C#)</li>
<li>Update the Books/Tools/Sites pages (and keep them more or less up to date)</li>
</ul>
<p>I was really hoping that there would be some interest in the powershellworkbench project, but I’ve not heard anything (except for a comment that there were some missing icons).  Since I really didn’t enjoy writing WPF code (I might like it if I did a lot of it, but this is a hobby project), I don’t see much of a future for that project.  I am comfortable with Windows Forms, though, so I’ll be rebooting that project with a new name.  I’m also going to switch to the Puzzle.SyntaxBox control, because I know it will do the things I need to and not get in the way.  I haven’t found a similar component that wasn’t extremely complicated.  My goal with the project is to make something that an administrator with limited time could customize for their environment.  I’m afraid that the complexity of WPF and the Avalon controls would make that improbable at best.</p>
<p>I was also hoping that there would be more feedback.  I’m sure that this is a common frustration among bloggers (especially bloggers in a niche like this), so I’m not going to worry about that.  I am, however, going to make a concerted effort to comment on blogs that I read.  If you have any comments, they are always welcome.  If you have suggestions on topics, I’m open to that, as well.</p>
<p>One final thing.  I’ve been thinking about moving my blog to “<a href="http://www.nosupportlinuxhosting.com/">No Support Linux Hosting</a>”.  I’m not a Linux expert, but they have a WordPress setup tutorial, and you can’t beat $1 per month.  If I do change, I hope I can do it without any disruption, but who knows?</p>
<p>-Mike</p>
]]></content:encoded>
			<wfw:commentRss>http://powershellstation.com/2010/10/07/happy-belated-anniversary/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>Package Management and a PowerShell Bug</title>
		<link>http://powershellstation.com/2010/01/19/package-management-and-a-powershell-bug/</link>
		<comments>http://powershellstation.com/2010/01/19/package-management-and-a-powershell-bug/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 05:41:58 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Package]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Require]]></category>

		<guid isPermaLink="false">http://powershellstation.com/?p=237</guid>
		<description><![CDATA[UPDATE: I have worked out how the behavior described at the end of this post is not a bug, but in fact just PowerShell doing what it&#8217;s told. Don&#8217;t have time to explain right now, but I&#8217;ll write something up later today. I also worked out how to &#8220;fix&#8221; the behavior. For a long time [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE:  I have worked out how the behavior described at the end of this post is not a bug, but in fact just PowerShell doing what it&#8217;s told.  Don&#8217;t have time to explain right now, but I&#8217;ll write something up later today.  I also worked out how to &#8220;fix&#8221; the behavior.</strong></p>
<p>For a long time now, I&#8217;ve been dissatisfied with what I call &#8220;package management&#8221; in PowerShell.  Those of you who know me will be shocked that anything in PowerShell is less than perfect in my eyes, but this is one place that I feel let down.  Modules in 2.0 remedy the situation somewhat, but it still isn&#8217;t quite what I want or am used to in other languages.</p>
<p>Let me give an example.  In VB.NET, if you need to use the functions in an assembly, you put &#8220;Imports AssemblyName&#8221; at the top of your script.  In C#, you would have &#8220;Using AssemblyName&#8221;.  In Python, there would be &#8220;Import Something&#8221;.</p>
<p>In PowerShell 1.0, you had nothing.  In 2.0, you could create a module manifest which would specify either RequiredModules or ScriptsToProcess (or several other things to do upon loading the module).  The problems I see  with using the module manifest are:</p>
<ul>
<li>What if I&#8217;m not writing a module?  There&#8217;s no such thing as a &#8220;script manifest&#8221;</li>
<li>What if the script or module that is required performs some initialization that should only be done once per session?</li>
<li>What if the script or module that is required performs <em>expensive</em> initialization?</li>
</ul>
<p>Because of these reasons (and because I only started using 2.0 when it went RTM) I wrote a couple of quick functions to do what I thought made sense.</p>
<pre class="brush: powershell">
$global:loaded_scripts=@{pkg_utils='INITIAL'}

function require($filename){
	if (!$global:loaded_scripts[$filename]){
	   . scripts:$filename.ps1
	   $global:loaded_scripts[$filename]=get-date
	}
}
function reload($filename){
	. scripts:$filename.ps1
	$global:loaded_scripts[$filename]=get-date
}
</pre>
<p>To use these you need to create a psdrive called scripts: with code like this (probably in your profile):</p>
<pre class="brush:powershell">New-PSdrive -name scripts -PSprovider filesystem -root PathToYourLibraries | Out-Null</pre>
<p>Then, also in your profile, you&#8217;ll want to dot-source the file you put these functions in (for example, package_tools.ps1):</p>
<pre class="brush: powershell">. scripts:package_tools.ps1</pre>
<p>Once you have those set up, you can dot-source the <strong>require</strong> function to make sure that a script has been loaded as such:</p>
<pre class="brush:powershell">. require somelibrary</pre>
<p>I have the functions I use divided by &#8220;subject&#8221; into several library scripts, and make sure that at the top of each script, I use &#8220;. require&#8221; to ensure that any prerequisites are already loaded.</p>
<p>Now for the PowerShell bug (which took me a long time to track down).<br />
Create 2 files, a.ps1 and b.ps1 in your scripts: directory.</p>
<pre class="brush:powershell">
# a.ps1
write-host "this is script a"
</pre>
<pre class="brush: powershell">
#b.ps1
write-host "this is script b"
write-host "this script loads a"
. require a
</pre>
<p>After dot-sourcing package_tools, run the following commands:</p>
<pre class="brush: powershell">
. require b
</pre>
<p>You should get output that looks something like this:</p>
<pre>
this is script b
this script loads a
this is script a
</pre>
<p>Everything looks good until you inspect the $global:loaded_scripts variable:</p>
<pre>
ps> $loaded_scripts

Name                           Value
----                           -----
a                              1/19/2010 11:23:09 PM
package_tools                  INITIAL
</pre>
<p>Although b.ps1 was indeed dot-sourced (you can see the output), and the only code-path through the  require function that would dot-source it would also add an entry to $loaded_scripts, there is no such entry.  The problem is that when b.ps1 called the require function (to load a.ps1), the $filename variable in the calling context (where it should have been &#8220;b&#8221;) was overwritten by the call with &#8220;a&#8221; as a parameter.  Walking through the code in a debugger confirms the problem.</p>
<p>Have you ever seen problems with recursion and dot-sourcing in PowerShell?  Can you see any way around the problem I&#8217;ve described?  For instance, saving the $filename in a variable and restoring it after the dot-source call (line 5 above) doesn&#8217;t help, because the same code-path is followed in the recursive call, and that variable is overwritten as well.</p>
<p>Even with this bug, I find the require function (and reload, which I didn&#8217;t discuss, but always loads the script in question) to be very helpful.  I also have extended them to include importing modules, if they exist.  I&#8217;ll discuss them in my next post, coming soon.</p>
<p>-Mike</p>
<p>P.S.  <a href="http://stackoverflow.com/questions/279974/importing-libraries-in-powershell">Here</a>&#8216;s a question I posted to StackOverflow.com about these functions back in November of 2008.</p>
]]></content:encoded>
			<wfw:commentRss>http://powershellstation.com/2010/01/19/package-management-and-a-powershell-bug/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An Overlooked Parameter</title>
		<link>http://powershellstation.com/2009/11/11/an-overlooked-parameter/</link>
		<comments>http://powershellstation.com/2009/11/11/an-overlooked-parameter/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 17:10:43 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://powershellstation.com/?p=173</guid>
		<description><![CDATA[This isn&#8217;t so much a post as an extended pingback.  This Post by Jeffrey Snover on the PowerShell Team Blog explains how to use the -expandproperty parameter of the select-object cmdlet. I had never noticed that parameter and was also annoyed by writing this all the time: get-something &#124; foreach {$_.SomeProperty} It was an idiom [...]]]></description>
			<content:encoded><![CDATA[<p>This isn&#8217;t so much a post as an extended pingback.  <a title="This post" href="http://blogs.msdn.com/powershell/archive/2009/09/14/select-expandproperty-propertyname.aspx">This Post</a> by Jeffrey Snover on the <a title="PowerShell Team Blog" href="http://blogs.msdn.com/powershell/default.aspx">PowerShell Team Blog</a> explains how to use the -expandproperty parameter of the select-object cmdlet.</p>
<p>I had never noticed that parameter and was also annoyed by writing this all the time:</p>
<pre class="brush: powershell"> get-something | foreach {$_.SomeProperty}</pre>
<p>It was an idiom that I was using a lot that felt like it didn&#8217;t fit.&lt;/p&gt; &lt;p&gt;As he points out, this can be replaced with the non-looping:</p>
<pre class="brush: powershell">get-something | select-object -expandProperty SomeProperty</pre>
<p>It&#8217;s longer if you don&#8217;t use aliases (and prefix-shortened parameternames), but I think it reads a lot better.</p>
<p>Let me know what you think.  Was this a surprise to you, or have you used the -expandProperty parameter before?</p>
<p>Mike</p>
<p>P.S.  You should definitely follow the PowerShell Team Blog&#8230;it is always worthwhile.</p>
]]></content:encoded>
			<wfw:commentRss>http://powershellstation.com/2009/11/11/an-overlooked-parameter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing your own PowerShell Hosting App (Part 1. Introduction)</title>
		<link>http://powershellstation.com/2009/10/12/writing-your-own-powershell-hosting-app-part-1-introduction/</link>
		<comments>http://powershellstation.com/2009/10/12/writing-your-own-powershell-hosting-app-part-1-introduction/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 02:12:51 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[Writing a Host]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[VB.NET]]></category>

		<guid isPermaLink="false">http://powershellstation.com/?p=111</guid>
		<description><![CDATA[I&#8217;ve mentioned before that I use a homegrown PowerShell host in my work.  I have been more than pleasantly surprised at how easy and how rewarding this is.  In the last few weeks, I&#8217;ve seen a few articles that have gotten me thinking about writing a series of blog posts about how to get started. [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve mentioned before that I use a homegrown PowerShell host in my work.  I have been more than pleasantly surprised at how easy and how rewarding this is.  In the last few weeks, I&#8217;ve seen a few articles that have gotten me thinking about writing a series of blog posts about how to get started.</p>
<p>Before actually writing anything, it&#8217;s good to ask yourself&#8230;why in the world would I write a host when there are so many out there already (ISE and PowerGUI are notable free examples)?  This is a really important question and one that will stop most projects in their tracks.  Most people can get what they need using an existing host.  Here are some of the reasons I chose to write  a host:</p>
<ul>
<li>I wanted complete control over the environment, as I knew (hoped) that I would be spending a lot of time using it</li>
<li>I wanted to be able to interact with the environment in ways that the existing tools didn&#8217;t allow</li>
<li>I was constrained to use PowerShell 1.0 (which eliminates the ISE)</li>
</ul>
<p>But probably the most pressing reason in reality was:</p>
<ul>
<li>I had a book (<a title="link" href="http://www.amazon.com/Professional-Windows-PowerShell-Programming-Providers/dp/0470173939/ref=sr_1_3?ie=UTF8&amp;s=books&amp;qid=1255398962&amp;sr=8-3">link</a>) that explained the technology and I wanted to play  <img src='http://powershellstation.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </li>
</ul>
<p>Unlike most (some?) administrators, I have a development background and even have Visual Studio installed on my machine, so testing the waters of writing a host wasn&#8217;t a big investment of time, and the pleasure of seeing something like this come together was well worth it.</p>
<p>Here are the posts that got my mind going again:</p>
<p><a title="Create your own IDE in 10 minutes" href="http://dotnet.org.za/rudi/archive/2009/10/08/create-your-own-ide-in-10-minutes.aspx">Create your own IDE in 10 minutes</a></p>
<p><a title="How to Host PowerShell in a WPF Application" href="http://dougfinke.com/blog/index.php/2009/09/02/how-to-host-powershell-in-a-wpf-application/">How to Host PowerShell in a WPF Application</a></p>
<p>In the next post, I&#8217;ll start the project and give you something to look at.</p>
<p>Let me know if there&#8217;s anything specific you&#8217;d like to see (or have experience implementing).</p>
<p>Mike</p>
]]></content:encoded>
			<wfw:commentRss>http://powershellstation.com/2009/10/12/writing-your-own-powershell-hosting-app-part-1-introduction/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A Handy Trick I&#8217;ve Started to Use a Lot</title>
		<link>http://powershellstation.com/2009/09/20/a-handy-trick-ive-started-to-use-a-lot/</link>
		<comments>http://powershellstation.com/2009/09/20/a-handy-trick-ive-started-to-use-a-lot/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 02:50:32 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[Scripts]]></category>

		<guid isPermaLink="false">http://powershellstation.com/?p=103</guid>
		<description><![CDATA[If you&#8217;re like me, you hate to do the same thing over and over.  That&#8217;s what programming is for, right?  To handle automating tedious procedures?  Unfortunately, it&#8217;s not at all appropriate to run off and build an app every time you need to do the same thing 3 times.  If you try that, you&#8217;ll have [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re like me, you hate to do the same thing over and over.  That&#8217;s what programming is for, right?  To handle automating tedious procedures?  Unfortunately, it&#8217;s not at all appropriate to run off and build an app every time you need to do the same thing 3 times.  If you try that, you&#8217;ll have a lot of chances to write apps,  but probably will be looking for a new job because it takes you way too long to get anything accomplished.</p>
<p>Scripting is the short answer to the dilemma above.  PowerShell is one of the latest entries into the scripting world, and to my tastes, one of the best.</p>
<p>Here&#8217;s something I used several times in the last few days.  I can&#8217;t remember quite where I saw it first, but it was in a PowerShell blog about looping (I think).</p>
<p>Anyway, the problem is that I needed to edit config files on the servers in a farm.  Fortunately, the servers were numbered sequentially.  So, what I wrote was (suitably sanitized for public consumption):</p>
<pre class="brush: powershell; gutter: false">1..9 | % { notepad "server$_c$path_to_config_fileconfig.file" }</pre>
<p>That popped the first 9 files up in notepad, ready to be edited.  The trick is to use the range syntax to create a list of numbers, and use % to loop through them.</p>
<p>If you need a longer range (with leading zeroes, of course), it&#8217;s not too hard.</p>
<pre class="brush: powershell; gutter: false">1..20 | % {notepad ("server{0:D2}c$path_to_config_fileconfig.file" -f $_)}</pre>
<p>Here, we use the format operator with a D2 format spceifier (2 digits, leading zeros).  See <a href="http://www.microsoft.com/technet/scriptcenter/resources/pstips/jul07/pstip0720.mspx">here</a> for more examples of format operators in PowerShell.</p>
<p>When you&#8217;re dealing with dozens of servers, tricks like this can save you a lot of time.</p>
<p>Let me know what you think.  What &#8220;idioms&#8221; in PowerShell do you find yourself using a lot?</p>
<p>Mike</p>
]]></content:encoded>
			<wfw:commentRss>http://powershellstation.com/2009/09/20/a-handy-trick-ive-started-to-use-a-lot/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Is it just me? (Or does PowerShell remind you of SQL?)</title>
		<link>http://powershellstation.com/2009/09/16/is-it-just-me-or-does-powershell-remind-you-of-sql/</link>
		<comments>http://powershellstation.com/2009/09/16/is-it-just-me-or-does-powershell-remind-you-of-sql/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 01:40:39 +0000</pubDate>
		<dc:creator>mike</dc:creator>
				<category><![CDATA[Discussion]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://powershellstation.com/?p=79</guid>
		<description><![CDATA[When preparing a PowerShell training class for a group of DBAs, I realized that there were some parallels between basic SQL and basic PowerShell commands. A (very) basic SQL statement has the form: SELECT &#60;COLUMNS&#62; FROM &#60;TABLE&#62; WHERE &#60;CONDITION&#62; ORDER BY &#60;EXPRESSION&#62; I noticed that a very common idiom for PowerShell pipelines* was: &#60;data source [...]]]></description>
			<content:encoded><![CDATA[<p>When preparing a PowerShell training class for a group of DBAs, I realized that there were some parallels between basic SQL and basic PowerShell commands.</p>
<p>A (very) basic SQL statement has the form:</p>
<pre>SELECT &lt;COLUMNS&gt;
FROM &lt;TABLE&gt;
WHERE &lt;CONDITION&gt;
ORDER BY &lt;EXPRESSION&gt;</pre>
<p>I noticed that a very common idiom for PowerShell pipelines* was:</p>
<pre>&lt;data source cmdlet&gt; | <strong>select-object</strong> &lt;properties&gt; |<strong> where-object</strong> &lt;CONDITION&gt; |  <strong>sort-object</strong> &lt;EXPRESSION&gt;
&nbsp;
</pre>
<p>By &#8220;&lt;data source cmdlet&gt;”, I mean some cmdlet that puts a bunch of objects in the pipeline, like get-childitem, get-process, get-task, etc.</p>
<p>Part of the power of SQL is that it doesn’t matter what kind of data is in the tables, the same form of SQL statement works the same way (predictability).  This is one of the things I love about PowerShell.  It doesn’t matter what kinds of data is returned by a cmdlet.  The same form of PowerShell pipeline* will perform the same kind of predictable operations on it.  I know that this is often mentioned in tutorials and videos about PowerShell, but this was when it really struck me. </p>
<p>A few other SQL/PowerShell comparisons might be:</p>
<table border="0" cellspacing="0" cellpadding="2" width="401">
<tbody>
<tr>
<td width="198" align="center" valign="top">
<p align="center"><strong>SQL</strong></p>
</td>
<td width="201" valign="top">
<p align="center"><strong>PowerShell</strong></p>
</td>
</tr>
<tr>
<td width="198" valign="top">GROUP BY</td>
<td width="201" valign="top">group-object</td>
</tr>
<tr>
<td width="198" valign="top">SUM(), AVG(), etc.</td>
<td width="201" valign="top">measure-object</td>
</tr>
<tr>
<td width="198" valign="top">Cursors</td>
<td width="201" valign="top">foreach-object loops</td>
</tr>
<tr>
<td width="198" valign="top">SELECT DISTINCT</td>
<td width="201" valign="top">select-object –unique</td>
</tr>
<tr>
<td width="198" valign="top">SELECT TOP n</td>
<td width="202" valign="top">select-object –first n</td>
</tr>
</tbody>
</table>
<p> </p>
<p>Obviously, this comparison breaks down pretty quickly.  There isn&#8217;t really a parallel that I can find to JOIN statements, which make SQL so powerful, and clearly there&#8217;s a lot of powershell scripts that don&#8217;t fit the pattern I&#8217;m describing.  I think, though, that it&#8217;s a useful comparison and can help get people &#8220;over the hump&#8221; in their quest to master PowerShell.</p>
<p>Let me know what you think.</p>
<p>Mike</p>
<p>* A Pipeline in PowerShell is a sequence of cmdlets where each takes the output of the previous cmdlet as its input.</p>
]]></content:encoded>
			<wfw:commentRss>http://powershellstation.com/2009/09/16/is-it-just-me-or-does-powershell-remind-you-of-sql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- This Quick Cache file was built for (  powershellstation.com/category/discussion/feed/ ) in 0.24519 seconds, on Feb 5th, 2012 at 10:05 pm UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on Feb 6th, 2012 at 10:05 pm UTC -->
