Yearly Archives: 2007

You are browsing the site archives by year.

Reading IIS.NET Blogs (or any RSS) with Powershell

Being a member of the IIS team, I often find myself checking blog posts to see what the members of the product team are blogging about.  However, since Powershell came out, I find myself doing more and more work on my scripts. It’s a bit annoying to have to jump out of Powershell to go read blog posts.  As such, I’ve written a few quick scripts to help me read IIS.NET from my pretty blue shell. For those of you who are already familiar with powershell and don’t want to read the long blog post, you can download my blog script from the DownloadCENTER: http://www.iis.net/downloads/default.aspx?tabid=34&g=6&i=1387 

Setting up your Powershell environment


To start, I’ve written a few supporting functions in my profile.  These functions help me keep my scripts organized and, since I change my scripts quite often, it helps me to sign them as well. 
First off, if you haven’t created your own certificate for signing code, please go back and take a look at my first Powershell blog post that give you the details on how to do this.  
Next, we need to add a few things to your Powershell profile.  To open your Powershell profile from within Powershell, type: 

PS > notepad $profile 
First, I add a function to allow us to easily sign our scripts (assuming you have created a cert to sign them wth): 

## Sign a file
##-------------------------------------------
function global:Sign-Script ( [string] $file )
{
     $cert = @(Get-ChildItem cert:CurrentUserMy -codesigning)[0]
     Set-AuthenticodeSignature $file $cert
}
set-alias -name sign -value sign-script

The next function is used to help me organize things. I have several scripts for various work environments.  I like to organize them by function. So, I keep my IIS scripts in an “IIS” directory, my common scripts in a “common” directory and so on.  Inside each of my script directories, I keep a “load.ps1” script that I can  use to initialize any of my work environments.  Lastly, I create a Powershell drive that matches the work environment name so I can get to my scripts easily. The function below does all the work for me. 

## Create a Drive
##-------------------------------------------
function global:New-Drive([string]$alias)
{
     $path = (join-path -path $global:profhome -childpath $alias)
     if( !(Test-Path $path ) )
     {
          ## Create the drive's directory if it doesn't exist
          new-item -path $global:profhome -name $alias -type directory
     }
     else
     {
          ## Execute the load script for this drive if one exists
          $loadscript = (join-path -path $path -childpath "load.ps1")
          if( Test-Path $loadscript)
          {
               $load = &$loadscript
          }
     }
     # Create the drive
     new-Psdrive -name $alias -scope global -Psprovider FileSystem -root $path
}

Within my profile, I simply call this function and pass in an alias. When the function executes it will create a directory with the alias name, if it doesn’t exist already. If the directory does exist, it will check for the load.ps1 file inside that path and execute it. Lastly, it will create powershell drive. I have the following calls added to my profile below: 

## Custom PS Drives
##-------------------------------------------
New-Drive -alias "common"
New-Drive -alias "iis"

Go ahead and save your profile now and type these commands: 

PS > Set-ExecutionPolicy Unrestricted
PS > &$profile
PS > Sign $profile
PS > Set-ExecutionPolicy AllSigned

 
The first command sets Powershell into unrestricted mode. This is because we need to execute the profile script and it hasn’t been signed yet.  The next command executes the profile. The third command uses the “sign” function that our profile script loaded. Since our profile is now signed, we can set our execution policy back to AllSigned. AllSigned means that Powershell will execute scripts as long as they are signed. 

From this point on, we can make changes to our profile and simply call our sign function again before we close our Powershell instance. The next instance of powershell that is opened will have our changes.  

Creating / Using Blog Functionality


Now that we have our environment set up, lets get to the blogging part.  If you’ve set up your environment right, you can execute the following command: 

PS > cd iis: 

This command will put you in the iis scripts directory.  Next, create a new blogs script by typing: 

PS > notepad blogs.ps1 

You’ll be prompted if you want to create the file. Go ahead and say yes.  Next, paste the following into the the notepad and save it: 
  

## Sets up all custom feeds from feeds.txt
##---------------------------------------------------
function global:Import-Feed
{
     if( $global:RssFeeds -eq $null )
     {
          $global:RssFeeds = @{};
     }
     $RssFeeds.Add( "iisblogs", "http://blogs.iis.net/rawmainfeed.aspx" );
     $RssFeeds.Add( "iisdownloads", "http://www.iis.net/DownloadCENTER/all/rss.aspx" );
}
Import-Feed ## Call Import-Feed so we are ready to go
## Gets a feed or lists available feeds
##---------------------------------------------------
function global:Get-Feed( [string] $name )
{
     if( $RssFeeds.ContainsKey( $name ) )
     {
          return $RssFeeds[$name];
     }
     else
     {
          Write-Host "The path requested does not exist";
          Write-Output $RssFeeds;
     }
}
## Gets IIS Blogs
##---------------------------------------------------
function global:Get-Blog([int]$index, [int]$last, [int]$first, [int]$open)
{
     $url = (Get-Feed iisblogs)
     return (Get-RSS $url $index $last $first $open)
}
## Gets a specific blog
##---------------------------------------------------
function global:Get-AuthorBlog([string]$creator)
{
     Get-Blog | Where-Object {$_.creator -eq $creator}
}
## Gets Downloads from IIS
##---------------------------------------------------
function global:Get-Download([int]$index, [int]$last, [int]$first, [int]$open)
{
     $url = (Get-Feed iisdownloads)
     return (Get-RSS $url $index $last $first $open)
}
## Gets a generic RSS Feed
##---------------------------------------------------
function global:Get-RSS([string]$url, [int]$index, [int]$last, [int]$first, [int]$open)
{
     $feed = [/xml](new-object System.Net.WebClient).DownloadString($url)
     if($index)
     {
          return $feed.rss.channel.item[$index]
     }
     if($open)
     {
          $ieaddr = $env:programfiles + "internet exploreriexplore.exe"
          return &(get-item $ieaddr) $feed.rss.channel.item[$open].link
     }
     if($last)
     {
          return ($feed.rss.channel.item | Select -last $last)
     }
     if($first)
     {
          return ($feed.rss.channel.item | Select -first $first)
     }
     return $feed.rss.channel.item
}

Once you’ve saved this file, close it.  We need to sign this script and execute it by typing: 

PS IIS:> sign blogs.ps1
PS IIS:> ./blogs.ps1 

Now lets start reading.  

  • Read all Blogs
PS iis:> Get-Blog 
  • Read the last five blog posts
PS iis:> Get-Blog -last 5 
  • Read the first five blog posts
PS iis:> Get-Blog -first 5 
  • Read the 8th blog post
PS iis:> Get-Blog -index 8 
  • Open the 12th blog post and open in Internet Explorer
PS iis:> Get-Blog -open 12 
  • Read all blog posts by Bill Staples
PS iis:> Get-AuthorBlog bills 
  • Read all items in DownloadCENTER
PS iis:> Get-Download 
  • Get titles of all items in DownloadCENTER
PS iis:> Get-Download | Select Title 

Of course, all the laws of Powershell still apply, so I can still do fun stuff like like listing only the blog titles from my blog. 

PS iis:> Get-AuthorBlog TobinTitus | Select Title 

I can do the same witht he raw blog output: 

PS iis:> Get-Blog -last 5 | Select pubDate, Creator, Title 

Happy reading. 

IIS.NET Blogs in Powershell

OT: Cat and Mouse

For those of you looking for IIS information, this blog post is not for you. For those of you that just like general computer information, read on and enjoy.

The computer mouse has come a long way over the years.  When Doug Engelbart invented the computer mouse, it was rather crude looking but was none-the-less very revolutionary.  Engelbart showed his invention to the world in 1968 during a presentation now know as “The Mother of All Demos.”  The mouse that Engelbart demoed was an electromechanical device that leveraged a large sphere to turn x and y coordinate counters as the device was rolled across a surface. Each click of the counter would tell the computer how far the mouse had “traveled”.  For several years the mouse kept the same basic principal. We improved on the original idea and replaced a large sphere with small rubbery balls with x,  i and often an additional diagonal gear wheel. The diagonal indicator was used to help correct the cursor movement if the mouse was rotated or tilted. The rubber helped the ball move across slick surfaces when a mouse pad just wasn’t cutting it. The downside to this rubbery surface was that pet owners ended up with a lot of cat (or dog) fur rolling into the mouse.  You would often have to open the bottom portion of the mouse and clean the hair and other debris out to make your pointing device work efficiently again.  Playing Doom or Quake with a junked-up mouse was an instant indication of a n00b that needed serious pwning.

Roll forward to the present day and we find optical mice taking the electromechanical device’s place. The optical approach solves a lot of the problems associated with older mice. For one, the new mice don’t have the rolling dowel-like rollers (counters) that can get gunked up anymore.  A rubbery ball is not picking up every piece of debris and yanking it into the mouse cavity as though it were a time-capsule for desktop debris.  So, why does your mouse still freak out when a piece of fur gets trapped under your optical mouse? 

The answer is pretty interesting and I’m sure will be solved with the next iteration of mouse invention. Many optical mice are created using a camera or an optoelectric sensor, an optical processor to compare images taken by the camera/sensor, and an LED  that illuminates the surface under your mouse.  The camera/sensor takes ~1500 picture samples a second!  The pictures are small (usually 10-20 square pixels) and gray-scale (usually registering fewer than 100 shades).  The optical processor examines and compares the picture samples to determine the relative position of the mouse to its previous position.

Now introduce your cat’s hair to the equation.  The cat hair gets entangled in the small cavity of the mouse where the optical sensor lives. As the mouse rolls across the desk, static builds up and flips the hair around wildly. As your mouse snaps those thousands of pictures, the hair position is captured and the optical processor gets confused by the sudden movement of the cat hair in the picture comparisons.  You can move your mouse slowly to the right, but if the hair is flipped around within the mouse cavity, the processor will think that you have jerked the mouse to the left or sharply downward.  If your cat is watching the computer screen as mine often does, these sharp movements may cause the cat to attack your monitor — truly creating an interesting game of cat and mouse.

IIS 7 Logging UI For Vista – Download Now

As many of you already know, the management console for IIS 7.0 on Windows Vista does not have a UI for logging.  Since this was a pain point for several customers, I decided to test out the extensibility APIs by creating a logging UI module. 

I’ve posted a preview version of my logging UI on the newly opened IIS Download Center. I will be releasing a few updates throughout the week with changes. The module also contains the source code for my UI module under the Microsoft Permissive License. This code will also be updated in future releases.

You can find the download at: http://www.iis.net/downloads/default.aspx?tabid=34&i=1328&g=6

If you have any questions, please feel free to contact me through my blog.

Ups and Downs of the past month

It’s sometimes hard to hold a completely technical blog, particularly when you have long absences from one post to the next. You feel you have to explain yourself to your readership each time you take more than a week or two between posts. This is no different. Despite having a ton of stuff to blog about, I haven’t posted since December. Much of this has to do with regular holiday planning, but much more has happened. For me, this past month has had some major ups and downs for me emotionally and I’m still a little mixed up.

This post will have a great deal of personal information in it, and much of it has nothing to do with IIS, but it should give you some insight into Microsoft if you are interested in that sort of thing.

If you’ve been paying attention to the weather in the Pacific Northwest, you know that on December 14th, we had a major windstorm that knocked out power to over 1 million customers. The bad news is that on December 15th, I had a flight scheduled to go visit my family on the west coast. United Airlines cancelled several flights, which put their check-in line in complete disarray. My flight wasn’t cancelled, but no thanks to United Airlines, I was not able to board my flight, and no other flights could be found for me along with my two cats. My trip was cancelled.

Since I was still in town, I helped put the finishing touches on a “Think Week” paper I had been writing along with two other employees here at Microsoft. Despite the power outages, we were able to make it into one of the buildings at Microsoft and submit our paper by the deadline. It was an interesting experience to submit a paper that every full time employee of the company can read and comment on, including Bill Gates.

I also took the opportunity to work on writing a UI module for IIS in that time. The module was actually finished, but after consulting with one of the developers, I decided to modify the sample and I haven’t had time to clean it up and submit it yet. More on that later.

On December 28th, I got a phone call saying that my grandfather had passed away. My family has always been important to me. My grandparents hold a special place in my heart because they gave me a lot of my determination. My grandfather was a tail-gunner in World War II, had seen more inventions and re-inventions in his lifetime than I could fathom. He always chuckled when I came home to visit and told him about this great “new” thing in technology that would change the world unlike anything else ever had. I didn’t get the joke then, but I do now. I don’t mean to downplay the importance of technology. When putting it in perspective, we are not the first people to change the world and we will certainly not be the last. I’ll miss my grandfather terribly and there are no words to describe how this has changed my world.

It was good, however, to go back home for my grandfather’s funeral. I got to help my dad clean up and set up his workshop. I also got to see one my best friend since I was 8 years old. I haven’t seen him in 10 months since I moved out west to work for Microsoft. I returned from my grandfather’s funeral on the 8th and have tried to get 100% back into the swing of things. I really hadn’t been able to focus on work the way that I usually do until Thursday. I was finally making some headway on a few projects at work.

Before I continue, I need to give some of you some background on me. 20 years ago, when I was in 5th grade, I taught myself Microsoft BASIC and Atari Assembler. I remember telling my parents back then that I was going to work for Microsoft one day. My mom told me to finish my homework first. Of course, I have finished my homework and 20 years later, here I am working for Microsoft and submitting a paper to the very man that started the company. A few weeks had gone by and we received a LOT of feedback about our paper, but none of that feedback is from Mr Gates. We sort of expected that. Bill doesn’t respond to many papers in a year.

However, the other day I got a barely coherent message on my cell phone. It was from one of the co-authors of the think week paper. He was an excited statement about Bill Gates reading our paper. I tried to connect to the VPN to go read the feedback but had some issues because my home network was, shall we say, “in flux”. It drove me nuts that there was feedback from the very man that we addressed the paper to, but I couldn’t read it. I jumped in the shower and then rushed into work to read it personally. During the entire ride to work, I was forcing myself to watch my speed carefully. However, my heart was racing so fast that I think it pushed 10 extra pounds of blood into my right foot. I got to work and quickly opened up the Think Week site and scrolled to our paper. When I read the comment, I couldn’t help but become giddy. The feedback was favorable and verbose — about a page and a half. I was elated and sitting here today, I’m still in shock about the entire thing.

I have to say that I’m extremely thankful for the opportunities we have inside our company. Inside the company, you can tackle any problem that you want. You simply need to apply your efforts in an area, and you’ll likely get the support of your managers, team, and friends. I know there are many people out there who like to point out some negative issues inside Microsoft. Some anonymous blogs out there take a rather candid look at company issues and seem to err on the side of complaining. My experience inside the company so far has been spectacular. It helps that I knew people inside the company before I moved out here. That said, there are many opportunities inside the company to make recommendations and get involved. I can’t be happy enough with that.

So, while this was not a technical post, I felt I owed it to you all to explain where I have been and why I haven’t been blogging (again). Thanks for putting up with me.