<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">
  <title>Precision Computing</title>
  <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/" />
  <link rel="self" href="http://www.leeholmes.com/blog/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2008-06-24T21:17:45.9071250-07:00</updated>
  <author>
    <name>Lee Holmes</name>
  </author>
  <subtitle>MSH:1337 &gt;"hello world" | out-web</subtitle>
  <id>http://www.leeholmes.com/blog/</id>
  <generator uri="http://www.dasblog.net" version="1.9.6264.0">DasBlog</generator>
  <entry>
    <title>First Solo &amp;ndash; and a Ripped Shirt to Prove It</title>
    <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/FirstSoloNdashAndARippedShirtToProveIt.aspx" />
    <id>http://www.leeholmes.com/blog/PermaLink,guid,888bbfc9-b0e2-4e67-9e6b-b264f74e2a01.aspx</id>
    <published>2008-06-24T21:17:45.9071250-07:00</published>
    <updated>2008-06-24T21:17:45.9071250-07:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Last night, I flew my first half-hour as Pilot in Command of N8756C, a 1977 Piper
Warrior. In flying, a pilot’s <a href="http://en.wikipedia.org/wiki/First_solo_flight">First
Solo</a> is a huge milestone. After hours of training and ground study, you finally
take to the air on your own.
</p>
        <p align="center">
          <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="184" alt="FirstSolo" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/FirstSoloandaRippedShirttoProveIt_122A9/P1010091_1.jpg" width="244" border="0" />
        </p>
        <p>
The most difficult part of flying is getting back down, so the First Solo is three
takeoffs and landings -- about half-an-hour in the traffic pattern. It seemed to be
the flight that would never come, though. 
</p>
        <p>
We first planned our pre-solo flight for Thursday, followed by the solo on Sunday.
The pre-solo flight is a comprehensive review, so we booked the airplane from 5 to
7 PM. When we went through our pre-flight checklist, we realized that none of the
avionics were working: I could hear myself, but couldn’t speak with my instructor.
We tried everything we could to resolve the problem (including accidentally enabling
the Emergency Locator Transmitter / Distress Beacon,) but couldn’t fix it. Dejected,
we re-parked the plane and returned to base. I later learned that the squelch on the
radio was wrongly adjusted. The squelch control determines the signal strength required
for transmission. It is normally used to suppress low-level static, but in this case
was set to exclude almost everything. 
</p>
        <p>
With that flight aside, we re-booked for Sunday – this time for both the pre-solo
and solo flight. 
</p>
        <p>
Sunday came around bright and sunny, as did our 6 PM flight time. We patiently waited
for our plane to arrive back from a previous lesson, filling time with some ground
work in the meantime. We planned a flight to <a href="http://www.airnav.com/airport/KPLU">Thun
Field</a>, with detours for maneuver practice and instrument flying. Then, we waited
some more. And some more. The plane finally got back 75 minutes late, but we went
out hoping to get at least part of the lesson done. 
</p>
        <p>
When we got to the plane for our pre-flight checklist, we of course found it bone-dry.
The gas truck took seemed to take its sweet time, but the real kicker came as we prepared
to taxi out of the parking area. There was traffic to our left: a brand spanking new <a href="http://en.wikipedia.org/wiki/Boeing_737">Boeing
737</a> being towed SLOWLY back toward the Boeing hangar in all of its <a href="http://blog.seattle-deliveries.com/2008/01/skymark-737-ja737p-pic.html">unpainted
glory</a>. By slowly, I mean walking pace. This taxi would have taken 45 or 50 minutes,
so we had to call off that flight, as well. We re-booked for Monday: 5 to 9 PM. 
</p>
        <p align="center">
          <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="164" alt="Boeing 737" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/FirstSoloandaRippedShirttoProveIt_122A9/clip_image001_3.jpg" width="244" border="0" />
        </p>
        <p>
Monday (yesterday) finally came around, and my study work for Sunday night was to
read up on how to use the <a href="http://en.wikipedia.org/wiki/VHF_omnidirectional_range">VOR
system</a> for navigation, rather than use the primarily visual navigation we were
previously planning. VORs are directional beacons that let a flight instrument determine
the direction from the VOR ground station to your airplane. To find a specific point,
you generally use two VORs at the same time to triangulate your position. 
</p>
        <p>
The flight was intense. It was 2.8 hours in the air and reviewed: 
</p>
        <ul>
          <li>
Slow flight, where you fly and maneuver at near-stall speeds 
</li>
          <li>
Power-On and Power-Off stalls, and stall recovery 
</li>
          <li>
Ground reference maneuvers (Turns around a point, S-turns, rectangular courses) 
</li>
          <li>
Steep turns and standard turns</li>
          <li>
Emergency procedures (We “lost our engine,” so I had to pick and prepare
for a landing) 
</li>
          <li>
Go-Arounds (Calling a mulligan on un-safe or un-certain landings) 
</li>
          <li>
5 landings at Thun field, with my instructor having his eyes closed for the final
3 or 4 
</li>
        </ul>
        <p>
I was recording this on my GPS, so here are some highlights. First, the Thun Field
landings:
</p>
        <p>
          <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="Thun Field landings" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/FirstSoloandaRippedShirttoProveIt_122A9/image_3.png" width="208" border="0" />
        </p>
        <p>
Then, some ground-reference maneuvres:
</p>
        <p>
          <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="182" alt="image" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/FirstSoloandaRippedShirttoProveIt_122A9/image_6.png" width="244" border="0" />
        </p>
        <p>
On the way back to Renton airport, we also did 30 minutes of Instrument Training.
For instrument training, you don a mask that prevents you from seeing outside the
cockpit, and maneuver the airplane by instruments alone. 
</p>
        <p>
When we finally landed back at Renton airport, we practiced another 2 landings, finally
coming to a full stop at the tie-down area. My instructor got out, wished me luck,
and watched as went through the pre-flight checklist again. I alerted the tower as
I prepared to taxi: 
</p>
        <blockquote>
          <p>
            <i>Renton Ground, this is Warrior 8756 Charlie at North Tower. Student pilot on first
solo, requesting closed traffic with information Alpha.</i>
          </p>
        </blockquote>
        <p>
I was given clearance to taxi to runway 15 (150 degrees, roughly north to south,)
and prepared for my first flight. I waited for a minute as a few other planes landed,
and then was given clearance for takeoff. I had too much power on my first run around
the traffic pattern, so ended up lining up with the runway a little too high. Rather
than try to rescue the landing in a potentially nervous state, I let the tower know
I was doing a go-around, and climbed back to the traffic pattern. The controller mentioned
that the winds were fairly variable and gusty, approaching 8 knots at times. She offered
the south to north landing on runway 33, which I declined (as the winds weren’t
affecting my landings.) The second attempt was much better, marking my first landing
as Pilot in Command. 
</p>
        <p>
Now for landing number two. 
</p>
        <p>
Take-off is usually a breeze, but the nose appeared unusually high as I gave the plane
full power on the ground. I quickly brought the power down, and exited one of the
taxiways to determine the cause. After checking everything (flaps, elevator, etc,)
I realized it was just a mind trick: I had been in a basically nose-down attitude
(for the descents) for the last 10 or 15 minutes, so it was a lot like Velocitization
in a car. You get so used to something (speed in a car, or nose angle in an airplane,)
that it becomes your mind’s new definition of normal. You combat velocitization
once you realize you have it, so I requested clearance to taxi back on the runway
and complete my landings. 
</p>
        <p>
In the air again, the controller mentioned that they were just about to close, and
asked if I wanted her to stay on. I didn’t want to keep her late, so I let her
know I’d make my next landing a full-stop. She was awesome, and said she had
no problem staying so I could get the solo done, so I continued with my next landing
– still OK, but with definite room for improvement. 
</p>
        <p>
My final takeoff is where it really kicked in. After lifting into the air, an enormous
thrill washed over me as I took a relaxed breath of fresh air. It was physically impossible
for me to NOT land a third time. I grinned as I made my final approach, and settled
in for the smoothest and straightest landing yet.
</p>
        <p>
As recorded by my GPS:
</p>
        <p>
          <a href="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/FirstSoloandaRippedShirttoProveIt_122A9/image_8.png">
            <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="484" alt="image" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/FirstSoloandaRippedShirttoProveIt_122A9/image_thumb_2.png" width="461" border="0" />
          </a>  
</p>
        <p>
As I taxied off the runway, the tower controller congratulated me on my landings as
I thanked her for her help. The landings were nothing for the highlight reels, of
course, but it gave a satisfying end-cap to 30 minutes that I will never forget. 
</p>
        <p>
And the ripped shirt to prove it? Well, in-line with tradition, my instructor <a href="http://flighttraining.aopa.org/ft_magazine/special/shirttails.cfm">cut
up the back of my shirt</a>. Before modern electronics, in-cockpit communication was
mainly through shirt tugging and hollers from the instructor that sat behind you.
Cutting off the back of the shirt symbolizes this very important step -- as your instructor
won't need to be yanking on it any more.
</p>
        <img width="0" height="0" src="http://www.leeholmes.com/blog/aggbug.ashx?id=888bbfc9-b0e2-4e67-9e6b-b264f74e2a01" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Importing and Exporting Credentials in PowerShell</title>
    <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/ImportingAndExportingCredentialsInPowerShell.aspx" />
    <id>http://www.leeholmes.com/blog/PermaLink,guid,680bc0bc-5b93-469c-8b64-be123744649b.aspx</id>
    <published>2008-06-04T08:40:28.5531250-07:00</published>
    <updated>2008-06-04T08:40:28.5531250-07:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
One question that comes up fairly often when dealing with (or writing!) secure cmdlets
is how to properly handle usernames and passwords. The solution there is to use (or
make) the -Credential parameter of type PSCredential. A PSCredential object helps
ensure that your password stays protected in memory, unlike cmdlets that accept a
straight username / password combination.
</p>
        <p>
If a parameter is of type PSCredential, PowerShell supports several types of input:
</p>
        <ul>
          <li>
empty: If you supply no input to a mandatory -Credential parameter, PowerShell prompts
you for the username and password.</li>
          <li>
string: If you supply a string to the -Credential parameter, PowerShell treats it
as a username and prompts you for the password.</li>
          <li>
credential: If you supply a credential object to the -Credential parameter, PowerShell
accepts it as-is.</li>
        </ul>
        <p>
This is great for interactive use, but what if you want to write an automated script
for a cmdlet that accepts a -Credential parameter? The solution lies in passing a
pre-constructed PSCredential object. The solution to this is covered by recipe 16.9
in the <a href="http://www.amazon.com/gp/product/0596528493?ie=UTF8&amp;tag=preciscomput-20&amp;link_code=as3&amp;camp=211189&amp;creative=373489&amp;creativeASIN=0596528493">PowerShell
Cookbook</a>:
</p>
        <p>
 
</p>
        <h1 style="text-align: justify">
          <a name="XREF86186_Securely_Store_Credentials_on_">Securely
Store Credentials on Disk</a>
          <p>
          </p>
        </h1>
        <h2 style="text-align: justify">Problem 
<p></p></h2>
        <p class="MsoBodyText">
Your script performs an operation that requires credentials, but you don’t want
it to require user interaction when it runs. 
</p>
        <p>
        </p>
        <h2 style="text-align: justify">Solution 
<p></p></h2>
        <p class="MsoBodyText">
To securely store the credential’s password to disk so that your script can
load it automatically, use the <span class="Literal"><span style="mso-bidi-font-family: 'Times New Roman'">ConvertFrom-SecureString</span></span> and <span class="Literal"><span style="mso-bidi-font-family: 'Times New Roman'">ConvertTo-SecureString</span></span> cmdlets. 
</p>
        <p>
        </p>
        <h3>Save the credential’s password to disk 
<p></p></h3>
        <p class="MsoBodyText">
The first step for storing a password on disk is usually a manual one. Given a credential
that you’ve stored in the <span class="Literal"><span style="mso-bidi-font-family: 'Times New Roman'">$credential</span></span> variable,
you can safely export its password to <span class="Filename"><span style="mso-bidi-font-family: 'Times New Roman'">password.txt</span></span> using
the following command: 
</p>
        <p>
        </p>
        <div style="border-right: medium none; padding-right: 0in; border-top: medium none; padding-left: 2pt; padding-bottom: 0in; margin-left: 0.25in; border-left: windowtext 1pt solid; margin-right: -67.7pt; padding-top: 0in; border-bottom: medium none; mso-element: para-border-div; mso-border-left-alt: solid windowtext .75pt">
          <p class="Code" style="margin: 0in 0in 0pt">
PS &gt;$credential.Password | ConvertFrom-SecureString | Set-Content <span class="Replaceable"><span style="mso-bidi-font-family: 'Times New Roman'">c:\temp\password.txt</span></span></p>
          <p>
          </p>
        </div>
        <h3>Recreate the credential from the password stored on disk 
<p></p></h3>
        <p class="MsoBodyText">
In the script that you want to run automatically, add the following commands: 
</p>
        <p>
        </p>
        <div style="border-right: medium none; padding-right: 0in; border-top: medium none; padding-left: 2pt; padding-bottom: 0in; margin-left: 0.25in; border-left: windowtext 1pt solid; margin-right: -67.7pt; padding-top: 0in; border-bottom: medium none; mso-element: para-border-div; mso-border-left-alt: solid windowtext .75pt">
          <p class="Code" style="margin: 0in 0in 0pt">
$password = Get-Content <span class="Replaceable"><span style="mso-bidi-font-family: 'Times New Roman'">c:\temp\password.txt</span></span> |
ConvertTo-SecureString 
</p>
          <p>
          </p>
          <p class="Code" style="margin: 0in 0in 0pt">
$credential = New-Object System.Management.Automation.PsCredential ` 
</p>
          <p>
          </p>
          <p class="Code" style="margin: 0in 0in 0pt">
            <span style="mso-spacerun: yes">    </span>"<span class="Replaceable"><span style="mso-bidi-font-family: 'Times New Roman'">CachedUser</span></span>",$password 
</p>
          <p>
          </p>
        </div>
        <p class="MsoBodyText">
These commands create a new credential object (for the <span class="Replaceable"><span style="mso-bidi-font-family: 'Times New Roman'">CachedUser</span></span> user)
and store that object in the <span class="Literal"><span style="mso-bidi-font-family: 'Times New Roman'">$credential</span></span> variable. 
</p>
        <p>
        </p>
        <h2>Discussion 
<p></p></h2>
        <p class="MsoBodyText">
When reading the solution, you might at first be wary of storing a password on disk.
While it is natural (and prudent) to be cautious of littering your hard drive with
sensitive information, the <span class="Literal"><span style="mso-bidi-font-family: 'Times New Roman'">ConvertFrom-SecureString</span></span> cmdlet
encrypts this data using Windows’ standard <span class="TechnicalItalic"><span style="mso-bidi-font-family: 'Times New Roman'">Data
Protection API</span></span>. This ensures that only your user account can properly
decrypt its contents. 
</p>
        <p>
        </p>
        <p class="MsoBodyText">
While keeping a password secure is an important security feature, you may sometimes
want to store a password (or other sensitive information) on disk so that other accounts
have access to it anyway. This is often the case with scripts run by service accounts
or scripts designed to be transferred between computers. The <span class="Literal"><span style="mso-bidi-font-family: 'Times New Roman'">ConvertFrom-SecureString</span></span> and <span class="Literal"><span style="mso-bidi-font-family: 'Times New Roman'">ConvertTo-SecureString</span></span> cmdlets
support this by allowing you to specify an encryption key. 
</p>
        <p>
        </p>
        <div style="border-right: medium none; padding-right: 0in; border-top: windowtext 1pt solid; padding-left: 0in; padding-bottom: 2pt; margin-left: 0.5in; border-left: medium none; margin-right: 0.5in; padding-top: 2pt; border-bottom: windowtext 1pt solid; mso-element: para-border-div; mso-border-top-alt: solid windowtext .75pt; mso-border-bottom-alt: solid windowtext .75pt">
          <p class="Note" style="margin: 6pt 0in">
When used with a hard-coded encryption key, this technique no longer acts as a security
measure. If a user can access to the content of your automated script, they have access
to the encryption key. If the user has access to the encryption key, they have access
to the data you were trying to protect. 
</p>
          <p>
          </p>
        </div>
        <p class="MsoBodyText">
Although the solution stores the password in a specific named file, it is more common
to store the file in a more generic location—such as the directory that contains
the script, or the directory that contains your profile. 
</p>
        <p>
        </p>
        <p class="MsoBodyText">
To load <span class="Filename"><span style="mso-bidi-font-family: 'Times New Roman'">password.txt</span></span> from
the same location as your profile, use the following command: 
</p>
        <p>
        </p>
        <div style="border-right: medium none; padding-right: 0in; border-top: medium none; padding-left: 2pt; padding-bottom: 0in; margin-left: 0.25in; border-left: windowtext 1pt solid; margin-right: -67.7pt; padding-top: 0in; border-bottom: medium none; mso-element: para-border-div; mso-border-left-alt: solid windowtext .75pt">
          <p class="Code" style="margin: 0in 0in 0pt">
$passwordFile = Join-Path (Split-Path $profile) password.txt 
</p>
          <p>
          </p>
          <p class="Code" style="margin: 0in 0in 0pt">
$password = Get-Content $passwordFile | ConvertTo-SecureString 
</p>
          <p>
          </p>
        </div>
        <p class="MsoBodyText">
To learn how to load it from the same location as your script, see “<a name="XREF93954_Find_your_Scripts_Location">Find
your Script’s Location</a>.” 
</p>
        <p>
        </p>
        <p class="MsoBodyText">
For more information about the <span class="Literal"><span style="mso-bidi-font-family: 'Times New Roman'">ConvertTo-SecureString</span></span> and <span class="Literal"><span style="mso-bidi-font-family: 'Times New Roman'">ConvertFrom-SecureString</span></span> cmdlets,
type <span class="Literal"><span style="mso-bidi-font-family: 'Times New Roman'">Get-Help
ConvertTo-SecureString</span></span> or <span class="Literal"><span style="mso-bidi-font-family: 'Times New Roman'">Get-Help
ConvertFrom-SecureString</span></span>. 
</p>
        <img width="0" height="0" src="http://www.leeholmes.com/blog/aggbug.ashx?id=680bc0bc-5b93-469c-8b64-be123744649b" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Flight Training, Episode 2</title>
    <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/FlightTrainingEpisode2.aspx" />
    <id>http://www.leeholmes.com/blog/PermaLink,guid,9164272c-05d4-44e4-b677-58d524c85865.aspx</id>
    <published>2008-06-03T23:42:09.3031250-07:00</published>
    <updated>2008-06-03T23:42:09.3031250-07:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
After what seems like an eternity, I finally got to start my official flight training.
As a Canadian (AKA "Alien,") applying for flight school also means getting
your fingerprints taken and being put in a special registration system. My training
permission cleared late last week, so I booked my first lessons as soon as I could.
In fact, for a government agency, the flight registration process was surprisingly
efficient. Finding a place to get TSA-approved fingerprints outside of work hours?
Well, that's a different story. 
</p>
        <p>
Anyways. 
</p>
        <p>
One of the things I really missed about my intro flights was a good understanding
of exactly where I traveled during the flight. I remembered some landmarks, but didn't
really catch on to many streets or things I knew from my ground travels. Recording
my tracks through a GPS system seemed to be the best approach, so I finally settled
on a <a href="Lowrance Airmap 2000C">Lowrance Airmap 2000C</a>. Its features rival
most of the top-end aircraft GPS products (aside from XM weather and traffic, which
I'm not in the market for,) at a fraction of the price. For about the same cost, I
would have been able to use some computer-based GPS software on my Tablet PC, but
messing around with a Tablet PC in the cockpit seems to be a lot more trouble than
it's worth.
</p>
        <p>
          <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="clip_image001" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/FlightTrainingEpisode2_13860/clip_image001_3.jpg" width="194" border="0" />
        </p>
        <p>
I took it on a long camping trip during the Memorial Day long weekend, and it was
fun watching it trace my path around the Puget Sound. It warned me plenty as I passed
through the restricted airspaces (McChord airforce base, SeaTac airport, etc,) so
luckily I wasn't actually flying. 
</p>
        <p>
On Thursday, I went for my first real lesson, flying AcuWings' Piper Warrior PA28-151.
This is the kind of plane I want to do most of my training on -- as the Cirrus SR20
(while newer and nicer) felt like it might prevent me from learning some of the subtle
basics -- like rudder control, or use of the nose-wheel while on the ground.
</p>
        <p>
          <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="188" alt="clip_image001[5]" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/FlightTrainingEpisode2_13860/clip_image001%5B5%5D_1.jpg" width="244" border="0" />
        </p>
        <p>
In the introductory flights, the instructor does almost all of the ground work, aside
from giving you a brief overview of what they are doing. For your first training flight,
though, you start to take over the technical preparations: aircraft examination, engine
start procedures, pre-takeoff work, and the post-flight run-down. We spent about 45
minutes on these preparations, learning the how and why behind 80+ items in the pre-flight
and post-flight checklists. 
</p>
        <p>
In the air, we practiced straight and level flight, ascents, descents, and (level,
ascending, descending) turns. Like the flight-preparation work, non-introductory training
means that you begin to take over much more of the landing preparations. During this
flight, we did 2 landings, one being a <a href="http://en.wikipedia.org/wiki/Touch-and-go_landing">touch-and-go</a>.
For both, I flew the traffic pattern, lined up the approach, and helped guide us toward
the runway. I did a little less of the actual landing than I had done during my introductory
flights, but I think that was probably because of higher wind. This flight gave me
0.8 hours of qualified dual-instruction to apply to my flight training. 
</p>
        <p>
On Sunday, we put in another 1.1 hours of dual instruction, with the learning curve
continuing just as steep. Since I had been taught the checklists, pre-flight this
time was all my own – including the inevitable splashing of leaded, high-octane <a href="http://en.wikipedia.org/wiki/Avgas">Avgas</a> on
my hands while testing for fuel contaminants. As we prepared for takeoff, I was shown
how to talk with the tower, request permission to taxi, take-off, and practice landings.
That's a massive system of verbal cryptography that will take a while to get used
to, but you feel like part of a club when you're doing it.
</p>
        <p>
While in the air, we practiced slow flight (near-stall conditions,) stalls, and recovering
from stalls. These are the most common "emergency" situations in flight,
and are relatively easy to recover from as long as you know what you are doing. If
you haven't practiced them, then you'll just panic and donate some iron to the earth's
mantle.
</p>
        <p>
After practicing those, we started working on landings. As a skill in flying, landings
are a unique breed. They are a skill within a skill: a technique that gets lavish
attention in the context of flying, but completely independent of it. Pilots obsess
about landings the same way that cigar aficionados gush about about the tower of ash
emanating from their cigar, or how developers delight in "Perl Golf,"
</p>
        <p>
It's a journey that's just beginning -- I can't wait for more.
</p>
        <img width="0" height="0" src="http://www.leeholmes.com/blog/aggbug.ashx?id=9164272c-05d4-44e4-b677-58d524c85865" />
      </div>
    </content>
  </entry>
  <entry>
    <title>PowerShell's Noble Blue</title>
    <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/PowerShellsNobleBlue.aspx" />
    <id>http://www.leeholmes.com/blog/PermaLink,guid,43a3b5c5-b4a5-45c7-897b-abd19625c33d.aspx</id>
    <published>2008-05-31T20:20:24.5958750-07:00</published>
    <updated>2008-05-31T20:20:24.5958750-07:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Once in awhile, you'll see a PowerShell screenshot that is still black and boring
like the traditional cmd.exe prompt. Other times, you'll see the fancy blue window
you've come to love. Why the difference? And if you're suffering from black window
syndrome, what can you do about it?
</p>
        <p>
          <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="237" alt="image" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/PowerShellStillLaunchesaBlackWindow_1098D/image_6.png" width="324" border="0" />
        </p>
        <p>
Before shipping Version 1, our marketing and design teams set to make the PowerShell
window a unique and marquee experience. What form did this take?
</p>
        <ul>
          <li>
            <strong>Blue</strong>. Specifically, Red: 1, Green: 36, Blue: 86. -- In hex, 012 456.
That number is much too cool to be a coincidence, but I haven't done the social archeology
to find out why :)</li>
          <li>
            <strong>Lucida Console</strong>. Lucida Console is infinitely more readable than the
raster fonts, and ships with all versions of Windows. Consolas is a <a href="http://www.hanselman.com/blog/UsingConsolasAsTheWindowsConsoleFont.aspx">beautiful
alternative</a>, but isn't broadly available.</li>
          <li>
            <strong>Window Size</strong>. Long gone are the days of 640x480 monitors being the
most common, so PowerShell's default window gives about 800x600 of usable space.</li>
          <li>
            <strong>Screen Buffer</strong>. Likewise, long gone are the days of 256mb of memory
being the most common, so PowerShell's default window gives a dreamy 60 pages of history
buffer. This is a shell you want to live in. And when you live in a shell, you 
want to be able to see what you've done.</li>
          <li>
            <strong>Quick Edit</strong>. Quick Edit mode lets you copy and paste easily to and
from the console window. It is the setting that most console users enable once they
realize it exists, and long gone are the days of <a href="http://blogs.msdn.com/oldnewthing/archive/2007/09/13/4886108.aspx">mouse-driven
console applications</a>.</li>
        </ul>
        <p>
Now, even with all of these improvements, you still see screen shots of PowerShell
prompts blinking desolate in the confines of a traditional black console window. Why
is this?
</p>
        <p>
PowerShell customizes its window through the shortcut properties in its Start Menu
link. When you launch PowerShell through the <strong>Start | Run</strong> dialog or
some other app launcher, these shortcut properties don't apply. Surprisingly, Windows
does not support a mechanism to make these console customizations machine-wide. Windows
supports per-user console customizations in the the HKCU hive of the registry, but
there's usually no "Current User" during a PowerShell install. And even
if there were, any customizations would not apply to user accounts created after PowerShell
was installed.
</p>
        <p>
So how do you get PowerShell's Noble Blue if you prefer <strong>Start | Run</strong>?
Here's a script from the PowerShell Cookbook that does exactly that -- for your current
user account.:
</p>
        <p>
          <font face="Courier New" size="1">## From Windows PowerShell, The Definitive Guide
(O'Reilly) 
<br />
## by Lee Holmes (</font>
          <a href="http://www.leeholmes.com/guide)">
            <font face="Courier New" size="1">http://www.leeholmes.com/guide)</font>
          </a>
        </p>
        <p>
          <font face="Courier New" size="1">Push-Location 
<br />
Set-Location HKCU:\Console 
<br />
New-Item ".\%SystemRoot%_system32_WindowsPowerShell_v1.0_powershell.exe" 
<br />
Set-Location ".\%SystemRoot%_system32_WindowsPowerShell_v1.0_powershell.exe" </font>
        </p>
        <p>
          <font face="Courier New" size="1">New-ItemProperty . ColorTable00 -type DWORD -value
0x00562401 
<br />
New-ItemProperty . ColorTable07 -type DWORD -value 0x00f0edee 
<br />
New-ItemProperty . FaceName -type STRING -value "Lucida Console" 
<br />
New-ItemProperty . FontFamily -type DWORD -value 0x00000036 
<br />
New-ItemProperty . FontSize -type DWORD -value 0x000c0000 
<br />
New-ItemProperty . FontWeight -type DWORD -value 0x00000190 
<br />
New-ItemProperty . HistoryNoDup -type DWORD -value 0x00000000 
<br />
New-ItemProperty . QuickEdit -type DWORD -value 0x00000001 
<br />
New-ItemProperty . ScreenBufferSize -type DWORD -value 0x0bb80078 
<br />
New-ItemProperty . WindowSize -type DWORD -value 0x00320078 
<br />
Pop-Location</font>
        </p>
        <img width="0" height="0" src="http://www.leeholmes.com/blog/aggbug.ashx?id=43a3b5c5-b4a5-45c7-897b-abd19625c33d" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Generating Code Coverage from PowerShell Scripts</title>
    <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/GeneratingCodeCoverageFromPowerShellScripts.aspx" />
    <id>http://www.leeholmes.com/blog/PermaLink,guid,ccaa6171-6c86-4d91-983f-ba40feaf225a.aspx</id>
    <published>2008-05-20T00:47:31.5620000-07:00</published>
    <updated>2008-05-20T00:47:31.5620000-07:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
If you're testing your PowerShell scripts (manually or automatically,) one of the
first questions you'll end up asking yourself is, "did I test enough?" 
</p>
        <p>
This is common problem in all of software development. To the rescue is a simple metric
known as "Code Coverage" – a measure of how much code you exercised
during the testing of that code. 
</p>
        <p>
However, the measurement is just the end result – you need a tool to get you
there. When it comes to measuring code coverage in PowerShell scripts, though, there
simply aren't any tools yet. 
</p>
        <p>
Like performance measurement tools, Code Coverage tools are sometimes driven by instrumentation
of the source code, and sometimes driven by sampling the code during runtime. Instrumentation
gives the highest accuracy, but we can go a long way by runtime analysis alone. To
accomplish that, we'll use our favourite feature to abuse – PowerShell script
tracing. The last time we pushed it, we got a <a href="http://www.leeholmes.com/blog/burnconsoleDigressionAnMSHScriptProfiler.aspx">sampling
profiler out of the deal</a>. Let's do it again for code coverage. 
</p>
        <p>
Take, for example, the following source code: 
</p>
        <pre style="color: #eeedf0; background-color: #012456">
          <span style="color: #cc66cc; background-color: #012456">trap</span> { <span style="color: #66cccc; background-color: #012456">"Error
handling!"</span><span style="color: #44aaaa; background-color: #012456">;</span><span style="color: #cc66cc; background-color: #012456">continue</span> } <span style="color: #66cccc; background-color: #012456">"Got
here"</span><span style="color: #cc66cc; background-color: #012456">if</span>(<span style="color: #66cc66; background-color: #012456">$args</span><span style="color: #44aaaa; background-color: #012456">[</span><span style="color: #66cccc; background-color: #012456">0</span><span style="color: #44aaaa; background-color: #012456">]</span><span style="color: #44aaaa; background-color: #012456">-eq</span><span style="color: #66cccc; background-color: #012456">"Test"</span>)
{ <span style="color: #66cccc; background-color: #012456">"Got TEST as an argument"</span> } <span style="color: #cc66cc; background-color: #012456">elseif</span>(<span style="color: #66cc66; background-color: #012456">$args</span><span style="color: #44aaaa; background-color: #012456">[</span><span style="color: #66cccc; background-color: #012456">0</span><span style="color: #44aaaa; background-color: #012456">]</span><span style="color: #44aaaa; background-color: #012456">-eq</span><span style="color: #66cccc; background-color: #012456">"Err0r"</span>)
{ <span style="color: #cc66cc; background-color: #012456">throw</span><span style="color: #66cccc; background-color: #012456">"Catch
Me!"</span> } <span style="color: #cc66cc; background-color: #012456">else</span> { <span style="color: #66cccc; background-color: #012456">"Didn't
get TEST as an argument"</span> } </pre>
        <p>
We want to run through three parameters that it takes, and make sure we're exercising
everything. Notice how we're even being diligent by testing the "Error"
case! 
</p>
        <pre style="color: #eeedf0; background-color: #012456">PS C:\temp&gt; $tests = @()                                              
PS C:\temp&gt; $tests += { .\Test-CodeCoverage.ps1 Test }                
PS C:\temp&gt; $tests += { .\Test-CodeCoverage.ps1 SomethingElse }       
PS C:\temp&gt; $tests += { .\Test-CodeCoverage.ps1 Error }               
PS C:\temp&gt;                                                           
PS C:\temp&gt; .\Get-ScriptCoverage.ps1 .\Test-CodeCoverage.ps1 $tests </pre>
        <p>
What does that give us? 
</p>
        <pre style="color: #eeedf0; background-color: #012456">
          <span style="color: #cc6666; background-color: #012456">trap
{ "Error handling!"; continue }</span>
          <span style="color: #66cc66; background-color: #012456">"Got
here"</span>
          <span style="color: #66cc66; background-color: #012456">if($args[0]
-eq "Test")</span> { <span style="color: #66cc66; background-color: #012456"> "Got
TEST as an argument"</span> } elseif($args[0] -eq "Err0r") { <span style="color: #cc6666; background-color: #012456"> throw
"Catch Me!"</span> } else { <span style="color: #66cc66; background-color: #012456"> "Didn't
get TEST as an argument"</span> } Coverage Statistics: 66.6666666666667% PS C:\temp&gt; </pre>
        <p>
Ouch! Why is the error handling code (in red) not being hit? Ah, after further investigation,
it turns out that we have a typo in our string comparison. We fix it: 
</p>
        <blockquote>
          <p>
... 
<br />
elseif($args[0] -eq "Err<font color="#ff0000">0</font>r") 
<br />
... 
</p>
        </blockquote>
        <p>
Becomes 
</p>
        <blockquote>
          <p>
... 
<br />
elseif($args[0] -eq "Error") 
<br />
... 
</p>
        </blockquote>
        <p>
And run code coverage again: 
</p>
        <pre style="color: #eeedf0; background-color: #012456">
          <span style="color: #66cc66; background-color: #012456">trap
{ "Error handling!"; continue }</span>
          <span style="color: #66cc66; background-color: #012456">"Got
here"</span>
          <span style="color: #66cc66; background-color: #012456">if($args[0]
-eq "Test")</span> { <span style="color: #66cc66; background-color: #012456"> "Got
TEST as an argument"</span> } elseif($args[0] -eq "Error") { <span style="color: #66cc66; background-color: #012456"> throw
"Catch Me!"</span> } else { <span style="color: #66cc66; background-color: #012456"> "Didn't
get TEST as an argument"</span> } Coverage Statistics: 100% PS C:\temp&gt; </pre>
        <p>
Much better. 
</p>
        <p>
Here is the script – under 80 lines of (heavily commented) code: 
</p>
        <pre style="color: #eeedf0; background-color: #012456">
          <span style="color: #cc6666; background-color: #012456">##
Get-ScriptCoverage.ps1</span>
          <span style="color: #cc6666; background-color: #012456">##
Test the script named by $testScript for code coverage.</span>
          <span style="color: #cc6666; background-color: #012456">##
The command given by $command must exercise this named</span>
          <span style="color: #cc6666; background-color: #012456">##
script.</span>
          <span style="color: #cc66cc; background-color: #012456">param</span>(<span style="color: #aaaa44; background-color: #012456">[string]</span><span style="color: #66cc66; background-color: #012456">$testScript</span><span style="color: #44aaaa; background-color: #012456">,</span><span style="color: #aaaa44; background-color: #012456">[ScriptBlock[]]</span><span style="color: #66cc66; background-color: #012456">$command</span>) <span style="color: #cc6666; background-color: #012456">#
Store the content of the script to be tested</span><span style="color: #66cc66; background-color: #012456">$fileContent</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #cccc66; background-color: #012456">gc</span><span style="color: #66cc66; background-color: #012456">$testScript</span><span style="color: #cccc66; background-color: #012456">-ea</span><span style="color: #66cccc; background-color: #012456">Stop</span><span style="color: #cc6666; background-color: #012456">##
Start a transcript, and log it to a file</span><span style="color: #66cc66; background-color: #012456">$tempFile</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #aaaa44; background-color: #012456">[IO.Path]</span><span style="color: #44aaaa; background-color: #012456">::</span><span style="color: #aaaa44; background-color: #012456">GetTempFilename</span>() <span style="color: #cccc66; background-color: #012456">Start-Transcript</span><span style="color: #66cc66; background-color: #012456">$tempFile</span><span style="color: #cc6666; background-color: #012456">##
Turn on line-level tracing, run the command(s),</span><span style="color: #cc6666; background-color: #012456">##
then turn off line-level tracing again.</span><span style="color: #cccc66; background-color: #012456">Set-PsDebug</span><span style="color: #cccc66; background-color: #012456">-Trace</span><span style="color: #66cccc; background-color: #012456">1</span><span style="color: #66cc66; background-color: #012456">$command</span><span style="color: #44aaaa; background-color: #012456">|</span><span style="color: #cccc66; background-color: #012456">Foreach-Object</span> { <span style="color: #44aaaa; background-color: #012456">&amp;</span><span style="color: #66cc66; background-color: #012456">$_</span> } <span style="color: #cccc66; background-color: #012456">Set-PsDebug</span><span style="color: #cccc66; background-color: #012456">-Trace</span><span style="color: #66cccc; background-color: #012456">0</span><span style="color: #cc6666; background-color: #012456">##
Stop the transcript</span><span style="color: #cccc66; background-color: #012456">Stop-Transcript</span><span style="color: #cc6666; background-color: #012456">##
Get the result of the script coverage run</span><span style="color: #66cc66; background-color: #012456">$coverageContent</span><span style="color: #44aaaa; background-color: #012456">=</span> (<span style="color: #cccc66; background-color: #012456">gc</span><span style="color: #66cc66; background-color: #012456">$tempFile</span>) <span style="color: #44aaaa; background-color: #012456">-match</span><span style="color: #66cccc; background-color: #012456">"^DEBUG:"</span><span style="color: #cccc66; background-color: #012456">Remove-Item</span><span style="color: #cccc66; background-color: #012456">-LiteralPath</span><span style="color: #66cc66; background-color: #012456">$tempFile</span><span style="color: #cccc66; background-color: #012456">Clear-Host</span><span style="color: #cc6666; background-color: #012456">##
Clean up interference from other scripts</span><span style="color: #66cc66; background-color: #012456">$scriptLines</span><span style="color: #44aaaa; background-color: #012456">=</span> @() <span style="color: #66cc66; background-color: #012456">$processedLines</span><span style="color: #44aaaa; background-color: #012456">=</span> @{} <span style="color: #cc66cc; background-color: #012456">foreach</span>(<span style="color: #66cc66; background-color: #012456">$originalLine</span><span style="color: #cc66cc; background-color: #012456">in</span><span style="color: #66cc66; background-color: #012456">$coverageContent</span>)
{ <span style="color: #cc6666; background-color: #012456"># Make sure we only process
unique lines in the</span><span style="color: #cc6666; background-color: #012456">#
transcript</span><span style="color: #cc66cc; background-color: #012456">if</span>(<span style="color: #66cc66; background-color: #012456">$processedLines</span><span style="color: #44aaaa; background-color: #012456">[</span><span style="color: #66cc66; background-color: #012456">$originalLine</span><span style="color: #44aaaa; background-color: #012456">]</span>)
{ <span style="color: #cc66cc; background-color: #012456">continue</span> } <span style="color: #66cc66; background-color: #012456">$processedLines</span><span style="color: #44aaaa; background-color: #012456">[</span><span style="color: #66cc66; background-color: #012456">$originalLine</span><span style="color: #44aaaa; background-color: #012456">]</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #66cc66; background-color: #012456">$true</span><span style="color: #cc6666; background-color: #012456">##
Recover as much as possible from the original script line</span><span style="color: #cc6666; background-color: #012456">##
without its debugging information</span><span style="color: #66cc66; background-color: #012456">$originalLine</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #66cc66; background-color: #012456">$originalLine</span><span style="color: #44aaaa; background-color: #012456">-replace</span><span style="color: #66cccc; background-color: #012456">" <span>&lt;</span><span>&lt;</span><span>&lt;</span><span>&lt;</span> "</span><span style="color: #44aaaa; background-color: #012456">,</span><span style="color: #66cccc; background-color: #012456">""</span><span style="color: #66cc66; background-color: #012456">$line</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #66cc66; background-color: #012456">$originalLine</span><span style="color: #44aaaa; background-color: #012456">-replace</span><span style="color: #66cccc; background-color: #012456">'\D*\d+\+
(.*)'</span><span style="color: #44aaaa; background-color: #012456">,</span><span style="color: #66cccc; background-color: #012456">'$1'</span><span style="color: #cc6666; background-color: #012456">##
Go through each line in the original script, and see if</span><span style="color: #cc6666; background-color: #012456">##
this is actually in the script</span><span style="color: #cc66cc; background-color: #012456">foreach</span>(<span style="color: #66cc66; background-color: #012456">$fileLine</span><span style="color: #cc66cc; background-color: #012456">in</span><span style="color: #66cc66; background-color: #012456">$fileContent</span>)
{ <span style="color: #cc6666; background-color: #012456">## If it is, add the debug
line to the list of lines</span><span style="color: #cc6666; background-color: #012456">##
covered by this scenario</span><span style="color: #cc66cc; background-color: #012456">if</span>(<span style="color: #66cc66; background-color: #012456">$fileLine</span><span style="color: #44aaaa; background-color: #012456">.</span><span style="color: #aaaa44; background-color: #012456">Contains</span>(<span style="color: #66cc66; background-color: #012456">$line</span>))
{ <span style="color: #66cc66; background-color: #012456">$scriptLines</span><span style="color: #44aaaa; background-color: #012456">+=</span><span style="color: #66cc66; background-color: #012456">$originalLine</span> }
} } <span style="color: #cc6666; background-color: #012456">## Find out which line
numbers were covered</span><span style="color: #66cc66; background-color: #012456">$coveredLines</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #66cc66; background-color: #012456">$scriptLines</span><span style="color: #44aaaa; background-color: #012456">|</span><span style="color: #cccc66; background-color: #012456">%</span> { <span style="color: #66cc66; background-color: #012456">$_</span><span style="color: #44aaaa; background-color: #012456">-replace</span><span style="color: #66cccc; background-color: #012456">'\D*(\d+)\+
.*'</span><span style="color: #44aaaa; background-color: #012456">,</span><span style="color: #66cccc; background-color: #012456">'$1'</span> } <span style="color: #44aaaa; background-color: #012456">|</span><span style="color: #cccc66; background-color: #012456">Sort</span><span style="color: #cccc66; background-color: #012456">-Unique</span><span style="color: #66cc66; background-color: #012456">$coverageCount</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #66cccc; background-color: #012456">0</span><span style="color: #66cc66; background-color: #012456">$possibleCoveredLines</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #66cccc; background-color: #012456">0</span><span style="color: #cc66cc; background-color: #012456">for</span>(<span style="color: #66cc66; background-color: #012456">$counter</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #66cccc; background-color: #012456">1</span><span style="color: #44aaaa; background-color: #012456">;</span><span style="color: #66cc66; background-color: #012456">$counter</span><span style="color: #44aaaa; background-color: #012456">-le</span><span style="color: #66cc66; background-color: #012456">$fileContent</span><span style="color: #44aaaa; background-color: #012456">.</span><span style="color: #aaaa44; background-color: #012456">Count</span><span style="color: #44aaaa; background-color: #012456">;</span><span style="color: #66cc66; background-color: #012456">$counter</span><span style="color: #44aaaa; background-color: #012456">++</span>)
{ <span style="color: #66cc66; background-color: #012456">$color</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #66cccc; background-color: #012456">"Red"</span><span style="color: #66cc66; background-color: #012456">$line</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #66cc66; background-color: #012456">$fileContent</span><span style="color: #44aaaa; background-color: #012456">[</span><span style="color: #66cc66; background-color: #012456">$counter</span><span style="color: #44aaaa; background-color: #012456">-</span><span style="color: #66cccc; background-color: #012456">1</span><span style="color: #44aaaa; background-color: #012456">]</span><span style="color: #cc6666; background-color: #012456">##
Ignore comments, blank lines, curly</span><span style="color: #cc6666; background-color: #012456">##
braces, and fall-through conditional statements</span><span style="color: #cc6666; background-color: #012456">##
in coverage computation (as they are never</span><span style="color: #cc6666; background-color: #012456">##
traced in Set-PsDebug tracing</span><span style="color: #cc66cc; background-color: #012456">if</span>((<span style="color: #66cc66; background-color: #012456">$line</span><span style="color: #44aaaa; background-color: #012456">-notmatch</span><span style="color: #66cccc; background-color: #012456">'^\s*#'</span>) <span style="color: #44aaaa; background-color: #012456">-and</span> (<span style="color: #66cc66; background-color: #012456">$line</span><span style="color: #44aaaa; background-color: #012456">-notmatch</span><span style="color: #66cccc; background-color: #012456">'^\s*{\s*$'</span>) <span style="color: #44aaaa; background-color: #012456">-and</span> (<span style="color: #66cc66; background-color: #012456">$line</span><span style="color: #44aaaa; background-color: #012456">-notmatch</span><span style="color: #66cccc; background-color: #012456">'^\s*}\s*$'</span>) <span style="color: #44aaaa; background-color: #012456">-and</span> (<span style="color: #66cc66; background-color: #012456">$line</span><span style="color: #44aaaa; background-color: #012456">-notmatch</span><span style="color: #66cccc; background-color: #012456">'^\s*else'</span>) <span style="color: #44aaaa; background-color: #012456">-and</span> (<span style="color: #66cc66; background-color: #012456">$line</span><span style="color: #44aaaa; background-color: #012456">-notmatch</span><span style="color: #66cccc; background-color: #012456">'^\s*param\('</span>) <span style="color: #44aaaa; background-color: #012456">-and</span> (<span style="color: #66cc66; background-color: #012456">$line</span><span style="color: #44aaaa; background-color: #012456">.</span><span style="color: #aaaa44; background-color: #012456">Trim</span>()))
{ <span style="color: #66cc66; background-color: #012456">$possibleCoveredLines</span><span style="color: #44aaaa; background-color: #012456">++</span> } <span style="color: #cc66cc; background-color: #012456">else</span> { <span style="color: #66cc66; background-color: #012456">$color</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #66cccc; background-color: #012456">"Gray"</span> } <span style="color: #cc6666; background-color: #012456">##
If this line was hit in code coverage, colour it</span><span style="color: #cc6666; background-color: #012456">##
green</span><span style="color: #cc66cc; background-color: #012456">if</span>(<span style="color: #66cc66; background-color: #012456">$coveredLines</span><span style="color: #44aaaa; background-color: #012456">-contains</span><span style="color: #66cc66; background-color: #012456">$counter</span>)
{ <span style="color: #66cc66; background-color: #012456">$color</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #66cccc; background-color: #012456">"Green"</span><span style="color: #66cc66; background-color: #012456">$coverageCount</span><span style="color: #44aaaa; background-color: #012456">++</span> } <span style="color: #cc6666; background-color: #012456">##
Display the line in the appropriate colour</span><span style="color: #cccc66; background-color: #012456">Write-Host</span><span style="color: #cccc66; background-color: #012456">-Fore</span><span style="color: #66cc66; background-color: #012456">$color</span><span style="color: #66cc66; background-color: #012456">$line</span> } <span style="color: #cc6666; background-color: #012456">##
Output the coverage statistics</span><span style="color: #cccc66; background-color: #012456">Write-Host</span> (<span style="color: #66cccc; background-color: #012456">"Coverage
Statistics: "</span><span style="color: #44aaaa; background-color: #012456">+</span><span style="color: #66cccc; background-color: #012456">"$($coverageCount
/ $possibleCoveredLines * 100)%"</span>) </pre>
        <img width="0" height="0" src="http://www.leeholmes.com/blog/aggbug.ashx?id=ccaa6171-6c86-4d91-983f-ba40feaf225a" />
      </div>
    </content>
  </entry>
  <entry>
    <title>First Steps in Flight</title>
    <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/FirstStepsInFlight.aspx" />
    <id>http://www.leeholmes.com/blog/PermaLink,guid,b605a295-8e9a-4774-b529-06c4a73327ce.aspx</id>
    <published>2008-05-06T10:03:21.9200000-07:00</published>
    <updated>2008-05-06T20:11:22.5768742-07:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
For a long time, I've been thinking about learning to fly. One of the random long-distance-drive
conversations I like to have is, "What job would you do if you were for some reason
prevented from doing what you do now?" For me, flying has always been something I
would entertain, but only romantically. The downsides to doing it professionally are
huge -- the time away from your family and strict seniority-based promotions being
the two largest factors. So instead, I wanted to reward myself with flying lessons
the next time I thought it was appropriate. A King of the Hill episode, of all things,
changed my mind on that. 
</p>
        <p align="center">
          <img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="226" alt="image" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/FirstStepsinFlight_8B3E/image_3.png" width="204" border="0" />
        </p>
        <p>
In that episode, Hank (the father) and Peggy (the mother) were going through marital
problems, and spoke with a counselor. The counselor asked them what they wanted to
do when they retired -- something they had been planning toward for a long time. Their
dream was to buy some motorcycles and tour the United States together. The counselor's
suggestion was simple -- holding off on buying the bikes doesn't really help anything,
so just buy the darn things and start enjoying yourselves! The cross-country tours
can wait until you have the time to do them, but little local trips can happen right
now. 
</p>
        <p>
That started the slow chemical reaction in my brain, which ultimately led me to start
investigating flying lessons more seriously. 
</p>
        <p>
My typical obsessive online research turned up lots of information about learning
to fly. Tom Unger’s “<a href="http://www.tumtum.com/flight/lessons/FlightLesson_1.shtml">Flying
Lessons</a>” journal was indispensable, gave a lot of great background information,
and what to expect with the process. However, I found very little about picking a
flight school around the Seattle area, and sent a mail to an internal mailing list
asking for opinions. Four suggestions came up most frequently:
</p>
        <ul>
          <li>
Pro-Flight Aviation: <a href="http://www.flyproflight.com/">http://www.flyproflight.com/</a></li>
          <li>
Galvin Flying Service: <a href="http://www.galvinflying.com/">http://www.galvinflying.com/</a></li>
          <li>
Acu-Wings: <a href="http://www.acuwings.com/">http://www.acuwings.com/</a></li>
          <li>
Alternate Air: <a href="http://www.alternateair.com/">http://www.alternateair.com/</a></li>
        </ul>
        <p>
I ruled out Galvin immediately – their responses to customer complaints on <a href="http://www.airnav.com/airport/KBFI/GALVIN">http://www.airnav.com/airport/KBFI/GALVIN</a> were
ridiculous and showed complete disregard for their customers. 
</p>
        <p>
I ended up looking for operations out of the Renton Municipal Airport (KRNT) as my
primary factor. It’s close to my house, and commute time seems to be the most important
element in choosing a base. Airport traffic and other factors can be learned at other
airports (such as Crest Airpark for its crazy small field, and Boeing Field for its
busy airspace,) since most of your practice take-offs and landings come from explicit
training exercises (as opposed to being dictated by the base you fly from.)
</p>
        <p>
I first checked out Pro-Flight during a 9:00 AM intro flight, taking up a well-loved
Cessna 172. Introductory flights are an amazing deal – even as a leisure activity.
They cost under $100 for a scenic tour of the Puget Sound, and you get to do most
of the flying yourself. 
</p>
        <p align="center">
          <img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="191" alt="image" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/FirstStepsinFlight_8B3E/image_6.png" width="234" border="0" />        <img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="191" alt="image" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/FirstStepsinFlight_8B3E/image_9.png" width="234" border="0" /></p>
        <p>
The biggest challenge (as compared to driving a car) was adapting to a new mental
model, and adapting to a very manual control system. When taxiing, having <a href="http://www.harmon.com/RudderPedals.htm">4
control surfaces at my feet</a> was pretty complex – seeing as I kept on thinking
of it like controlling handles on a bike steering column. I would instinctively push
right expecting to turn left, but got the hang of it more when I thought about it
as differential braking (even when I was using the nose wheel part of the control.)
My only point of minor helmet fire came at this point – when we needed to use differential
braking to make a turn, but my feet were only on the nose wheel portion of the control
(as suggested by the instructor.)
</p>
        <p align="center">
          <img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="170" alt="image" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/FirstStepsinFlight_8B3E/image_14.png" width="244" border="0" />
        </p>
        <p>
          <br />
Oh, and ignoring my internal alarm bells is hard enough when starting an automatic
transmission car without depressing a clutch – an airplane was much worse.
</p>
        <p>
What surprised me most was how much input you had to give the controls. It felt like
there was a good 8 inches of travel in the foot pedals – much more than I was expecting.
I was sure I was going to rip the knob off of the dash when I was priming the engine.
</p>
        <p>
After we taxied, takeoff went pretty well. There was no traffic, so we didn’t burn
engine hours waiting in line. Actually leaving the pavement was weird, as I again
was expecting to need a subtle touch. After pushing the throttle forward slowly like
you see them do on big airplanes, the instructor told me to just gun it :) The climb
felt surprisingly manual as well, although the instructor did give me a rate of ascent
to aim for, which helped a lot. Once I visually leveled off, the instructor pointed
out that I was still climbing.  The nose definitely points a lot lower during
steady flight than it does during takeoff, but adapting to that came shortly.
</p>
        <p>
We did some minor orientation and directional work, and even got to do some nice steep
turns. The ceiling was really indefinite, and we had to avoid some cloud cover. The
runway approach went really well as we approached from the North. I guess since there
was no traffic, we basically did the 45 degree entry directly into an extended final
for the <a href="http://en.wikipedia.org/wiki/Airfield_traffic_pattern">traffic pattern</a>.
Lining up felt pretty natural, although I made the approach too low – I was aiming
for the numbers instead of the first dash.
</p>
        <p align="center">
          <a href="http://en.wikipedia.org/wiki/Airfield_traffic_pattern">
            <img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="222" alt="image" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/FirstStepsinFlight_8B3E/image_17.png" width="513" border="0" />
          </a>
        </p>
        <p>
          <br />
So all-in-all, it was a great time up – and they seem like a very capable flight school.
</p>
        <p>
The next day, I took a flight with AcuWings, and I can understand why there is so
much support for them. Their office was a little hard to find at first (barely any
signs on an already nondescript office building,) but they seemed well-run. Their
office was off-base, so we had a very short drive across the road to the actual airplanes.
They will be getting a building on the field in the near future, so that will be convenient.
I followed the owner to the field who, despite his precision flying and deep knowledge
of flight rules, failed to use his signal light even once.
</p>
        <p>
For that intro flight, we flew their Cirrus SR20 (since I wanted to try a completely
different airplane.) Different it was – an ’07 model, tons of electronics, tons of
power, and no traditional yoke! You control the throttle with your right hand, and
control the direction with a joystick-like device on your left. The weather was beautiful:
in the mid-60s with unlimited ceiling, and 10 miles of visibility. This made for a
much busier airport, which was also good to experience.
</p>
        <p align="center">
          <img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="186" alt="image" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/FirstStepsinFlight_8B3E/image_20.png" width="244" border="0" />     <img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="190" alt="image" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/FirstStepsinFlight_8B3E/image_23.png" width="244" border="0" /></p>
        <p>
          <br />
My daughter joined us on this ride -- an experience I was thrilled to have been able
to share with her.
</p>
        <p>
The aircraft was a lot more responsive than the Cessna, so I initially pitched it
up to like 1100 ft/min correcting to the proper 700 ft/min or so during takeoff. We
climbed to 3500 feet, and were treated to an awesome view of Mount Rainier. With all
of the interactive electronics and gadgets, I had to consciously stop myself from
getting too absorbed in the pretty displays, and instead use the cockpit window for
what it was intended for :) We did some more level turns, played with the autopilot
a bit, and practiced throttle control.
</p>
        <p>
I was amazed to learn that airplanes will “skip” in the atmosphere. If you let them
go with wings level and drop the power, they will just settle on a new lower altitude
that matches the new power.
</p>
        <p>
After about half an hour in the air, we came back to the Renton base and ran a more
typical approach. We flew parallel to the runway (which I was surprised to realize
was 30ish degrees off of the North-South axis,) and made a short final from the South
due to heavy traffic. The landing went well, probably because it was almost entirely
under the control of my instructor :)
</p>
        <p>
After landing, it became very clear to me that this hobby has much more in store for
me. 
</p>
        <img width="0" height="0" src="http://www.leeholmes.com/blog/aggbug.ashx?id=b605a295-8e9a-4774-b529-06c4a73327ce" />
      </div>
    </content>
  </entry>
  <entry>
    <title>PowerShell Crash - Your Help Needed</title>
    <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/PowerShellCrashYourHelpNeeded.aspx" />
    <id>http://www.leeholmes.com/blog/PermaLink,guid,ff2c2c0a-5481-4005-a150-002229ca9556.aspx</id>
    <published>2008-03-31T22:23:22.7913744-07:00</published>
    <updated>2008-03-31T22:23:22.7913744-07:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
A few years ago, we experimented with a <a href="http://www.leeholmes.com/blog/MonadBreakingChangeAlignmentWithLivecomStrategy.aspx">"Live"
version of Get-ChildItem</a> that retrieved elegant textual context-based advertisements
from the internet as you used PowerShell.
</p>
        <p>
This has been very successful, but unfortunately, a small subset of our trial user
population has experienced crashing behaviour due to these new shell modifications.
We have been unable to reproduce the issue in our labs, so the users in question have
sent us screen casts of the crash. Even still, we've been looking at the code so long
that we still can't confirm the problem.
</p>
        <p>
It would really help the PowerShell team if you could take a look and help us identify
the issue.
</p>
        <p>
I've posted the screen cast here: <a title="http://www.leeholmes.com/projects/powershell_crash/" href="http://www.leeholmes.com/projects/powershell_crash/">http://www.leeholmes.com/projects/powershell_crash/</a>.
Make sure you have sound enabled, as that is supposedly an important factor.
</p>
        <p>
          <a href="http://www.leeholmes.com/projects/powershell_crash/">
            <img src="http://www.leeholmes.com/blog/content/binary/dir-LIVE.gif" />
          </a>
        </p>
        <img width="0" height="0" src="http://www.leeholmes.com/blog/aggbug.ashx?id=ff2c2c0a-5481-4005-a150-002229ca9556" />
      </div>
    </content>
  </entry>
  <entry>
    <title>BgShell &amp;ndash; Background Shell</title>
    <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/BgShellNdashBackgroundShell.aspx" />
    <id>http://www.leeholmes.com/blog/PermaLink,guid,30423581-e743-43fa-bbbb-1f641b03419e.aspx</id>
    <published>2008-03-28T00:33:12.1640000-07:00</published>
    <updated>2008-03-28T00:37:11.0081250-07:00</updated>
    <content type="html">&lt;div class=Section1&gt;
&lt;p class=MsoTitle style="PADDING-RIGHT: 0in; PADDING-LEFT: 0in; PADDING-BOTTOM: 4pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0in; BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none" align=center&gt;
&lt;img src="http://www.leeholmes.com/blog/content/binary/bgshell.gif" border=0&gt;
&lt;/p&gt;
&lt;p class=MsoTitle style="PADDING-RIGHT: 0in; PADDING-LEFT: 0in; PADDING-BOTTOM: 4pt; BORDER-TOP-STYLE: none; PADDING-TOP: 0in; BORDER-BOTTOM: #4f81bd 1pt solid; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none" align=center&gt;
[Download: &lt;a href="http://www.leeholmes.com/projects/BgShell/BgShell.zip"&gt;BgShell.zip&lt;/a&gt;]
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
BgShell is a proof of concept PowerShell host that explores the idea of "PowerShell
Everywhere."
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
What if PowerShell was always at your fingertips – making quick calculations easier
than launching Windows Calculator? Or, making a “quick ipconfig” with PowerShell just
a keystroke away? BgShell offers PowerShell Everywhere, and instant gratification.
Simply press Control-Alt-B, and the BgShell interface appears immediately. Press Control-Alt-B
again to hide the shell. Closing the window only hides the shell, keeping it instantly
available for your next command.
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
The concept of “PowerShell Everywhere” goes further than that, though. What if you
could bind PowerShell script blocks to arbitrary keystrokes? BgShell supports that,
too. If you use any keyboard Macro programs, BgShell can likely replace them -- and
with a more powerful engine and scripting language, at that. 
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
BgShell lets you define these in a host-specific profile. If you tend to write the
same thing over and over, just define a hotkey for it:
&lt;/p&gt;
&lt;div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: white; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid"&gt;
&lt;p class=MsoNormal style="PADDING-RIGHT: 0in; PADDING-LEFT: 0in; BACKGROUND: white; MARGIN-BOTTOM: 0pt; PADDING-BOTTOM: 0in; BORDER-TOP-STYLE: none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: green; FONT-FAMILY: " courier="courier" new??="new??"&gt;##
Boy, I type this a lot.&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; FONT-FAMILY: " courier="courier" new??="new??"&gt; 
&lt;br&gt;
&lt;span style="COLOR: #35687d"&gt;$keyMapping&lt;/span&gt;[&lt;span style="COLOR: maroon"&gt;'Control,Alt,Q'&lt;/span&gt;]
= @{&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Action = { SendString &lt;span style="COLOR: maroon"&gt;'PowerShell Rocks!'&lt;/span&gt; }&amp;nbsp; 
&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p class=MsoNormal style="BACKGROUND: white; MARGIN-BOTTOM: 0pt; LINE-HEIGHT: normal"&gt;
&lt;span style="FONT-SIZE: 12pt; FONT-FAMILY: " courier="courier" new??="new??"&gt;&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
Or, rather than batting the mouse cursor out of the way when it obscures your typing,
just press a hotkey:
&lt;/p&gt;
&lt;div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid"&gt;
&lt;p class=MsoNormal style="PADDING-RIGHT: 0in; PADDING-LEFT: 0in; PADDING-BOTTOM: 0in; BORDER-TOP-STYLE: none; PADDING-TOP: 0in; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: green; LINE-HEIGHT: 115%; FONT-FAMILY: " courier="courier" new??="new??"&gt;##
Move the annoying mouse pointer out of your way&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%; FONT-FAMILY: " courier="courier" new??="new??"&gt; 
&lt;br&gt;
&lt;span style="COLOR: #35687d"&gt;$keyMapping&lt;/span&gt;[&lt;span style="COLOR: maroon"&gt;'Control,Alt,Z'&lt;/span&gt;]
= @{&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Action = { 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Windows.Forms.Cursor]::Position = (&lt;span style="COLOR: #2b91af"&gt;New-Object&lt;/span&gt; System.Drawing.Point &lt;span style="COLOR: maroon"&gt;0&lt;/span&gt;,&lt;span style="COLOR: maroon"&gt;0&lt;/span&gt;)&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p class=MsoNormal&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
Or even bring some of your old Unix habits to the Win32 console:
&lt;/p&gt;
&lt;div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid"&gt;
&lt;p class=MsoNormal style="PADDING-RIGHT: 0in; PADDING-LEFT: 0in; PADDING-BOTTOM: 0in; BORDER-TOP-STYLE: none; PADDING-TOP: 0in; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #35687d; LINE-HEIGHT: 115%; FONT-FAMILY: " courier="courier" new??="new??"&gt;$keyMapping&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%; FONT-FAMILY: " courier="courier" new??="new??"&gt;[&lt;span style="COLOR: maroon"&gt;'Control,L'&lt;/span&gt;]
= @{ 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; KeypressHandled = { IsClassActive &lt;span style="COLOR: maroon"&gt;'ConsoleWindowClass'&lt;/span&gt; }; 
&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;## Console clear&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Action =&amp;nbsp; { SendKeys &lt;span style="COLOR: maroon"&gt;'{ESC}cls{ENTER}'&lt;/span&gt; } 
&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;span style="FONT-SIZE: 11pt; LINE-HEIGHT: 115%; FONT-FAMILY: " calibri?,?sans-serif??="calibri?,?sans-serif??"&gt;
&lt;br style="PAGE-BREAK-BEFORE: always" clear=all&gt;
&lt;/span&gt; 
&lt;p class=MsoNormal&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
At the same time, you’ve been building new habits in PowerShell. Why not cater to
them?
&lt;/p&gt;
&lt;div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid"&gt;
&lt;p class=MsoNormal style="PADDING-RIGHT: 0in; PADDING-LEFT: 0in; PADDING-BOTTOM: 0in; BORDER-TOP-STYLE: none; PADDING-TOP: 0in; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #35687d; LINE-HEIGHT: 115%; FONT-FAMILY: " courier="courier" new??="new??"&gt;$keyMapping&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%; FONT-FAMILY: " courier="courier" new??="new??"&gt;[&lt;span style="COLOR: maroon"&gt;'Control,F'&lt;/span&gt;]
= @{ 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; KeypressHandled = { IsClassActive &lt;span style="COLOR: maroon"&gt;'ConsoleWindowClass'&lt;/span&gt; }; 
&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;## Console foreach-object&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Action =&amp;nbsp; { SendString &lt;span style="COLOR: maroon"&gt;'| foreach
{ $_. }'&lt;/span&gt;; SendKeys &lt;span style="COLOR: maroon"&gt;'{LEFT}{LEFT}'&lt;/span&gt; } 
&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p class=MsoNormal&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
Keystroke automation of other programs opens up entire new realms of interactive management
potential:
&lt;/p&gt;
&lt;div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid"&gt;
&lt;p class=MsoNormal style="PADDING-RIGHT: 0in; PADDING-LEFT: 0in; PADDING-BOTTOM: 0in; BORDER-TOP-STYLE: none; PADDING-TOP: 0in; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: green; LINE-HEIGHT: 115%; FONT-FAMILY: " courier="courier" new??="new??"&gt;##
Control,Alt,C -- Convert selected text in an Outlook Message&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; LINE-HEIGHT: 115%; FONT-FAMILY: " courier="courier" new??="new??"&gt; 
&lt;br&gt;
&lt;span style="COLOR: green"&gt;## into a code sample&lt;/span&gt; 
&lt;br&gt;
&lt;span style="COLOR: #35687d"&gt;$keyMapping&lt;/span&gt;[&lt;span style="COLOR: maroon"&gt;'Control,Alt,C'&lt;/span&gt;]
= @{ 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; KeypressHandled = { IsClassActive &lt;span style="COLOR: maroon"&gt;'_WwG'&lt;/span&gt; }; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Action =&amp;nbsp; {&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #2b91af"&gt;Start-Sleep&lt;/span&gt; -m &lt;span style="COLOR: maroon"&gt;100&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendKeys &lt;span style="COLOR: maroon"&gt;"%o"&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #2b91af"&gt;Start-Sleep&lt;/span&gt; -m &lt;span style="COLOR: maroon"&gt;500&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendString &lt;span style="COLOR: maroon"&gt;"ff"&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #2b91af"&gt;Start-Sleep&lt;/span&gt; -m &lt;span style="COLOR: maroon"&gt;500&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendString &lt;span style="COLOR: maroon"&gt;"Courier
New"&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendKeys &lt;span style="COLOR: maroon"&gt;"{ENTER}"&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #2b91af"&gt;Start-Sleep&lt;/span&gt; -m &lt;span style="COLOR: maroon"&gt;500&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendKeys &lt;span style="COLOR: maroon"&gt;"%o"&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #2b91af"&gt;Start-Sleep&lt;/span&gt; -m &lt;span style="COLOR: maroon"&gt;500&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendString &lt;span style="COLOR: maroon"&gt;"fs"&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #2b91af"&gt;Start-Sleep&lt;/span&gt; -m &lt;span style="COLOR: maroon"&gt;500&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendString &lt;span style="COLOR: maroon"&gt;"9"&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SendKeys &lt;span style="COLOR: maroon"&gt;"{ENTER}"&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #2b91af"&gt;Start-Sleep&lt;/span&gt; -m &lt;span style="COLOR: maroon"&gt;500&lt;/span&gt; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;br&gt;
}&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p class=MsoNormal&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
Of course, your brain starts to hurt with so many hotkeys. In that case, maybe a memorable
phrase is better?
&lt;/p&gt;
&lt;div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: white; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid"&gt;
&lt;p class=MsoNormal style="PADDING-RIGHT: 0in; PADDING-LEFT: 0in; BACKGROUND: white; MARGIN-BOTTOM: 0pt; PADDING-BOTTOM: 0in; BORDER-TOP-STYLE: none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"&gt;
&lt;span style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: " courier="courier" new??="new??"&gt;##
Get the current date&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="PADDING-RIGHT: 0in; PADDING-LEFT: 0in; BACKGROUND: white; MARGIN-BOTTOM: 0pt; PADDING-BOTTOM: 0in; BORDER-TOP-STYLE: none; LINE-HEIGHT: normal; PADDING-TOP: 0in; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BORDER-BOTTOM-STYLE: none"&gt;
&lt;span style="FONT-SIZE: 10pt; COLOR: #35687d; FONT-FAMILY: " courier="courier" new??="new??"&gt;$stringMapping&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: " courier="courier" new??="new??"&gt;[ &lt;span style="COLOR: maroon"&gt;"**date"&lt;/span&gt; ]
= { SendString (&lt;span style="COLOR: #2b91af"&gt;Get-Date&lt;/span&gt;) }&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p class=MsoNormal&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
How about saving yourself from the tedium of template code?
&lt;/p&gt;
&lt;span style="FONT-SIZE: 9pt"&gt; 
&lt;div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 1pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 1pt; BACKGROUND: white; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid"&gt;&lt;pre&gt;&lt;span style="COLOR: green"&gt;##
Get some input from the user&lt;/span&gt; &lt;span style="COLOR: blue"&gt;function&lt;/span&gt; Get-Input
{ param (&lt;span style="COLOR: #35687d"&gt;$message&lt;/span&gt; = &lt;span style="COLOR: maroon"&gt;"Input
: "&lt;/span&gt;, &lt;span style="COLOR: #35687d"&gt;$title&lt;/span&gt; = &lt;span style="COLOR: maroon"&gt;"Inputbox"&lt;/span&gt;) &lt;span style="COLOR: #35687d"&gt;$vbs&lt;/span&gt; = &lt;span style="COLOR: #2b91af"&gt;New-Object&lt;/span&gt; -com
MSScriptControl.ScriptControl &lt;span style="COLOR: #35687d"&gt;$vbs&lt;/span&gt;.language = &lt;span style="COLOR: maroon"&gt;'vbscript'&lt;/span&gt; &lt;span style="COLOR: #35687d"&gt;$vbs&lt;/span&gt;.addcode(&lt;span style="COLOR: maroon"&gt;"function
getInput() getInput = inputbox(`"$message`",`"$title`") end function"&lt;/span&gt;) &lt;span style="COLOR: #35687d"&gt;$result&lt;/span&gt; = &lt;span style="COLOR: #35687d"&gt;$vbs&lt;/span&gt;.Eval(&lt;span style="COLOR: maroon"&gt;'getInput'&lt;/span&gt;) &lt;span style="COLOR: #35687d"&gt;$result&lt;/span&gt; } &lt;span style="COLOR: green"&gt;##
Generate a C# property&lt;/span&gt; &lt;span style="COLOR: #35687d"&gt;$stringMapping&lt;/span&gt;[ &lt;span style="COLOR: maroon"&gt;"**prop
"&lt;/span&gt; ] = { &lt;span style="COLOR: #35687d"&gt;$template&lt;/span&gt; = @" /// &amp;lt;summary&amp;gt;
/// Summary of what this property does /// &amp;lt;/summary&amp;gt; public __TYPE__ __NAME__
{ get { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; __NAMELOWER__; } set { __NAMELOWER__
= value; } } private __TYPE__ __NAMELOWER__; "@ &lt;span style="COLOR: #35687d"&gt;$type&lt;/span&gt;,&lt;span style="COLOR: #35687d"&gt;$name&lt;/span&gt; =
(Get-Input -Message &lt;span style="COLOR: maroon"&gt;"Property type and name, such as 'String
Foo': "&lt;/span&gt;) -split &lt;span style="COLOR: maroon"&gt;" "&lt;/span&gt; &lt;span style="COLOR: #35687d"&gt;$template&lt;/span&gt; = &lt;span style="COLOR: #35687d"&gt;$template&lt;/span&gt;.Replace(&lt;span style="COLOR: maroon"&gt;"__TYPE__"&lt;/span&gt;, &lt;span style="COLOR: #35687d"&gt;$type&lt;/span&gt;) &lt;span style="COLOR: #35687d"&gt;$template&lt;/span&gt; = &lt;span style="COLOR: #35687d"&gt;$template&lt;/span&gt;.Replace(&lt;span style="COLOR: maroon"&gt;"__NAME__"&lt;/span&gt;, &lt;span style="COLOR: #35687d"&gt;$name&lt;/span&gt;) &lt;span style="COLOR: #35687d"&gt;$template&lt;/span&gt; = &lt;span style="COLOR: #35687d"&gt;$template&lt;/span&gt;.Replace(&lt;span style="COLOR: maroon"&gt;"__NAMELOWER__"&lt;/span&gt;,
(&lt;span style="COLOR: #35687d"&gt;$name&lt;/span&gt;.Substring(&lt;span style="COLOR: maroon"&gt;0&lt;/span&gt;,&lt;span style="COLOR: maroon"&gt;1&lt;/span&gt;).ToLower()
+ &lt;span style="COLOR: #35687d"&gt;$name&lt;/span&gt;.Substring(&lt;span style="COLOR: maroon"&gt;1&lt;/span&gt;))) &lt;span style="COLOR: #35687d"&gt;$autoIt&lt;/span&gt;.ClipPut(&lt;span style="COLOR: #35687d"&gt;$template&lt;/span&gt;)
}&lt;/pre&gt;
&lt;/div&gt;
&lt;/span&gt; 
&lt;p class=MsoNormal&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
The sky really is the limit. 
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
For more examples, see the example profile. Place it in the same directory as your
regular PowerShell profile. BgShell surfaces this profile location through the standard &lt;span style="FONT-FAMILY: " courier="courier" new??="new??"&gt;$profile&lt;/span&gt; variable.
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p class=MsoNormal&gt;
&lt;u&gt;Note&lt;/u&gt;
&lt;/p&gt;
&lt;p class=MsoListParagraph style="TEXT-INDENT: -0.25in"&gt;
&lt;span style="FONT-FAMILY: symbol"&gt;·&lt;span times="times" new="new" roman??="roman??"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Vista
introduces security enhancements that prevent low-privilege applications from being
notified of keystrokes in (or sending keystrokes to) high-privilege applications.
BgShell is marked to run as administrator so that it can respond in elevated windows.
&lt;/p&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://www.leeholmes.com/blog/aggbug.ashx?id=30423581-e743-43fa-bbbb-1f641b03419e" /&gt;</content>
  </entry>
  <entry>
    <title>Realtime Syntax Highlighting in your PowerShell Console</title>
    <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/RealtimeSyntaxHighlightingInYourPowerShellConsole.aspx" />
    <id>http://www.leeholmes.com/blog/PermaLink,guid,22283f95-29a2-4688-b1a9-051df9f2d69b.aspx</id>
    <published>2008-02-12T00:26:56.8246250-08:00</published>
    <updated>2008-02-12T00:26:56.8246250-08:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <em>[Download: </em>
          <a title="http://www.leeholmes.com/projects/SyntaxHighlight/Start-Colourizer.zip" href="http://www.leeholmes.com/projects/SyntaxHighlight/Start-Colourizer.zip">
            <em>http://www.leeholmes.com/projects/SyntaxHighlight/Start-Colourizer.zip</em>
          </a>
          <em>]</em>
        </p>
        <p>
In our most recent CTP, we exposed PowerShell's parsing and tokenizing API for the
great benefit of ISVs and hobbyists alike. As an initial demonstration of it, <a href="http://www.leeholmes.com/blog/SyntaxHighlightingInPowerShell.aspx">Show-ColorizedContent</a> let
you display nicely formatted code listing in your console:
</p>
        <pre style="color: #eeedf0; background-color: #012456">
          <br />
PS C:\Temp&gt; .\Show-ColorizedContent.ps1 Show-ColorizedContent.ps1 ` &gt;&gt; -HighlightRanges
(4..5+1+30..33) &gt;&gt; <span style="color: #66cc66; background-color: #012456">001
&gt; </span><span style="color: #cc6666; background-color: #012456">#requires -version
2.0</span> 002 | 003 | <span style="color: #cccc66; background-color: #012456">param</span>( <span style="color: #66cc66; background-color: #012456">004
&gt; </span><span style="color: #66cc66; background-color: #012456">$filename</span><span style="color: #44aaaa; background-color: #012456">=</span> $(<span style="color: #cc66cc; background-color: #012456">throw</span><span style="color: #66cccc; background-color: #012456">"Please
specify a filename."</span>)<span style="color: #44aaaa; background-color: #012456">,</span><span style="color: #66cc66; background-color: #012456">005
&gt; </span><span style="color: #66cc66; background-color: #012456">$highlightRanges</span><span style="color: #44aaaa; background-color: #012456">=</span> @()<span style="color: #44aaaa; background-color: #012456">,</span> 006
| <span style="color: #aaaa44; background-color: #012456">[System.Management.Automation.SwitchParameter]</span><span style="color: #66cc66; background-color: #012456">$excludeLineNumbers</span>)
007 | 008 | <span style="color: #cc6666; background-color: #012456"># [Enum]::GetValues($host.UI.RawUI.ForegroundColor.GetType())
| % { Write-Host -Fore $_ "$_" }</span> (...)<br />
026 | <span style="color: #66cc66; background-color: #012456">$highlightColor</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #66cccc; background-color: #012456">"Green"</span> 027
| <span style="color: #66cc66; background-color: #012456">$highlightCharacter</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #66cccc; background-color: #012456">"&gt;"</span> 028
| 029 | <span style="color: #cc6666; background-color: #012456">## Read the text of
the file, and parse it</span><span style="color: #66cc66; background-color: #012456">030
&gt; $file</span><span style="color: #44aaaa; background-color: #012456">=</span> (<span style="color: #cccc66; background-color: #012456">Resolve-Path</span><span style="color: #66cc66; background-color: #012456">$filename</span>)<span style="color: #44aaaa; background-color: #012456">.</span><span style="color: #aaaa44; background-color: #012456">Path</span><span style="color: #66cc66; background-color: #012456">031
&gt; $content</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #aaaa44; background-color: #012456">[IO.File]</span><span style="color: #44aaaa; background-color: #012456">::</span><span style="color: #aaaa44; background-color: #012456">ReadAllText</span>(<span style="color: #66cc66; background-color: #012456">$file</span>) <span style="color: #66cc66; background-color: #012456">032
&gt; $parsed</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #aaaa44; background-color: #012456">[System.Management.Automation.PsParser]</span><span style="color: #44aaaa; background-color: #012456">::</span><span style="color: #aaaa44; background-color: #012456">Tokenize</span>(<span style="color: #66cc66; background-color: #012456">$content</span><span style="color: #44aaaa; background-color: #012456">,</span><span style="color: #aaaa44; background-color: #012456">[ref]</span><span style="color: #66cc66; background-color: #012456">$null</span>) <span style="color: #44aaaa; background-color: #012456">|</span><span style="color: #66cc66; background-color: #012456">033
&gt; </span><span style="color: #cccc66; background-color: #012456">Sort</span><span style="color: #66cccc; background-color: #012456">StartLine</span><span style="color: #44aaaa; background-color: #012456">,</span><span style="color: #66cccc; background-color: #012456">StartColumn</span> 034
| 035 | <span style="color: #cc66cc; background-color: #012456">function</span><span style="color: #66cccc; background-color: #012456">WriteFormattedLine</span>(<span style="color: #66cc66; background-color: #012456">$formatString</span><span style="color: #44aaaa; background-color: #012456">,</span><span style="color: #aaaa44; background-color: #012456">[int]</span><span style="color: #66cc66; background-color: #012456">$line</span>)
036 | { 037 | <span style="color: #cc66cc; background-color: #012456">if</span>(<span style="color: #66cc66; background-color: #012456">$excludeLineNumbers</span>)
{ <span style="color: #cc66cc; background-color: #012456">return</span> } 038 | 039
| <span style="color: #66cc66; background-color: #012456">$hColor</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #66cccc; background-color: #012456">"Gray"</span> 040
| <span style="color: #66cc66; background-color: #012456">$separator</span><span style="color: #44aaaa; background-color: #012456">=</span><span style="color: #66cccc; background-color: #012456">"|"<br /></span></pre>
        <p>
While this is very cool, we can actually push the parsing and tokenizing API even
further. How about <strong><em>real time</em></strong>?
</p>
        <p>
The first time I got this working, I actually giggled a little with glee. We're all
so used to instant gratification when it comes to syntax highlighting that we sometimes
forget about it. Until you drop into an environment that doesn't support it -- such
as Notepad.exe or the PowerShell console. But with enough chewing gum and rubber bands,
we can at least bring it into the PowerShell console.
</p>
        <blockquote>
          <p>
            <em>As an aside, the V2 CTP also includes an early alpha version of PowerShell's new
graphical host, Graphical PowerShell. Graphical PowerShell handles syntax highlighting
swimmingly, and then some. If you want even more usability improvements (such as window
resizing, tabs, and direct Unicode support,) that's where it'll be.</em>
          </p>
        </blockquote>
        <p>
The primary problem with creating a real time colourizer is that PowerShell doesn't
generate any events or notifications when you press a key. This makes cooperative
multithreading difficult, so instead we need to take a parasitic approach and dig
around in the console's screen buffer.
</p>
        <p>
PowerShell doesn't support script threading either, though, so the step toward real-time
syntax highlighting in your console is a slightly modified version of Jim Truher's
"<a href="http://jtruher.spaces.live.com/blog/cns!7143DA6E51A2628D!130.entry">Background
Jobs and PowerShell</a>" script. 
</p>
        <p>
For each job that you create, Jim's script creates a new <a href="http://msdn2.microsoft.com/en-us/library/ms569311(VS.85).aspx">System.Management.Automation.Runspaces.Runspace</a> instance,
and then executes the job in the pipeline. Since the runspace class offers an asynchronous
(non-blocking) invoke method, this effectively lets us run PowerShell code in the
background of our current process. As written, though, Jim's background job support
doesn't offer access to the variables and information of the runspace that launched
the job. While normally useful, it does limit the usefulness of jobs for parasitic
groveling! So, our main change in the New-Job script is to add a variable to the context
of new jobs: $executionContextProxy. Through this variable, child jobs can access
the variables and other information of the parent that spawned them. This update is
included in the <a href="[Download: http://www.leeholmes.com/projects/SyntaxHighlight/Start-Colourizer.zip]">attached
zip file</a>.
</p>
        <p>
Once we can launch jobs in the background that have access to our environment, the
next step is the actual colourizer. This script runs as the background job. It starts
at the bottom of the console buffer (where your cursor is,) and scans upward (and
left) until it finds the last line of your prompt. It takes that rectangle, uses the
parser API to determine how to colourize it, and then swiftly replaces that section
of your console screen buffer with the colourized version.
</p>
        <blockquote>
          <p>
            <em>I say "quickly" here to mean "as quickly as possible." There
is a slight chance that the background job will swap in the colourized buffer after
you've typed some more. It takes some pretty drastic measures to avoid this, but the
occasional visual glitch will happen. This is only visual, however. Once you press
ENTER, PowerShell will still execute the command you typed.</em>
          </p>
        </blockquote>
        <p>
Many prompts use the Write-Host to add colourized prompts to the console, and return
only a single space in the prompt() function. Since the colourizer can't know exactly
how your prompt will appear on the screen, you need to tell it what the last line
looks like. In your prompt function, set a global variable (called "promptMarker")
to have the same text as the last line of your prompt. For example, if your prompt
displays:
</p>
        <p>
PS:15 &gt;
</p>
        <p>
on the screen, then set $GLOBAL:promptMarker = "PS:15 &gt;"
</p>
        <p align="left">
Now, with New-Job.ps1 and Start-Colourizer.ps1 in your path (and a prompt that updates
the promptMarker variable,) start the colourizer as a job:
</p>
        <p align="center">
          <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="354" alt="image" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/SyntaxHighlightinginyourPowerShellConsol_13B95/image_3.png" width="644" border="0" />
        </p>
        <p>
Now, PowerShell updates your console with context-sensitive syntax highlighting as
you type.
</p>
        <p>
If you find the default console colours to be ugly, the included Set-ConsoleColourTable.ps1
script tones them down to something much easier on the eyes.
</p>
        <p>
          <em>[Download: </em>
          <a title="http://www.leeholmes.com/projects/SyntaxHighlight/Start-Colourizer.zip" href="http://www.leeholmes.com/projects/SyntaxHighlight/Start-Colourizer.zip">
            <em>http://www.leeholmes.com/projects/SyntaxHighlight/Start-Colourizer.zip</em>
          </a>
          <em>]</em>
        </p>
        <p>
Enjoy!
</p>
        <img width="0" height="0" src="http://www.leeholmes.com/blog/aggbug.ashx?id=22283f95-29a2-4688-b1a9-051df9f2d69b" />
      </div>
    </content>
  </entry>
  <entry>
    <title>PowerShell Cookbook Sample Chapter: Environmental Awareness</title>
    <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/PowerShellCookbookSampleChapterEnvironmentalAwareness.aspx" />
    <id>http://www.leeholmes.com/blog/PermaLink,guid,07707b70-f099-4808-af75-2d802fe4ca20.aspx</id>
    <published>2007-12-17T11:05:55.3494870-08:00</published>
    <updated>2007-12-17T11:05:55.3494870-08:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
When O’Reilly put up the overview page for the Windows PowerShell Cookbook, the sample
chapter was originally “Looping and Flow Control.” While a useful chapter in its own
right, it didn’t really highlight the solution-oriented focus the book takes.
</p>
        <p>
They’ve now updated the sample chapter to one much more representative: Environmental
Awareness.
</p>
        <p>
The goal of this chapter is to help you work with the global environment (environment
variables and common system paths,) and script’s environment (its location, name,
and invocation info.)
</p>
        <p>
It covers:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <em>14. Environmental Awareness<br />
       14.0 Introduction   
<br />
       14.1 View and Modify Environment Variables   
<br />
       14.2 Access Information About Your Command's
Invocation   
<br />
       14.3 Program: Investigate the InvocationInfo
Variable   
<br />
       14.4 Find Your Script's Name   
<br />
       14.5 Find Your Script's Location   
<br />
       14.6 Find the Location of Common System Paths   
<br />
       14.7 Program: Search the Windows Start Menu   
<br />
       14.8 Get the Current Location   
<br />
       14.9 Safely Build File Paths Out of Their Components   
<br />
       14.10 Interact with PowerShell's Global Environment  </em>
          </p>
        </blockquote>
        <p>
You can download it by following the sample chapter link at the <a href="http://www.oreilly.com/catalog/9780596528492/">book’s
overview page</a>.<br /></p>
        <img width="0" height="0" src="http://www.leeholmes.com/blog/aggbug.ashx?id=07707b70-f099-4808-af75-2d802fe4ca20" />
      </div>
    </content>
  </entry>
  <entry>
    <title>PowerShell's -EQ Operator: Reference Equality vs Value Equality</title>
    <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/PowerShellsEQOperatorReferenceEqualityVsValueEquality.aspx" />
    <id>http://www.leeholmes.com/blog/PermaLink,guid,ec2c6aeb-f4a2-4e70-ad06-63ff9204bdf7.aspx</id>
    <published>2007-12-05T09:43:41.8137500-08:00</published>
    <updated>2007-12-05T09:43:41.8137500-08:00</updated>
    <content type="html">&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="COLOR: #1f497d"&gt;&lt;font size=3&gt;&lt;font face=Calibri&gt;A question recently came
up asking why the -eq operator doesn't work for two different (but equal) SecureStrings.&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="COLOR: #1f497d"&gt;&lt;font size=3&gt;&lt;font face=Calibri&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="COLOR: #1f497d"&gt;&lt;font size=3&gt;&lt;font face=Calibri&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;By
default, almost all environments (the .NET Framework included) test if two things
are exactly the same – that they are stored in the same place in memory. This is called
reference equality.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="COLOR: #1f497d"&gt;
&lt;o:p&gt;
&lt;font face=Calibri size=3&gt;&amp;nbsp;&lt;/font&gt;
&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;[D:\documents\WindowsPowerShell]&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;PS:14 &amp;gt;
$test = Read-Host -AsSecureString&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;****&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;[D:\documents\WindowsPowerShell]&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;PS:15 &amp;gt;
[Object]::ReferenceEquals($test, $test)&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;True&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;[D:\documents\WindowsPowerShell]&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;PS:16 &amp;gt;
$test -eq $test&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;True&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="COLOR: #1f497d"&gt;
&lt;o:p&gt;
&lt;font face=Calibri size=3&gt;&amp;nbsp;&lt;/font&gt;
&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="COLOR: #1f497d"&gt;&lt;font size=3&gt;&lt;font face=Calibri&gt;That’s not usually what
people want, so each individual type of object is (optionally) responsible for supporting
a value-based equality test. They do this by implementing interfaces (software contracts)
called IComparable and / or IEquatable:&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="COLOR: #1f497d"&gt;
&lt;o:p&gt;
&lt;font face=Calibri size=3&gt;&amp;nbsp;&lt;/font&gt;
&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;[D:\documents\WindowsPowerShell]&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;PS:17 &amp;gt;
$string1 = "Test"&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;[D:\documents\WindowsPowerShell]&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;PS:18 &amp;gt;
$string2 = "Test"&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;[D:\documents\WindowsPowerShell]&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;PS:19 &amp;gt;
[Object]::ReferenceEquals($string1, $string2)&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;False&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="COLOR: #1f497d"&gt;
&lt;o:p&gt;
&lt;font face=Calibri size=3&gt;&amp;nbsp;&lt;/font&gt;
&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;[D:\documents\WindowsPowerShell]&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;PS:20 &amp;gt;
[String].GetInterfaces()&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;IsPublic
IsSerial Name&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;--------
-------- ----&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;True&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
False&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;IComparable&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;True&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
False&amp;nbsp;&amp;nbsp;&amp;nbsp; ICloneable&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;True&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
False&amp;nbsp;&amp;nbsp;&amp;nbsp; IConvertible&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;True&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
False&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;IComparable`1&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;True&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
False&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerable`1&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;True&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
False&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerable&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;True&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
False&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;IEquatable`1&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: red; FONT-FAMILY: 'Courier New'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;[D:\documents\WindowsPowerShell]&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;PS:21 &amp;gt;
$string1 -eq $string2&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;True&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="COLOR: #1f497d"&gt;&lt;font size=3&gt;&lt;font face=Calibri&gt;The implementors of the
SecureString class have chosen to not implement these contracts, so PowerShell supports
only reference equality on these types:&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="COLOR: #1f497d"&gt;
&lt;o:p&gt;
&lt;font face=Calibri size=3&gt;&amp;nbsp;&lt;/font&gt;
&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;[D:\documents\WindowsPowerShell]&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;PS:30 &amp;gt;
[System.Security.SecureString].GetInterfaces()&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;IsPublic
IsSerial Name&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;--------
-------- ----&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;True&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
False&amp;nbsp;&amp;nbsp;&amp;nbsp; IDisposable&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;[D:\documents\WindowsPowerShell]&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;PS:31 &amp;gt;
$test1 = Read-Host -AsSecureString&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;****&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;[D:\documents\WindowsPowerShell]&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;PS:32 &amp;gt;
$test2 = Read-Host -AsSecureString&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;****&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;[D:\documents\WindowsPowerShell]&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;PS:33 &amp;gt;
$test1 -eq $test2&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt 0.5in"&gt;
&lt;span style="FONT-SIZE: 9pt; COLOR: #1f497d; FONT-FAMILY: 'Courier New'"&gt;False&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="COLOR: #1f497d"&gt;
&lt;o:p&gt;
&lt;font face=Calibri size=3&gt;&amp;nbsp;&lt;/font&gt;
&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.leeholmes.com/blog/aggbug.ashx?id=ec2c6aeb-f4a2-4e70-ad06-63ff9204bdf7" /&gt;</content>
  </entry>
  <entry>
    <title>Guitar Hero 3 ... for Drums</title>
    <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/GuitarHero3ForDrums.aspx" />
    <id>http://www.leeholmes.com/blog/PermaLink,guid,c46ec161-0531-4032-b085-bd7d282e414c.aspx</id>
    <published>2007-11-27T20:35:28.1780000-08:00</published>
    <updated>2007-11-27T23:28:09.1471250-08:00</updated>
    <content type="html">&lt;p&gt;
I'm not particularly a drum fan, but this is an &lt;a href="http://www.youtube.com/watch?v=JbkypkD7B-U"&gt;amazing
feat of skill and technology&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;div class=wlWriterSmartContent id=scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:22ca29d5-5fab-4c8c-945b-ff462b307545 style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;
&lt;div id=2d6843bb-f453-4309-97bf-4ca82d98a922 style="PADDING-RIGHT: 0px; DISPLAY: inline; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px"&gt;
&lt;div align=center&gt;&lt;a href="http://www.youtube.com/watch?v=JbkypkD7B-U&amp;amp;rel=1" target=_new&gt;&lt;img alt="" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/GuitarHero3.forDrums_12195/video52b79cb9fad8.jpg" onload="var downlevelDiv = document.getElementById('2d6843bb-f453-4309-97bf-4ca82d98a922'); downlevelDiv.innerHTML = &amp;quot;&lt;div&gt;&lt;object width=\&amp;quot;425\&amp;quot; height=\&amp;quot;350\&amp;quot;&gt;&lt;param name=\&amp;quot;movie\&amp;quot; value=\&amp;quot;http://www.youtube.com/v/JbkypkD7B-U&amp;amp;rel=1\&amp;quot;&gt;&lt;\/param&gt;&lt;param name=\&amp;quot;wmode\&amp;quot; value=\&amp;quot;transparent\&amp;quot;&gt;&lt;\/param&gt;&lt;embed src=\&amp;quot;http://www.youtube.com/v/JbkypkD7B-U&amp;amp;rel=1\&amp;quot; type=\&amp;quot;application/x-shockwave-flash\&amp;quot; wmode=\&amp;quot;transparent\&amp;quot; width=\&amp;quot;425\&amp;quot; height=\&amp;quot;350\&amp;quot;&gt;&lt;\/embed&gt;&lt;\/object&gt;&lt;\/div&gt;&amp;quot;;" galleryimg="no"&gt;&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
&lt;em&gt;Since I injured my middle left finger playing Guitar Hero 2 way too much when
it came out, I've been dying to get back to playing it. ... so I thought "wouldn't
it be great to be able to play Guitar Hero on the drums?" So I thought about how that
might be accomplished... researched, implemented, borrowed, and here I outline the
finished product.&lt;/em&gt; 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Even just listening to the drum kit during the song sounds great. For more information,
Egyokeo has also been kind enough to &lt;a href="http://egyokeo.com/midihero/"&gt;outline
the full build&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.leeholmes.com/blog/aggbug.ashx?id=c46ec161-0531-4032-b085-bd7d282e414c" /&gt;</content>
  </entry>
  <entry>
    <title>PowerShell Cookbook vs PowerShell in Action</title>
    <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/PowerShellCookbookVsPowerShellInAction.aspx" />
    <id>http://www.leeholmes.com/blog/PermaLink,guid,ce9ac25b-6664-4a39-8a0a-3d64fc38c5d3.aspx</id>
    <published>2007-11-20T19:50:47.8312500-08:00</published>
    <updated>2007-11-20T19:50:47.8312500-08:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
The ACoupleOfAdmins blog recently posted a <a href="http://acoupleofadmins.com/2007/11/20/book-review-windows-powershell-cookbook/">book
review</a> of the PowerShell Cookbook (and were kind enough to also write an <a href="http://www.amazon.com/review/R3633AAEKYVRPN/ref=cm_cr_pr_viewpnt#R3633AAEKYVRPN">Amazon
Review</a>.) They bring up some excellent points. Mainly,
</p>
        <blockquote>
          <p>
            <em>The Windows PowerShell Cookbook will stay on my shelf as a reference book (for
the code samples), but I would look to other resources first (e.g. Windows PowerShell
In Action by Bruce Payette), if you need a resource to help learn PowerShell.</em>
          </p>
        </blockquote>
        <p>
I thought long and hard about the depth and breadth of the book. One theme they're
picking up on is that the PowerShell Cookbook is not a language focused book, and
does not go into gritty detail about each language feature. This is intentional, as
I wanted the book to have a very clear and unique value. We already have one PowerShell
in Action, so there's really not a need for another.
</p>
        <p>
One thing that's missed by the review is the implicit <a href="http://en.wikipedia.org/wiki/False_dichotomy">False
Dichotomy</a> -- that you should only have one book on PowerShell. The PowerShell
Cookbook is intended to be a reference book (for its code samples and pre-packaged
solutions,) while PowerShell in Action is intended to be a guided PowerShell tutorial.
There is very little overlap between Bruce's book and the PowerShell Cookbook, and
both provide significant value.
</p>
        <p>
Since both Bruce and I wrote books with the intention to benefit the PowerShell community,
it would not be in the best interest of anybody to have competing books!
</p>
        <img width="0" height="0" src="http://www.leeholmes.com/blog/aggbug.ashx?id=ce9ac25b-6664-4a39-8a0a-3d64fc38c5d3" />
      </div>
    </content>
  </entry>
  <entry>
    <title>3rd Parties and PowerShell Execution Policies</title>
    <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/3rdPartiesAndPowerShellExecutionPolicies.aspx" />
    <id>http://www.leeholmes.com/blog/PermaLink,guid,9f9a203a-4cfa-47ae-83e2-28138b3d70e8.aspx</id>
    <published>2007-11-19T17:37:04.6281250-08:00</published>
    <updated>2007-11-19T17:37:04.6281250-08:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
A question came up on the newsgroup recently about why Exchange changes PowerShell’s
execution policy from “Restricted” to “RemoteSigned.” Doesn’t that lower PowerShell’s
security?
</p>
        <p>
The "Restricted" execution policy isn't intended to be something that PowerShell users
live with forever. It's a safe default that protects non PowerShell users from being
impacted by PowerShell-based malware.
</p>
        <p>
For example, many home users had never used VBScript, but still got bitten by the
flurry of WSH-based viruses that got mailed to them. PowerShell's Restricted execution
policy solves this. To an attacker, a computer that has never used PowerShell is the
same as a computer that doesn't have PowerShell installed at all. And since attackers
care look to affect the largest number of computers possible, PowerShell becomes a
less attractive vehicle for their attack. That, in turn, makes PowerShell users safer
too. Given all of PowerShell’s security barbs, an attacker is better off using executables
or other popular scripting languages as an attack vehicle.
</p>
        <p>
So in light of all this, the Exchange team updates the execution policy to RemoteSigned
by our recommendation.
</p>
        <p>
If you are a vendor that ships PowerShell scripts as an integral part of your offering
(not just cmdlets,) you should absolutely expect that your users will want to run
them. It would be a poor user experience if they had to install your product, and
then change their execution policy when they try to use it. There’s also the very
real threat of them just trying to make the message go away and picking a needlessly
lax execution policy (such as Unrestricted.)
</p>
        <p>
In this situation, we recommend that:
</p>
        <ul>
          <li>
You sign your scripts with a real Authenticode code signing certificate</li>
          <li>
During installation, you change the execution policy to AllSigned if it is currently
Restricted. If it is anything but Restricted, leave it alone.</li>
          <li>
If your installer supports silent installation, offer an option to not modify the
execution policy.</li>
        </ul>
        <p>
To clarify the “leave it alone” point – a non-default execution policy has been put
there for a reason. While you might want to increase security to change the execution
policy to AllSigned, it is more likely that you will inadvertently break other installed
products, or parts of their IT infrastructure that depends on unsigned scripts.
</p>
        <p>
If you do not have a code signing certificate, we recommend getting one! If you cannot,
then your installer should prompt the user to change the execution policy to RemoteSigned
if it is currently Restricted. If it is anything but Restricted, leave it alone.
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <em>“&lt;This product&gt; includes scripts that help you &lt;manage Active Directory,
etc.&gt; Your current PowerShell script execution policy will prevent these scripts
from running. Would you like to update the execution policy to allow these scripts
to run?” ([Yes – Default] / No / Cancel)</em>
          </p>
        </blockquote>
        <p>
Now what about Exchange? Surely they can afford a code signing certificate!
</p>
        <p>
From their design and user research, they know that a vast majority of their user
base will write their own scripts, or run scripts from the community. When they do
that, they will ultimately get our execution policy warning, and be forced to make
a decision. The most secure decision they can make is the RemoteSigned execution policy,
so the Exchange installer makes that decision on their behalf.
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://www.leeholmes.com/blog/aggbug.ashx?id=9f9a203a-4cfa-47ae-83e2-28138b3d70e8" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Laughing babies are contagious</title>
    <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/LaughingBabiesAreContagious.aspx" />
    <id>http://www.leeholmes.com/blog/PermaLink,guid,4415ec54-8d60-439f-bb4d-545196c389d4.aspx</id>
    <published>2007-11-08T16:16:07.5310000-08:00</published>
    <updated>2007-11-08T20:21:54.4843750-08:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Here's a nice light-hearted video if you need a laugh :)
</p>
        <p>
          <embed pluginspage="http://macromedia.com/go/getflashplayer" src="http://images.video.msn.com/flash/soapbox1_1.swf" width="432" height="364" type="application/x-shockwave-flash" flashvars="c=v&amp;v=e566b2b8-fe4d-45b3-988f-ef4f998888f2&amp;ifs=true&amp;fr=msnvideo&amp;mkt=en-US&amp;brand=" allowfullscreen="true" base="http://images.video.msn.com" quality="high">
          </embed>
          <br />
          <a title="William laughing" href="http://video.msn.com/video.aspx?vid=e566b2b8-fe4d-45b3-988f-ef4f998888f2" target="_new">Video:
William laughing</a>
        </p>
        <p>
 
</p>
        <img width="0" height="0" src="http://www.leeholmes.com/blog/aggbug.ashx?id=4415ec54-8d60-439f-bb4d-545196c389d4" />
      </div>
    </content>
  </entry>
  <entry>
    <title>Syntax Highlighting in PowerShell</title>
    <link rel="alternate" type="text/html" href="http://www.leeholmes.com/blog/SyntaxHighlightingInPowerShell.aspx" />
    <id>http://www.leeholmes.com/blog/PermaLink,guid,753e4111-dd26-4113-9899-57a15a4c4004.aspx</id>
    <published>2007-11-06T22:22:07.9210000-08:00</published>
    <updated>2007-11-06T22:24:27.8593750-08:00</updated>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Since we just released a <a href="http://blogs.msdn.com/powershell/archive/2007/11/06/the-community-technology-preview-ctp-of-windows-powershell-2-0.aspx">CTP
of PowerShell V2</a>, I thought I'd share a handy little script to demonstrate one
of the new APIs we introduced: <font face="Courier New"><a href="http://www.leeholmes.com/projects/ShowColorizedContent/Show-ColorizedContent.zip">Show-ColorizedContent.ps1</a></font>. 
</p>
        <p>
This CTP introduces a new tokenizer API that lets you work with PowerShell script
content the same way that our parser does -- as a collection of items (tokens) that
represent the underlying structure of that script Until now, any tool that works with
the data of a PowerShell script needs to parse the script on its own -- usually with
fragile regular expressions or other means. 
</p>
        <p>
This often works, but usually falls apart on complex scripts:
</p>
        <p align="center">
          <img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="149" alt="image" src="http://www.leeholmes.com/blog/content/binary/WindowsLiveWriter/SyntaxHighlightinginPowerShell_1225E/image_8.png" width="244" bord