<?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>Global Knowledge Training Blog &#187; PowerShell</title>
	<atom:link href="http://globalknowledgeblog.com/category/technology/microsoft/powershell-technology/feed/" rel="self" type="application/rss+xml" />
	<link>http://globalknowledgeblog.com</link>
	<description>Your Source for Technical, Professional, &#38; Leadership Training</description>
	<lastBuildDate>Thu, 17 May 2012 17:34:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Renaissance Sculpture – the PowerShell way!</title>
		<link>http://globalknowledgeblog.com/technology/microsoft/renaissance-sculpture-the-powershell-way/</link>
		<comments>http://globalknowledgeblog.com/technology/microsoft/renaissance-sculpture-the-powershell-way/#comments</comments>
		<pubDate>Thu, 15 Mar 2012 12:18:14 +0000</pubDate>
		<dc:creator>Mike Hammond</dc:creator>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://globalknowledgeblog.com/?p=5474</guid>
		<description><![CDATA[PowerShell, like most Microsoft technologies, gives us more than one way to do the same thing. Sometimes that’s good news: it’s nice to use software that can compensate for differences in style from one user to another. Other times, it creates an issue. Sometimes one way to do something is less effective than another — sometimes in subtle ways. The wrong choice might add a few extra seconds to a job that takes a few minutes and many minutes to a job that might take hours. Those small changes add up over time. Which question do you want your boss to ask: “How does she manage to get everything done with time to spare?” or “Why is he always running behind schedule?”]]></description>
			<content:encoded><![CDATA[<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2012/03/david123925756.jpg"><img class="alignright size-full wp-image-5493" title="david123925756" src="http://globalknowledgeblog.com/wp-content/uploads/2012/03/david123925756.jpg" alt="" width="300" height="300" /></a>PowerShell, like most Microsoft technologies, gives us more than one way to do the same thing. Sometimes that’s good news: it’s nice to use software that can compensate for differences in style from one user to another. Other times, it creates an issue.</p>
<p>Sometimes one way to do something is less effective than another — sometimes in subtle ways. The wrong choice might add a few extra seconds to a job that takes a few minutes and many minutes to a job that might take hours. Those small changes add up over time. Which question do you want your boss to ask: “How does she manage to get everything done with time to spare?” or “Why is he always running behind schedule?”</p>
<p>One of PowerShell’s most valuable features is pipelining. Borrowed from UNIX, pipelining allows manipulation of vast amounts of data with elegantly short statements. In one programming statement, data can be retrieved, filtered, sorted, acted upon, reported on, and sent to your inbox. But that great strength masks one of its greatest vulnerabilities. Great quantities of information can be processed quickly. But is it as quickly as it could be?</p>
<p>Consider the following piece of PowerShell code.</p>
<p><span style="font-family: monospace;"> Get-WMIObject Win32_Service | Where-Object {$_.Name –eq “Spooler”} | Start-Service</span></p>
<p>It’s a straightforward piece of code that starts the Print Spooler service. It processes in a <em>fifth</em> of a second — that’s quick! Get the service and start it… simple, right?</p>
<p>Not so fast. Think carefully about what happens in this code. The first segment, before the first pipe, does not retrieve one service — it retrieves <em>all</em> the services. Now, I’ve got 167 services currently present on my laptop (running Windows 8 Consumer Preview, by the way). 167 objects gurgle down the pipeline into Where-Object. That cmdlet takes those 167 objects and produces an output of a grand total of…</p>
<p>…one object — which gets started by <span style="font-family: monospace;">Start-Service</span>.</p>
<p>I’m reminded of a quote attributed to the sculptor Michelangelo.</p>
<p><em>“In every block of marble I see a statue; see it as plainly as though it stood before me, shaped and perfect in attitude and action. I have only to hew away the rough walls that imprison the lovely apparition to reveal it to other eyes, as mine see it.”</em></p>
<p>My call to <span style="font-family: monospace;">Get-WMIObject</span> serves up a big ol’ block o’ marble. 167 services are described by a lot of data. The <span style="font-family: monospace;">Where-Object</span> filter starts ‘hewing away’ pieces from that Statue-of-David-sized block of marble until it gets down to the size of a small figurine, which it puts on the pipeline. What happens to the rest of that unused marble? Jacopo I’Indaco (one of Michelangelo’s underappreciated assistants) sweeps it into a dustpan while sobbing quietly to himself.</p>
<p>Is there a better way? There certainly is. <span style="font-family: monospace;">Get-WMIObject</span> has a <span style="font-family: monospace;">–filter</span> parameter, which allows us to pass a description of what we are interested in to the WMI service. WMI tries to act like a big database of information about a Windows system that you can query — but in reality it isn’t. WMI passes your request to a piece of software called a provider. That’s important because WMI providers — the components that extract the data we need — are specialists in retrieving data from their areas of expertise. They can retrieve data in a fast, targeted way. Here’s a piece of code with identical output, but with a processing time of 120 milliseconds.</p>
<p><span style="font-family: monospace;">Get-WMIObject –filter “Name = ‘Spooler’” | Start-Service</span></p>
<p>What’s the difference? Consider visiting a library. I live in the Chicago area, and the biggest library in the area in the Harold Washington Library Center in downtown Chicago. This massive, ten-story facility circulated 77,000 books in January of this year alone. Imagine visiting the HWLC with a burning need to read a particular book. Unfortunately, you are too shy to ask for help finding it. The good news is that it is still very possible to find your book. All that’s necessary is to check each book, on each shelf, in each stack of shelves, in each row of stacks, on each floor until you find it — or worse, until you get to the top floor and find it isn’t there at all. It’s beyond obvious that you would have saved time by asking a librarian, who with a quick check of an index could have pointed you immediately to the correct floor, stack, and shelf — or else told you not to bother, because the library doesn’t have the title.</p>
<p>The librarian is the <span style="font-family: monospace;">WMI –filter</span> parameter. The underlying provider code that retrieves my list of services has expert knowledge about those services. It can intelligently target the data that I need. That’s handy when finding my one service in a list of 167. It’s an even more valuable when targeting hundreds or even thousands of objects.</p>
<p>By contrast, <span style="font-family: monospace;">Where-Object</span> is the wallflower on the sixth floor of the library still searching for the latest Tom Clancy novel in the horticulture section. While blindfolded. Yeah — he’ll be a while.</p>
<p>Maybe you’re thinking, “big deal, Mike — you saved 80 milliseconds. Don’t spend it all in one place.” But consider the percentage improvement in the speed of that data retrieval (calculated with the very handy <span style="font-family: monospace;">Measure-Command</span> cmdlet, incidentally). Cutting a 200ms job down to 120ms is a savings of 40%! How’d you like to take an hour-long task and cut it down to 36 minutes? Or take something that runs all day and shave off 3 hours? Perhaps more dramatically, isn’t it important to you to make sure that jobs that you hope to complete in 36 minutes don’t take an hour? Here’s how: look for opportunities to filter objects without having to resort to <span style="font-family: monospace;">Where-Object</span>.</p>
<p>I like to think that if Michelangelo were a PowerShell programmer, he’d have said this: <em>“I see a statue in my mind, and… then I buy a statue just like it that somebody else carved. Then I show it to everybody and say that it’s mine. Because that leaves me more time to do things I really care about.”</em></p>
]]></content:encoded>
			<wfw:commentRss>http://globalknowledgeblog.com/technology/microsoft/renaissance-sculpture-the-powershell-way/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scripting Games</title>
		<link>http://globalknowledgeblog.com/technology/microsoft/scripting-games/</link>
		<comments>http://globalknowledgeblog.com/technology/microsoft/scripting-games/#comments</comments>
		<pubDate>Fri, 17 Feb 2012 18:46:20 +0000</pubDate>
		<dc:creator>Mike Hammond</dc:creator>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[scripting games]]></category>

		<guid isPermaLink="false">http://globalknowledgeblog.com/?p=5344</guid>
		<description><![CDATA[I loved my freshman year high school Spanish class. I would have done okay had I been left to my own devices, but by luck, I had two of my best friends sitting on either side of me in that class, and we developed a friendly rivalry over our grades in the class. Competition pushed us to excellence far better than any of us could have pushed ourselves alone. Microsoft has capitalized on that desire to compete in a perennial competition called the Scripting Games. Competitors have a week to submit a solution to the challenge, posting it to www.PoshCode.org, which hosts the competition again this year. Each entry is then evaluated by a panel of judges. Prizes are awarded for the top-scoring scripters in a beginner and advanced division, and additional prizes are awarded randomly to participants, with an increased chance of winning as you participate in greater numbers of challenge events.]]></description>
			<content:encoded><![CDATA[<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/02/blographic010.jpg"><img class="alignright size-full wp-image-3134" title="FoosballTeamwork" src="http://globalknowledgeblog.com/wp-content/uploads/2011/02/blographic010.jpg" alt="" width="250" height="250" /></a>I loved my freshman year high school Spanish class. I’m kind of a grammar nerd, so that came somewhat naturally, and I’d watched The Three Amigos enough times to have a plausible (if corny) accent. I would have done okay had I been left to my own devices, but by luck, I had two of my best friends sitting on either side of me in that class, and we developed a friendly rivalry over our grades in the class. Soon, the teacher had to start taking off partial points for accent marks that weren’t at precise 45-degree angles just to be able to have something for us to improve. Competition pushed us to excellence far better than any of us could have pushed ourselves alone.</p>
<p>Microsoft has capitalized on that desire to compete in a perennial competition called the Scripting Games. Begun in 2006, the Microsoft Scripting Games presents scripters with a series of challenges calling for PowerShell script solutions (the 2006 competition sported a VBScript division, as well.) Competitors have a week to submit a solution to the challenge, posting it to <a href="http://www.poshcode.org/">www.PoshCode.org</a>, which hosts the competition again this year. Each entry is then evaluated by a panel of judges. Prizes are awarded for the top-scoring scripters in a beginner and advanced division, and additional prizes are awarded randomly to participants, with an increased chance of winning as you participate in greater numbers of challenge events.</p>
<p>Points are awarded not only for the basic functionality of the script but for real-world criteria such as reusability, documentation, and adherence to good coding practices. Maybe there are people out there who like writing documentation — I’m not among them. But would I do it to win a shot at an e-book from O’Reilly or a full version of PowerGUI? You bet. Last year’s grand prize winner got a free admission to TechEd and a personal phone call from the inventor of PowerShell, Mr. Jeffrey Snover. Not everybody gets to say, “Here’s what I told Jeffrey Snover that I want to see in PowerShell 3.0…” you know?</p>
<p>The Games officially begin on April 2, and details are available at the <a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/02/04/the-2012-windows-powershell-scripting-games-all-links-on-one-page.aspx">All Links On One Page document </a>posted here. The Games are managed once again by Ed Wilson, who holds the official title of Microsoft Scripting Guy. He posts PowerShell tips and tricks daily (!) to the <a href="http://blogs.technet.com/b/heyscriptingguy/archive/2012/02/04/the-2012-windows-powershell-scripting-games-all-links-on-one-page.aspx">Hey, Scripting Guy blog</a>. It’s via this blog that the Scripting Games challenges will be announced, so that’s another great reason to subscribe to that blog. The Scripting Guy has somehow convinced his bride to participate in the games again this year, so you’ll see her on the leaderboard as ScriptingWife. <a href="http://blogs.technet.com/b/heyscriptingguy/archive/tags/windows+powershell/scripting+wife/">The Scripting Wife has her own blog</a>, focused on those who are new to PowerShell-based scripting.</p>
<p>The spirit of competition brings out the best in good competitors; join the fun in the 2012 Microsoft Scripting Games, and I’ll race you to the top!  ¡Vámanos!</p>
<p><a href="http://blogs.technet.com/heyscriptingguy/archive/tags/2012+Scripting+Games/default.aspx"><img style="display: block; margin: 0px auto; border-width: 0px;" src="http://blogs.technet.com/resized-image.ashx/__size/150x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8203.hsg_2D00_2_2D00_4_2D00_12_2D00_1.png" alt="2012 Scripting Games" /></a></p>
<p style="font-size: 80%; text-align: center; margin: 0px;"><a title="2012 Scripting Games--Grab this badge here!" href="http://blogs.technet.com/resized-image.ashx/__size/150x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-76-18/8203.hsg_2D00_2_2D00_4_2D00_12_2D00_1.png">Grab this badge here!</a></p>
<p> </p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://globalknowledgeblog.com/technology/microsoft/scripting-games/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerShell Makes You an Expert Cab Driver!</title>
		<link>http://globalknowledgeblog.com/technology/microsoft/powershell-makes-you-an-expert-cab-driver/</link>
		<comments>http://globalknowledgeblog.com/technology/microsoft/powershell-makes-you-an-expert-cab-driver/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 13:58:40 +0000</pubDate>
		<dc:creator>Mike Hammond</dc:creator>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://globalknowledgeblog.com/?p=5001</guid>
		<description><![CDATA[Microsoft just released the second CTP (that’s Community Technology Previews) of the forthcoming PowerShell 3.0. The version that comes on your Windows 7 clients and your Windows Server 2008 R2 servers is the 2.0 release, so Microsoft is giving the PowerShell community an opportunity to kick the tires on the new version before it goes prime-time. There are some great new features in there, but some of them make me worry that I may soon need to turn in a job application at AAA A1 Taxi Company.]]></description>
			<content:encoded><![CDATA[<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/12/taxi83386337.jpg"><img class="alignright size-full wp-image-5102" title="taxi83386337" src="http://globalknowledgeblog.com/wp-content/uploads/2011/12/taxi83386337.jpg" alt="" width="300" height="300" /></a>I travel a good bit for work, and I noticed a strange trend lately. Has anybody other than me noticed that more cab drivers don’t seem to know where they’re going? Now, don’t get me wrong; I mean that in the nicest possible way. Cab drivers are regular folk, just out there trying to earn a living, after all. So why am I picking on them? It’s because I remember a day, not too long in the past, when a cab driver could be counted on to perform a valuable service – namely, take you to any destination you could name. And (call me crazy) it seems to me that this is changing, for better or worse.</p>
<p>I flew to Atlanta a few months back and made my way to the taxi stand. Settling into my seat, I half-heard something from the front seat that I presumed was equivalent to, “Where to, Mac?” I named my hotel and the street. The driver started to pull away from the curb, but in seconds pulled back over to the curb and stopped. He visibly thought about something and then, wordlessly, he grabbed and handed to me… his GPS receiver. It was up to me to key in the location I wanted to go.</p>
<p>Maybe I’m all alone in this, but I find this terribly <em>strange</em>. I would think that one of the first things they teach you in cabbie school is where all the hotels are and how to get to them — right after the part about collecting money from the customer, and maybe right before the bit about being polite and friendly.  I always presumed that one of the things that a cab driver brings to the table in any transaction is <em>knowledge of the local area, </em>you know?</p>
<p>Maybe I’m just showing my age.</p>
<p>What does all this have to do with PowerShell? Glad you asked. Microsoft just released the second CTP (that’s Community Technology Previews) of the forthcoming PowerShell 3.0. The version that comes on your Windows 7 clients and your Windows Server 2008 R2 servers is the 2.0 release, so Microsoft is giving the PowerShell community an opportunity to kick the tires on the new version before it goes prime-time. There are some great new features in there, but some of them make me worry that I may soon need to turn in a job application at AAA A1 Taxi Company.</p>
<h3>Automatic Module Imports</h3>
<p>Historically, PowerShell required its users to manually direct the shell to add new modules of functionality. <strong>Import-Module</strong> is part of the PowerShell core cmdlets for precisely that purpose. This allows PowerShell (for performance reasons) to start up with the minimally necessary set of features to be useful while allowing the user to add the modules that contain the functionality needed for specialized tasks.</p>
<p>PowerShell 3.0 is going to remove that requirement. You will now be able to invoke any cmdlets, and, if the corresponding module isn’t imported, PowerShell will import it on your behalf! To activate this feature requires the use of the PSModuleAutoLoadingPreference variable — so it is possible to turn it off or require the intended user of a module to name the module <em>and</em> the cmdlet in order to invoke the cmdlet.</p>
<h3>Tab-completed Enumerations</h3>
<p>Another nice feature is an extension to PowerShell’s tab-completion capabilities. PowerShell already supports the ability to press the Tab key to ask PowerShell to fill in the remainder of a lengthy cmdlet name or the name of a parameter. PowerShell users have long been able, for example, to type <strong>Get-ADFin&lt;tab&gt;</strong> and see the cmdlet name completed to <strong>Get-ADFineGrainedPasswordPolicy</strong> or to type <strong>Write-Host –Fore&lt;tab&gt;</strong> and see the parameter expand to <strong>–ForegroundColor</strong>. PowerShell 3.0 will go beyond that to incorporate tab completion on Enumerations.</p>
<p>Enumerations are sets of values available to PowerShell that are managed in a collection. Specifically, enumerations are a listing of constant values, each referenced by a name. You’ve used enumerations, perhaps without knowing it, when using certain parameters that require you to supply one of a constrained list of values. Consider calling <strong>Set-ExecutionPolicy</strong>, which can take parameters like Restricted, Unrestricted, RemoteSigned, and others. Or consider the <strong>ForegroundColor</strong> parameter to <strong>Write-Host</strong> that I just mentioned, which takes parameters of Red, Green, Cyan (but not <em>Blue</em>). Both of these parameters can accept only a particular set of predefined values. And, thanks to PowerShell 3.0, I can fill them in with tab completion! Under PowerShell 3.0, I can type <strong>Set-ExecutionPolicy Un&lt;tab&gt; </strong>and see it fill in <strong>Unrestricted</strong>. I can type <strong>Write-H&lt;tab&gt; </strong> <strong>–F&lt;tab&gt; M&lt;tab&gt; </strong>and see it expand that text out to <strong>Write-Host –ForegroundColor Magenta</strong>. That’s a savings of about twenty keystrokes!</p>
<p>Not that I’ll be using magenta for any of my text, of course — maybe a nice, responsible DarkCyan. But I can save some keystrokes when doing either and still create nice readable code!</p>
<h3>Getting Your PowerShell Hack License</h3>
<p>Be careful with these new tools. Remember that with great PowerShell comes great responsibility! Remember that just because you have the ability to name a cmdlet and see PowerShell launch it for you doesn’t mean that you shouldn’t be busily studying your lists of modules and which cmdlets are provided by each. Just as I fear for the day when I need a cab and solar flares have knocked out the GPS system, I worry that my dear readers may find themselves needing a key cmdlet on a computer that has not been upgraded to PowerShell 3.0 and find themselves as lost as that one Atlanta cab driver. Stay familiar with your local terrain. Know how to find your way around even when these clever shortcuts fail you. Don’t let these handy features blunt your knowledge of how PowerShell actually works, or perhaps it’ll be <em>your</em> voice I hear calling “Where to, Mac” from the front seat of my cab!</p>
]]></content:encoded>
			<wfw:commentRss>http://globalknowledgeblog.com/technology/microsoft/powershell-makes-you-an-expert-cab-driver/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>And At Long Last – Square Pegs in Round Holes</title>
		<link>http://globalknowledgeblog.com/technology/microsoft/and-at-long-last-%e2%80%93-square-pegs-in-round-holes/</link>
		<comments>http://globalknowledgeblog.com/technology/microsoft/and-at-long-last-%e2%80%93-square-pegs-in-round-holes/#comments</comments>
		<pubDate>Tue, 01 Nov 2011 12:42:29 +0000</pubDate>
		<dc:creator>Mike Hammond</dc:creator>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://globalknowledgeblog.com/?p=4827</guid>
		<description><![CDATA[Let’s review what we’ve seen about PowerShell pipeline behavior before we get to the grand finale of this extended discussion.]]></description>
			<content:encoded><![CDATA[<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/10/squarepeg3.jpg"><img class="alignright size-full wp-image-4836" title="squarepeg3" src="http://globalknowledgeblog.com/wp-content/uploads/2011/10/squarepeg3.jpg" alt="" width="300" height="300" /></a>Let’s review what we’ve seen about PowerShell pipeline behavior before we get to the grand finale of this extended discussion.</p>
<ol>
<li>Many cmdlets accept pipeline input ‘ByValue’, meaning that they can consume whole objects of a given type. You can look at the datatype associated with the -<strong>InputObject</strong> parameter of a cmdlet to figure out which type of object is ‘eaten’ by that cmdlet (the ‘INPUTS’ section of the <strong>–full</strong> version of a cmdlet’s help file gives you an even better idea).</li>
<li>Most cmdlets also have other parameters that accept pipeline input but with a twist: these parameters aren’t looking for specific <em>types </em>of objects, but instead they expect to find incoming objects which contain a property that has the same name as that parameter. So the <strong>–name</strong> parameter of the <strong>Get-Process</strong> cmdlet hopes incoming objects have a <strong>name </strong>property.</li>
</ol>
<p>These abilities provide rich pipelining functionality. I can pipe many kinds of cmdlet output to many other cmdlets and have a very good intuition that the pipelining will work the way I expect. Until, of course, the time when it doesn’t (cue ominous music here…)</p>
<p>So what happens when I have output from one cmdlet that I want to feed to a second cmdlet, and neither of the above scenarios is applicable? For example, <strong>Get-Foo </strong>produces objects of type <strong>System.GKTrainingRocks.Foo</strong>, and <strong>Set-Bar</strong> expects input objects to be of type <strong>System.GKTrainingRocks.Bar</strong> (those are all imaginary, by the way — I’ve been hanging around UNIX users too much). Worse, what if none of the names of the properties of the output match the names of the parameters on the next cmdlet in the pipeline? Crazy talk? Actually, no.</p>
<p>Just imagine: while you busily plan your company’s upgrade to SQL Server codename “Denali”, your boss drops by your desk and wants a list of all the services running on all the corporate print servers. The PowerShell portion of your brain wakes up and starts spinning its wheels: “Hmm, listing services — there’s <strong>Get-Service </strong>for that — okay — how about getting a list of computers — I could query Active Directory for those — <strong>Get-ADComputer</strong> sounds about right — maybe I can hook those two cmdlets together…”</p>
<p>So you try to make it work with something like this: <strong>Get-ADComputer –filter {Name –like “PrintServer*”} | Get-Service</strong></p>
<p>Eagerly anticipating success, your mouth drops open when you see a list of errors:</p>
<p><span style="color: red;"><strong>Get-Service : Cannot validate argument on parameter ‘ComputerName’.  The argument is null, empty, or an element of the argument collection contains a null value.  Supply a collection that does not.….</strong></span></p>
<p>NOOOOOOOOOOOOOOOOOOOOOO!</p>
<p>What went wrong? Let’s take each of our main pipelining scenarios one at a time.</p>
<p>What kind of object does <strong>Get-ADComputer </strong>generate? Check the help file (or simply retrieve a computer object using the cmdlet and pipe it to <strong>Get-Member</strong>). Here’s the help-file snippet (using <strong>Get-Help Get-ADComputer –full</strong>).</p>
<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/10/ScreenShot1.bmp"><img class="aligncenter size-full wp-image-4828" title="ScreenShot1" src="http://globalknowledgeblog.com/wp-content/uploads/2011/10/ScreenShot1.bmp" alt="" width="599" height="196" /></a></p>
<p>It produces<strong> Microsoft.ActiveDirectory.Management.ADUser</strong> objects. So far so good. Next question: what kind of objects does <strong>Get-Service </strong>accept as input on the pipeline?</p>
<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/10/ScreenShot2.bmp"><img class="aligncenter size-full wp-image-4829" title="ScreenShot2" src="http://globalknowledgeblog.com/wp-content/uploads/2011/10/ScreenShot2.bmp" alt="" width="597" height="154" /></a></p>
<p>Aha! <strong>Get-Service</strong> expects <strong>System.ServiceProcess.ServiceController</strong> objects. It has no clue what to do with a <strong>Microsoft.ActiveDirectory.Management.ADUser.</strong></p>
<p>No need to panic yet — it’s time to try plan B. Does <strong>Get-Service</strong> allow pipeline interaction with objects using parameters that have names I can find on my incoming <strong>ADUser</strong> objects? Remarkably enough, yes it does! There’s a <strong>Name </strong>property on my ADUser object — that’s the name of the computer I got from AD. And there’s a <strong>–name</strong> parameter on <strong>Get-Service</strong> and it…</p>
<p>Uh oh. That’s not good. The <strong>–name </strong>parameter for <strong>Get-Service</strong> wants the name of the <em>service</em> about which I want to retrieve data — not the name of the <em>computer</em> from which I want to get it. What does <strong>Get-Service</strong> use to identify the target computer? There it is — it’s the –<strong>computername </strong>parameter. That creates a challenge. I can’t use the <strong>Name</strong> property of my object because it doesn’t mean the same thing as the <strong>–name</strong> property of the cmdlet. I can’t use the <strong>–computername </strong>parameter of the cmdlet because I don’t have a matching <strong>ComputerName </strong>property  on my <strong>ADUser</strong> object. I’ve got a square peg and a round hole. Now what do I do?</p>
<p>Our essential problem is the name mismatch. If there was a way to take an incoming <strong>ADUser</strong> object with its underloved <strong>Name </strong>property and <em>rename</em> it to have the name <strong>ComputerName</strong> instead, we could do well. It turns out there’s a way to do that, and the help comes from an unlikely place — the humble <strong>Select-Object</strong> cmdlet.</p>
<p>A little noticed part of the help file for <strong>Select-Object</strong> reads like this:<br /> <span style="font-family: monospace;"><br /> –Property &lt;Object[]&gt;</span></p>
<p><span style="font-family: monospace;">Specifies the properties to select. Wildcards are permitted.</span></p>
<p><span style="font-family: monospace;">The value of the Property parameter can be a new calculated property. To create a calculated property, use a hash table. Valid keys are:</span></p>
<p><span style="font-family: monospace;">– Name (or Label) &lt;string&gt;</span></p>
<p><span style="font-family: monospace;">– Expression &lt;string&gt; or &lt;script block&gt;<br /> </span><br /> What does this mean to us? In short, it means we can relabel a property of an object with a new name. The technique requires a <em>hashtable</em>, an unordered list of pairs of values. This particular hash table identifies the <em>Label</em> on our new property, as well as an <em>Expression</em> that describes the value that the new property is to have. So:</p>
<p><strong>Select-Object –Property @{Label=”ComputerName”;Expression=”$_.Name”}</strong></p>
<p>This piece of code can receive an object with a <strong>Name</strong> property and emit an object that has a <strong>ComputerName </strong>property instead! If we squeeze that in between a <strong>Get-ADComputer</strong> and a <strong>Get-Service</strong>, we should be all set! Our finished square-peg/round-hole solution looks like this:</p>
<p><strong>Get-ADComputer –filter {Name –like “PrintServer*”} | Select-Object –Property @{Label=”ComputerName”;Expression=”$_.Name”} | Get-Service</strong></p>
<p>PowerShell is optimized to allow many predictable, common-sense cmdlet interactions to happen automatically. A great many day-to-day tasks are accounted for in the design of PowerShell’s constellation of cmdlets. It’s comforting to know that even when the default behavior of our favorite cmdlets doesn’t allow for our desired results, we can add just a little bit of code to assemble the pieces into a satisfying solution.</p>
 <div class=’series_links’> </div><div class=’series_toc’><h3>Fitting Square Pegs in Round Holes with PowerShell 2.0 Series</h3><ul><li><a href='http://globalknowledgeblog.com/technology/microsoft/powershell-2-0-fits-square-pegs-in-round-holes/' title='PowerShell 2.0 Fits Square Pegs in Round Holes'>PowerShell 2.0 Fits Square Pegs in Round Holes</a></li><li><a href='http://globalknowledgeblog.com/technology/microsoft/putting-square-pegs-in-square-holes-with-powershell-2-0/' title='Putting Square Pegs in Square Holes with PowerShell 2.0'>Putting Square Pegs in Square Holes with PowerShell 2.0</a></li><li>And At Long Last – Square Pegs in Round Holes</li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://globalknowledgeblog.com/technology/microsoft/and-at-long-last-%e2%80%93-square-pegs-in-round-holes/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>More Square (and Not-so-Square) PowerShell 2.0 Holes</title>
		<link>http://globalknowledgeblog.com/technology/microsoft/more-square-and-not-so-square-powershell-2-0-holes/</link>
		<comments>http://globalknowledgeblog.com/technology/microsoft/more-square-and-not-so-square-powershell-2-0-holes/#comments</comments>
		<pubDate>Fri, 16 Sep 2011 12:16:25 +0000</pubDate>
		<dc:creator>Mike Hammond</dc:creator>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://globalknowledgeblog.com/?p=4437</guid>
		<description><![CDATA[As you look at the help file for your favorite cmdlets, you’ll notice (if you’re using –full) that many of the parameters of those cmdlets provide support for pipeline input. Most of them, though, don’t accept pipeline input “ByValue” – they accept it “ByPropertyName”. This means that when an object is passed to this cmdlet on the pipeline, a “ByPropertyName” parameter of the cmdlet watches that incoming object to see if the object has a property with the exact same name as that parameter. If there’s an exact match, the value of that object’s property is applied to that parameter. Hoo, boy. Example time.]]></description>
			<content:encoded><![CDATA[<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/08/squarepeg95615108.jpg"><img class="alignright size-full wp-image-4450" title="squarepeg95615108" src="http://globalknowledgeblog.com/wp-content/uploads/2011/08/squarepeg95615108.jpg" alt="" width="300" height="300" /></a>As you look at the help file for your favorite cmdlets, you’ll notice (if you use <strong>–full</strong>) that many of the parameters of those cmdlets provide support for pipeline input. Most of them, though, don’t accept pipeline input “ByValue” — they accept it “ByPropertyName”. This means that when an object is passed to this cmdlet on the pipeline, a “ByPropertyName” parameter of the cmdlet watches that incoming object to see if the object has a property with the exact same name as that parameter. If there’s an exact match, the value of that object’s property is applied to that parameter. Hoo, boy. Example time.</p>
<p>Imagine I wrote a PowerShell function that produces objects of my own design. My objects are of type PSObject (which is to say, they are generic). My objects represent students in my classroom, and they have the following properties: Name, StudentID, and EyeColor. If I invoke that function (let’s call it <strong>Get-Student</strong>), it will generate a list of student objects and put them on the pipeline. Left unattended, those will travel down the pipeline, find nothing else to do, and get written out to the screen. But what if I pipe those objects somewhere? What if I said, for example, <strong>Get-Student | Restart-Service</strong>? Sounds ridiculous, and, yeah — you’re right about that. Just go with me for a minute…</p>
<p>What happens when those student objects hit <strong>Restart-Service</strong>? The <strong>–InputObject</strong> parameter looks up to see if what’s coming is a System.ServiceProcess.ServiceController. It’s not, and that parameter goes back to sleep. Then the <strong>–Name</strong> parameter wakes up, and looks to see if the incoming object has a Name property. It does, and so this parameter <em>binds</em> to the value in the name property. <strong>Restart-Service</strong> will try to restart a service that has the same name as one of my students. It’s not likely to work (unless I’ve got a student whose name is Browser or FontCache), but nonetheless, the pipeline is assuming that I know what I’m doing.</p>
<p>What does this mean? It means I can write code that produces objects that have properties that match the names of parameters of cmdlets that I want to work with. I can then pass those objects to cmdlets that expect objects with that matching set of properties. So maybe this isn’t an example of a square peg in a square hole, but of an octagonal peg in an octagonal hole.</p>
]]></content:encoded>
			<wfw:commentRss>http://globalknowledgeblog.com/technology/microsoft/more-square-and-not-so-square-powershell-2-0-holes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Putting Square Pegs in Square Holes with PowerShell 2.0</title>
		<link>http://globalknowledgeblog.com/technology/microsoft/putting-square-pegs-in-square-holes-with-powershell-2-0/</link>
		<comments>http://globalknowledgeblog.com/technology/microsoft/putting-square-pegs-in-square-holes-with-powershell-2-0/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 12:08:43 +0000</pubDate>
		<dc:creator>Mike Hammond</dc:creator>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://globalknowledgeblog.com/?p=4433</guid>
		<description><![CDATA[So you’ve got a Service object in your hands – maybe you ran something like Get-Service “Print Spooler”. So now what? Well, one logical thing to do might be to restart that service (perhaps to fix a stuck print queue). There’s a cmdlet for that, called Restart-Service. The principle of pipelining says that I should be able to just feed the Print Spooler service object to the Restart-Service cmdlet. It turns out that works. ]]></description>
			<content:encoded><![CDATA[<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/08/squarehole95615108.jpg"><img class="alignright size-full wp-image-4443" title="squarehole95615108" src="http://globalknowledgeblog.com/wp-content/uploads/2011/08/squarehole95615108.jpg" alt="" width="150" height="150" /></a><strong><em></em></strong>So you’ve got a Service object in your hands — maybe you ran something like <strong>Get-Service “Print Spooler”. </strong></p>
<p>So now what? Well, one logical thing to do might be to restart that service (perhaps to fix a stuck print queue).</p>
<p>There’s a cmdlet for that, called <strong>Restart-Service</strong>. The principle of pipelining says that I should be able to just feed the Print Spooler service object to the <strong>Restart-Service</strong> cmdlet.</p>
<p>It turns out that works. I can simply do this:</p>
<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/08/Screen-Shot-2.jpg"><img class="aligncenter size-full wp-image-4434" title="Screen Shot 2" src="http://globalknowledgeblog.com/wp-content/uploads/2011/08/Screen-Shot-2.jpg" alt="" width="598" height="384" /></a></p>
<p>Note the use of the <strong>–force</strong>; this service has dependent services, so PowerShell wants to know that you are REALLY sure of what you are doing.</p>
<p>So how did that work? How did <strong>Restart-Service</strong> know what to do with the incoming Print Spooler service? It helps to take a close look at the help file for <strong>Restart-Service.  </strong>Have a look:</p>
<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/08/Screen-Shot-3.jpg"><img class="aligncenter size-full wp-image-4435" title="Screen Shot 3" src="http://globalknowledgeblog.com/wp-content/uploads/2011/08/Screen-Shot-3.jpg" alt="" width="599" height="385" /></a></p>
<p>Take a close look at the data type named for the <strong>–InputObject</strong> parameter of <strong>Restart-Service. </strong>It’s looking for objects of the “ServiceController” type. That should ring a bell for you — that’s the same type of object that I get from my call to <strong>Get-Service</strong>. So far, so good, but how does PowerShell know to associate an incoming ServiceController object with the <strong>–InputObject</strong> parameter? Take another look at the help file (using the <strong>–full switch</strong>) for <strong>Restart-Service</strong>:</p>
<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/08/Screen-Shot-4.jpg"><img class="aligncenter size-full wp-image-4436" title="Screen Shot 4" src="http://globalknowledgeblog.com/wp-content/uploads/2011/08/Screen-Shot-4.jpg" alt="" width="589" height="144" /></a></p>
<p>Note that the <strong>–InputObject</strong> parameter is designed to accept pipeline input — it WANTS to find data on the pipeline that it can work with. Specifically, <strong>–InputObject</strong> accepts pipeline input “ByValue” or, in other words, it consumes the entire incoming object whole. This is the mechanism by which PowerShell feeds the incoming service from the call to <strong>Get-Service</strong> (Print Spooler in my example) as an input to <strong>Restart-Service</strong>.</p>
 <div class=’series_links’> </div><div class=’series_toc’><h3>Fitting Square Pegs in Round Holes with PowerShell 2.0 Series</h3><ul><li><a href='http://globalknowledgeblog.com/technology/microsoft/powershell-2-0-fits-square-pegs-in-round-holes/' title='PowerShell 2.0 Fits Square Pegs in Round Holes'>PowerShell 2.0 Fits Square Pegs in Round Holes</a></li><li>Putting Square Pegs in Square Holes with PowerShell 2.0</li><li><a href='http://globalknowledgeblog.com/technology/microsoft/and-at-long-last-%e2%80%93-square-pegs-in-round-holes/' title='And At Long Last – Square Pegs in Round Holes'>And At Long Last – Square Pegs in Round Holes</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://globalknowledgeblog.com/technology/microsoft/putting-square-pegs-in-square-holes-with-powershell-2-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerShell 2.0 Fits Square Pegs in Round Holes</title>
		<link>http://globalknowledgeblog.com/technology/microsoft/powershell-2-0-fits-square-pegs-in-round-holes/</link>
		<comments>http://globalknowledgeblog.com/technology/microsoft/powershell-2-0-fits-square-pegs-in-round-holes/#comments</comments>
		<pubDate>Thu, 25 Aug 2011 12:52:59 +0000</pubDate>
		<dc:creator>Mike Hammond</dc:creator>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://globalknowledgeblog.com/?p=4420</guid>
		<description><![CDATA[PowerShell 2.0 embraces and extends an old idea in command-line administration — the pipeline. Understanding what can be done with this powerful feature is a key to being effective in the new, bold world of command-line administration of Windows systems.]]></description>
			<content:encoded><![CDATA[<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/08/squarepegroundhole120984241.jpg"><img class="alignright size-full wp-image-4421" title="squarepegroundhole120984241" src="http://globalknowledgeblog.com/wp-content/uploads/2011/08/squarepegroundhole120984241.jpg" alt="" width="300" height="300" /></a>PowerShell 2.0 embraces and extends an old idea in command-line administration — the pipeline. Understanding what can be done with this powerful feature is a key to being effective in the new, bold world of command-line administration of Windows systems.</p>
<p>The pipeline is not a new idea. Douglas McIlroy is a mathematician and programmer who noticed, back in the 70s, that the output of one command in Unix often became the input for the next. He put forward the idea of a “pipe” to send the output of one program directly to the input of another, skipping the step of saving that output in a file of some sort. A few years later in 1973, Unix co-creator Ken Thompson added the feature to Unix.</p>
<p><strong>Pipeline Limits = Tool Development</strong></p>
<p>One key limitation of the Unix pipeline (and of the CMD.EXE pipeline that eventually followed in DOS and Windows) was that it was only passing text from one command to the other. In other words, it wasn’t much more sophisticated than writing all the output to a file and reading it back in to give it to the next application. What the receiving program received was a tsunami of text. This led to the development of tools like grep, awk, sed, and Perl as ways to manipulate that big block of text to produce meaningful output to feed to that next program. This has been a workable approach for Unix users for generations now. Microsoft has taken a totally different approach with PowerShell, however. PowerShell’s pipeline isn’t passing plain text, it’s passing Objects.</p>
<p><strong>Objects and You</strong></p>
<p>Objects, in programmer-speak, are a software representation of a real-world thing. Real objects have properties: my pen has a certain quantity of ink in it; my computer has a screen with a certain number of inches in diagonal size. Real objects also usually support tasks we can perform on them: my car has a GoFaster and TurnLeft method (hey, I could be a NASCAR driver!). Programming objects represent a real-world thing using a set of properties and a set of methods that replicate the information and tasks that are relevant to using that thing in the real world. Applying that to computer technology, consider the idea of a Windows service. It’s a piece of software that runs in the background and allows your computer to perform some sort of functionality. What kinds of information do you want to know about a service? Things like the name of the service, the name of the executable it’s running, whether it’s stopped or started… things like that. What kinds of tasks do I need to perform to administer services? Well, I’d need to stop and start services, mostly. I might need to change the start mode from Automatic to Manual.</p>
<p>PowerShell represents the idea of a Windows service using an object. When I call on the <strong>Get-Service</strong> cmdlet to give me a list of services, what I get is actually a list of <em>objects</em> that represent those services. How do I know what kind of objects? I can pipe those objects to <strong>Get-Member</strong> and it will tell me all about it, like so: (and don’t forget, you can click on these images to see them at full size!)</p>
<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/08/Screen-Shot-1.jpg"><img class="aligncenter size-full wp-image-4432" title="Screen Shot 1" src="http://globalknowledgeblog.com/wp-content/uploads/2011/08/Screen-Shot-1.jpg" alt="" width="598" height="385" /></a></p>
<p>So a service is an instance of a System.ServiceProcess.ServiceController object. What’s that? Remember that PowerShell is built on top of the .Net Framework, a large base of code for Windows application developers. .Net provides a vast list of types of objects that can be used to assemble programs, and they all have lengthy names like that one. Long story short, “ServiceController”  objects are .Net’s way (and therefore PowerShell’s way) of describing services.</p>
 <div class=’series_links’> </div><div class=’series_toc’><h3>Fitting Square Pegs in Round Holes with PowerShell 2.0 Series</h3><ul><li>PowerShell 2.0 Fits Square Pegs in Round Holes</li><li><a href='http://globalknowledgeblog.com/technology/microsoft/putting-square-pegs-in-square-holes-with-powershell-2-0/' title='Putting Square Pegs in Square Holes with PowerShell 2.0'>Putting Square Pegs in Square Holes with PowerShell 2.0</a></li><li><a href='http://globalknowledgeblog.com/technology/microsoft/and-at-long-last-%e2%80%93-square-pegs-in-round-holes/' title='And At Long Last – Square Pegs in Round Holes'>And At Long Last – Square Pegs in Round Holes</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://globalknowledgeblog.com/technology/microsoft/powershell-2-0-fits-square-pegs-in-round-holes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PowerShell 2.0 Protects You From Viruses!</title>
		<link>http://globalknowledgeblog.com/technology/security/powershell-2-0-protects-you-from-viruses/</link>
		<comments>http://globalknowledgeblog.com/technology/security/powershell-2-0-protects-you-from-viruses/#comments</comments>
		<pubDate>Mon, 18 Jul 2011 12:05:17 +0000</pubDate>
		<dc:creator>Mike Hammond</dc:creator>
				<category><![CDATA[Malware]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://globalknowledgeblog.com/?p=4093</guid>
		<description><![CDATA[Virus protection? PowerShell? Well… sort of.

An old Internet joke from way back involves the so-called Amish Virus. ‘Infection’ by the Amish Virus can be diagnosed when you open an email and see this:
<p style="text-align: center;"><strong>Thou hast just received the Amish Virus.</strong>
<strong> As we haveth no technology nor programming experience, this virus worketh on the honour system. Please delete all the files from thy hard drive and manually forward this virus to all on thy mailing list.
We thank thee for thy cooperation.
— The Amish Computer Engineering Dept.</strong></p>
The subtle humor of this long-standing joke lies in the fact that the author of the ‘virus’ is so technology averse that you have to damage yourself and others with it manually – the virus is not going to automate any of that for you. Of course, few recipients of such an email would go through the effort of doing something so obviously destructive. Common sense quickly argues against deleting valuable files or taking deliberate steps to infect friends with a damaging virus.]]></description>
			<content:encoded><![CDATA[<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/04/computerfail.jpg"><img class="alignright size-full wp-image-3492" title="computerfail" src="http://globalknowledgeblog.com/wp-content/uploads/2011/04/computerfail.jpg" alt="" width="250" height="250" /></a>Virus protection? PowerShell? Well… sort of.</p>
<p>An old Internet joke from way back involves the so-called Amish Virus. ‘Infection’ by the Amish Virus can be diagnosed when you open an email and see this:</p>
<p style="text-align: center;"><strong>Thou hast just received the Amish Virus.</strong><br />
<strong> As we haveth no technology nor programming experience, this virus worketh on the honour system. Please delete all the files from thy hard drive and manually forward this virus to all on thy mailing list.<br />
We thank thee for thy cooperation.<br />
— The Amish Computer Engineering Dept.</strong></p>
<p>The subtle humor of this long-standing joke lies in the fact that the author of the ‘virus’ is so technology averse that you have to damage yourself and others with it manually — the virus is not going to automate any of that for you. Of course, few recipients of such an email would go through the effort of doing something so obviously destructive. Common sense quickly argues against deleting valuable files or taking deliberate steps to infect friends with a damaging virus.</p>
<p>What does all this have to do with PowerShell? Interestingly, PowerShell defends against a few kinds of actual security threats using some of the same philosophy that protects us from the ravages of the dreaded Amish Virus.</p>
<p>For contrast, let me remind you about a little virus called ILoveYou. Launched in May of 2000, this simple little piece of code scanned infected computers for graphics and audio files, replaced the contents of those file with a copy of itself, and then propagated itself via email. Unsuspecting targets of the virus found an attachment seemingly named Love-Letter-For-You.txt attached to an email that appeared to be from a trusted source. A text file — what could go wrong? Double-clicking it (you could do that in Outlook back in those days) revealed the truth. The file wasn’t Love-Letter-For-You.txt — it was Love-Letter-For-You.txt.<em>vbs</em>. A VBScript-based application had just been launched in the system, and quite probably, without its user’s awareness.</p>
<p>The impact was immediate and drastic. In a week and a half, 50 million computers had been infected, and upwards of 5 billion dollars of damage had been done. Major corporations, plus the CIA, the Pentagon, and the British Parliament all took their email servers offline in order to clean up the mess. Whoa.</p>
<p>You can imagine that when building PowerShell, Microsoft surely wanted to avoid the disaster produced by the freely-executable nature of VBScript and JavaScript on Windows systems. PowerShell was launched with some significant protections against this kind of mischief.</p>
<p><strong>File Extension Association</strong><br />
Part of what made ILoveYou so nasty was that it didn’t need to ask the user if he wanted to run the VBScript-based executable — that functionality was built right into the operating system. You see, the .VBS extension is already associated with the WScript.exe program in Windows by default, so double-clicking a .vbs file (or a .vbs file masquerading as a .txt) is sufficient to trigger it. By contrast, .PS1 — the PowerShell script file extension, is associated with Notepad.exe. So if some thoughtless user double-clicks an attachment called DamagingVirus.PS1 — no worries — it opens in Notepad, and no harm is done.</p>
<p><strong>Execution Policy</strong><br />
Additionally, PowerShell ships in a default state that prevents script execution. This behavior is called an execution policy, and it’s a reboot-persistent, group policy-configurable setting. It sets a computer-wide configuration for how much trust we need to have in a PowerShell script before we can run it. The default execution policy is called Restricted, and it prevents the execution of any PS1 files. That’s true even for those scripts created locally, or run by the Administrator.</p>
<p>Interestingly, the execution policy does not prevent execution of individual statements at the PowerShell command prompt. So it’s possible that one could attempt to run a PS1 script, fail to do so, and then copy and paste the text of the script into the PowerShell console, one line at a time. But in most cases, that activates our primary defense against the Amish Virus. Common sense should take over in the mind of the user, who realizes he is in danger of doing something foolish. We can imagine that our users would not respond cooperatively to an email that says this:</p>
<p style="text-align: center;"><strong>You have just received the PowerShell Virus.<br />
Please open the attached PS1 file, and cut and paste the executable code into a running instance of PowerShell.exe. That, or run Set-ExecutionPolicy unrestricted at a PowerShell prompt, and then launch the attached script. </strong></p>
<p style="text-align: center;"><strong>Trust me, it’s totally safe!</strong></p>
<p>Well, at least we can hope.</p>
<p><strong>Related Courses:</strong><br />
<a href="http://www.globalknowledge.com/mania?utm_source=blog&amp;utm_medium=referral&amp;utm_campaign=socialmedia">Take 2 Microsoft Courses for the price of 1</a><br />
<a href="http://www.globalknowledge.com/training/course.asp?pageid=9&amp;courseid=15729&amp;catid=184&amp;country=United+States?utm_source=blog&amp;utm_medium=referral&amp;utm_campaign=socialmedia">Automating Administration with Windows PowerShell 2.0</a></p>
]]></content:encoded>
			<wfw:commentRss>http://globalknowledgeblog.com/technology/security/powershell-2-0-protects-you-from-viruses/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PowerShell 2.0 Answers Life’s Big Questions!</title>
		<link>http://globalknowledgeblog.com/technology/microsoft/powershell-2-0-answers-life%e2%80%99s-big-questions/</link>
		<comments>http://globalknowledgeblog.com/technology/microsoft/powershell-2-0-answers-life%e2%80%99s-big-questions/#comments</comments>
		<pubDate>Wed, 08 Jun 2011 17:28:40 +0000</pubDate>
		<dc:creator>Mike Hammond</dc:creator>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://globalknowledgeblog.com/?p=3979</guid>
		<description><![CDATA[Is there anybody out there? Are we alone in the universe? Are my computers online? PowerShell 2.0 can tell you! (At least that last one.)

So the boss emails you a list of computers and wants you to check if each of them are available on the network. You could open a command prompt, type PING and the first name, wait for a response, PING the second, ad nauseum. If there’s two names on the list, fine. How many on this list? 183. Yuck! Sounds like a job for… PowerShell!]]></description>
			<content:encoded><![CDATA[<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/02/blographic078.jpg"><img src="http://globalknowledgeblog.com/wp-content/uploads/2011/02/blographic078.jpg" alt="" title="blographic078" width="250" height="250" class="alignright size-full wp-image-3139" /></a>Is there anybody out there? Are we alone in the universe? Are my computers online? PowerShell 2.0 can tell you! (At least that last one.)</p>
<p>So the boss emails you a list of computers and wants you to check if each of them are available on the network. You could open a command prompt, type PING and the first name, wait for a response, PING the second, ad nauseum. If there’s two names on the list, fine. How many on this list? 183. Yuck! Sounds like a job for… PowerShell!</p>
<h3>Get-Help</h3>
<p>Okay — let’s find a PowerShell feature that lets me ping a computer. <strong>Get-Command</strong> is the usual way to go about that, but in this case, I’m not getting a lot of luck. I see the PING executable, and other stuff I don’t need, but nothing in PowerShell. Here’s a wild idea — let’s try using <strong>Get-Help</strong> and see what we find.</p>
<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/06/ps2-ScreenShot1.jpg"><img class="aligncenter size-full wp-image-3980" title="ps2-ScreenShot1" src="http://globalknowledgeblog.com/wp-content/uploads/2011/06/ps2-ScreenShot1.jpg" alt="" width="555" height="355" /> </a></p>
<p>Interesting — there’s a <strong>Test-Connection</strong> cmdlet that claims to be able to send PINGs to one or more computers. Sounds perfect. Let’s take a close look at the help file for <strong>Test-Connection</strong>.</p>
<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/06/ps2-ScreenShot2.jpg"><img class="aligncenter size-full wp-image-3981" title="ps2-ScreenShot2" src="http://globalknowledgeblog.com/wp-content/uploads/2011/06/ps2-ScreenShot2.jpg" alt="" width="555" height="355" /> </a></p>
<p>I like the idea of the <strong>–Quiet</strong> parameter for a simple TRUE/FALSE evaluation of whether the computer is on the network. Having an object to interrogate might be useful in a later script, but for now, I’ll leave that <strong>Win32_PINGSTATUS</strong> object alone. What I really want to do is get a list of which computers are not currently accessible. So strategically, I want to iterate through my list of computer names, and for each one of them, if it isn’t ping-able (is that a word? Is now) then I want to get a message that says so. So how about something like this (click on the screenshot for a larger image)?</p>
<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/06/ps2-ScreenShot3.jpg"><img class="aligncenter size-full wp-image-3982" title="ps2-ScreenShot3" src="http://globalknowledgeblog.com/wp-content/uploads/2011/06/ps2-ScreenShot3.jpg" alt="" width="558" height="60" /> </a></p>
<p>It’s a good start. But I don’t know which of the computers from my file are the ones returning true and false. Also, let’s assume I only want to know which computers are offline. Time to pull out the trusty old ‘if’ statement.</p>
<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/06/ps2-ScreenShot4.jpg"><img class="aligncenter size-full wp-image-3983" title="ps2-ScreenShot4" src="http://globalknowledgeblog.com/wp-content/uploads/2011/06/ps2-ScreenShot4.jpg" alt="" width="558" height="60" /> </a></p>
<p>Hmmm. Those pesky rebels are at it again, it seems.</p>
<p>I like the output of this little one-liner. It’s a little <em>slow</em>, though. I can tweak it a bit by adding the <strong>–Count 1</strong> parameter to <strong>Test-Connection</strong>, which instead of launching 4 ICMP packets sends One Ping Only (now, why am I hearing Sean Connery’s voice in my head all of a sudden?)</p>
]]></content:encoded>
			<wfw:commentRss>http://globalknowledgeblog.com/technology/microsoft/powershell-2-0-answers-life%e2%80%99s-big-questions/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>PowerShell 2.0 Nukes Grunt Work! — Part 2</title>
		<link>http://globalknowledgeblog.com/technology/microsoft/powershell-2-0-nukes-grunt-work-need-alt-title/</link>
		<comments>http://globalknowledgeblog.com/technology/microsoft/powershell-2-0-nukes-grunt-work-need-alt-title/#comments</comments>
		<pubDate>Tue, 17 May 2011 12:25:44 +0000</pubDate>
		<dc:creator>Mike Hammond</dc:creator>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://globalknowledgeblog.com/?p=3923</guid>
		<description><![CDATA[When we left off, I’d found the date and time of the last Restore Point taken on this machine. And luckily, since this data is coming out of WMI, I can extract the name of the computer I’m running this on from the same object. WMI helpfully supplies a ‘__Server’ property with its objects (note: that’s two underscore characters, not one). So with a little finagling, we get this cute little one-liner (cutting out that awkward ForEach-Object).]]></description>
			<content:encoded><![CDATA[<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/05/peasinanut200.jpg"><img src="http://globalknowledgeblog.com/wp-content/uploads/2011/05/peasinanut200.jpg" alt="" title="peasinanut200" width="200" height="200" class="alignright size-full wp-image-3934" /></a>When we left off, I’d found the date and time of the last Restore Point taken on this machine. </p>
<p>And luckily, since this data is coming out of WMI, I can extract the name of the computer I’m running this on from the same object. </p>
<p>WMI helpfully supplies a ‘__Server’ property with its objects (note: that’s two underscore characters, not one). </p>
<p>So with a little finagling, we get this cute little one-liner (cutting out that awkward ForEach-Object).</p>
<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/05/ScreenShot6.jpg"><img class="aligncenter size-full wp-image-3924" title="ScreenShot6" src="http://globalknowledgeblog.com/wp-content/uploads/2011/05/ScreenShot6.jpg" alt="" width="626" height="85" /></a></p>
<p>The @{Name= … Expression=…} syntax is called a Calculated Property when I use it in Select-Object, and it’s a great little tactic for either renaming a property with an ugly name (like Mr. UnderscoreUnderscoreServer there) or for performing some operation on a piece of data before exposing it to the light of day (like running that date formatter function over the CreationTime property). Check out the Get-Help file for Select-Object, and look at the details of the –Property parameter (you’ll see you can also use the word ‘Label’ instead of ‘Name’.)</p>
<p>This looks great so far. The next trick is accomplishing this same task across a few hundred computers.</p>
<p>Does Get-ComputerRestorePoint have a –computername property we can use to connect to each computer in the boss’s list? Rats — nope. But maybe there’s another way. Take a look at what kind of object that cmdlet produces. Get-Member is the best way to accomplish that — it shows you the name of the .NET class and the list of each of the properties and methods of the objects you pass in to it on the pipeline.</p>
<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/05/ScreenShot7.jpg"><img class="aligncenter size-full wp-image-3925" title="ScreenShot7" src="http://globalknowledgeblog.com/wp-content/uploads/2011/05/ScreenShot7.jpg" alt="" width="617" height="273" /></a></p>
<p>Okay — so it’s a WMI object. Maybe we’re better off accessing the restore points directly through Get-WMIObject. That cmdlet DOES have a –computername property, so I can target it at different computers from a central point.</p>
<p>Alas, Get-ComputerRestorePoint has a built-in method for doing conversion of date information to the DateTime format. This is one of those times where we need to make a trade-off. With the large numbers of computers to inventory, I’ll take the clunkier format conversion to get the multiple computer support of Get-WMIObject. Alternatively, we could have tackled this using PowerShell Remoting, but let’s save that for another time. Let’s look for a WMI class that supports restore points.</p>
<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/05/ScreenShot8.jpg"><img class="aligncenter size-full wp-image-3926" title="ScreenShot8" src="http://globalknowledgeblog.com/wp-content/uploads/2011/05/ScreenShot8.jpg" alt="" width="614" height="395" /></a></p>
<p>Note that the first attempt to search for a restore-related class flopped. That’s because Get-WMIObject –list only searches WMI’s ‘root\cimv2’ namespace by default. In fairness, that’s where most of the good stuff lives, but in this case what we are looking for isn’t there. So where is it? The class type from the earlier call to Get-Member gives a clue. Look after the pound sign. The second attempt finds the class we need.</p>
<p>So now we can rebuild our query to directly attack the problem with Get-WMIObject – like so:</p>
<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/05/ScreenShot9.jpg"><img class="aligncenter size-full wp-image-3927" title="ScreenShot9" src="http://globalknowledgeblog.com/wp-content/uploads/2011/05/ScreenShot9.jpg" alt="" width="602" height="165" /></a></p>
<p>Yep — that’s got it. Now we just need to target this at our list of computers, and we’re home free. If we drop the list of computer names from the boss into a text file (ComputerNames.txt, for example), we can just do this:</p>
<p><a href="http://globalknowledgeblog.com/wp-content/uploads/2011/05/ScreenShot10.jpg"><img class="aligncenter size-full wp-image-3928" title="ScreenShot10" src="http://globalknowledgeblog.com/wp-content/uploads/2011/05/ScreenShot10.jpg" alt="" width="615" height="254" /></a></p>
<p>And we’re done. I can take that output and throw it into a file with Out-File, or a CSV file with Export-CSV. Problem solved. Days of wasted time saved. The boss gets his data, and I go back to designing our cloud strategy!</p>
 <div class=’series_links’> </div><div class=’series_toc’><h3>PowerShell 2.0 Series</h3><ul><li><a href='http://globalknowledgeblog.com/technology/microsoft/powershell-2-0-nukes-grunt-work/' title='PowerShell 2.0 Nukes Grunt Work!'>PowerShell 2.0 Nukes Grunt Work!</a></li><li>PowerShell 2.0 Nukes Grunt Work! — Part 2</li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://globalknowledgeblog.com/technology/microsoft/powershell-2-0-nukes-grunt-work-need-alt-title/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

