<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.iis.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:cs="http://blogs.iis.net/"><channel><title>Tobin Titus Blog : PowerShell</title><link>http://blogs.iis.net/tobintitus/archive/tags/PowerShell/default.aspx</link><description>Tags: PowerShell</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>Reading IIS.NET Blogs with Powershell</title><link>http://blogs.iis.net/tobintitus/archive/2007/02/13/reading-iis-net-blogs-with-powershell.aspx</link><pubDate>Tue, 13 Feb 2007 19:14:00 GMT</pubDate><guid isPermaLink="false">50bcf3b4-f6fe-4638-adff-0c150e922e99:1577140</guid><dc:creator>TobinTitus</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.iis.net/tobintitus/rsscomments.aspx?PostID=1577140</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.iis.net/tobintitus/commentapi.aspx?PostID=1577140</wfw:comment><comments>http://blogs.iis.net/tobintitus/archive/2007/02/13/reading-iis-net-blogs-with-powershell.aspx#comments</comments><description>&lt;P&gt;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.&amp;nbsp; 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.&amp;nbsp; 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: &lt;A href="http://www.iis.net/downloads/default.aspx?tabid=34&amp;amp;g=6&amp;amp;i=1387"&gt;http://www.iis.net/downloads/default.aspx?tabid=34&amp;amp;g=6&amp;amp;i=1387&lt;/A&gt;&lt;/P&gt;
&lt;H4&gt;Setting up your Powershell environment&lt;/H4&gt;
&lt;HR&gt;

&lt;P&gt;To start, I've written a few supporting functions in my profile.&amp;nbsp; These functions help me keep my scripts organized and, since I change my scripts quite often, it helps me to sign them as well.&lt;/P&gt;
&lt;P&gt;First off, if you haven't created your own&amp;nbsp;certificate for signing code, please go back and&amp;nbsp;take a look at &lt;A class="" href="http://blogs.iis.net/tobintitus/archive/2006/11/30/powershell-and-microsoft-web-administration.aspx"&gt;my&amp;nbsp;first Powershell blog post&lt;/A&gt; that give you the details on how to do this.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Next, we need to add a few things to your Powershell profile.&amp;nbsp; To open your Powershell profile from within Powershell, type: &lt;/P&gt;
&lt;P class=ConsoleCode&gt;PS &amp;gt; notepad $profile&lt;/P&gt;
&lt;P&gt;First, I add a function to allow us to easily sign our scripts (assuming you have created a cert to sign them wth):&lt;/P&gt;&lt;PRE class=ExampleCode&gt;## Sign a file
##-------------------------------------------
  function global:Sign-Script ( [string] $file )
  {
    $cert = @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]
    Set-AuthenticodeSignature $file $cert
  }
  set-alias -name sign -value sign-script
&lt;/PRE&gt;
&lt;P&gt;The next function is used to help me organize things. I have several scripts for various&amp;nbsp;work environments.&amp;nbsp; 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.&amp;nbsp; Inside each of my script directories, I keep a "load.ps1" script that I can&amp;nbsp; use to initialize any of my work environments.&amp;nbsp; 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.&lt;/P&gt;&lt;PRE class=ExampleCode&gt;## 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 = &amp;amp;$loadscript
      }
    }
    # Create the drive
    new-Psdrive -name $alias -scope global -Psprovider FileSystem -root $path
  }
&lt;/PRE&gt;
&lt;P&gt;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: &lt;/P&gt;&lt;PRE class=ExampleCode&gt;## Custom PS Drives
##-------------------------------------------
  New-Drive -alias "common" 
  New-Drive -alias "iis" 
&lt;/PRE&gt;
&lt;P&gt;Go ahead and save your profile now and type these commands:&lt;/P&gt;
&lt;P class=ConsoleCode&gt;PS &amp;gt; Set-ExecutionPolicy Unrestricted&lt;BR&gt;PS &amp;gt; &amp;amp;$profile&lt;BR&gt;PS &amp;gt; Sign $profile&lt;BR&gt;PS &amp;gt; Set-ExecutionPolicy AllSigned&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;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.&amp;nbsp; 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.&lt;/P&gt;
&lt;P&gt;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.&amp;nbsp;&lt;/P&gt;
&lt;H4&gt;Creating / Using Blog Functionality&lt;/H4&gt;
&lt;HR&gt;

&lt;P&gt;Now that we have our environment set up, lets get to the blogging part.&amp;nbsp; If you've set up your environment right, you can execute the following command:&lt;/P&gt;
&lt;P class=ConsoleCode&gt;PS &amp;gt; cd iis:&lt;/P&gt;
&lt;P&gt;This command will put you in the iis scripts directory.&amp;nbsp; Next, create a new blogs script by typing:&lt;/P&gt;
&lt;P class=ConsoleCode&gt;PS &amp;gt; notepad blogs.ps1&lt;/P&gt;
&lt;P&gt;You'll be prompted if you want to create the file. Go ahead and say yes.&amp;nbsp; Next, paste the following into the the notepad and save it:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE class=ExampleCode&gt;## 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 explorer\iexplore.exe"
    return &amp;amp;(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
}
&lt;/PRE&gt;
&lt;P&gt;Once you've saved this file, close it.&amp;nbsp; We need to sign this script and execute it by typing:&lt;/P&gt;
&lt;P class=ConsoleCode&gt;PS IIS:&amp;gt; sign blogs.ps1&lt;BR&gt;PS IIS:&amp;gt; ./blogs.ps1&lt;/P&gt;
&lt;P class=ConsoleCode&gt;Now lets start reading.&amp;nbsp; &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Read all Blogs&lt;/LI&gt;&lt;/UL&gt;
&lt;P class=ConsoleCode&gt;PS iis:\&amp;gt; Get-Blog &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Read the last five blog posts&lt;/LI&gt;&lt;/UL&gt;
&lt;P class=ConsoleCode&gt;PS iis:\&amp;gt; Get-Blog -last 5 &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Read the first five blog posts&lt;/LI&gt;&lt;/UL&gt;
&lt;P class=ConsoleCode&gt;PS iis:\&amp;gt; Get-Blog -first 5 &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Read the 8th blog post&lt;/LI&gt;&lt;/UL&gt;
&lt;P class=ConsoleCode&gt;PS iis:\&amp;gt; Get-Blog -index 8 &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Open the 12th blog post and open in Internet Explorer&lt;/LI&gt;&lt;/UL&gt;
&lt;P class=ConsoleCode&gt;PS iis:\&amp;gt; Get-Blog -open 12 &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Read all blog posts by Bill Staples&lt;/LI&gt;&lt;/UL&gt;
&lt;P class=ConsoleCode&gt;PS iis:\&amp;gt; Get-AuthorBlog bills&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Read all items in DownloadCENTER&lt;/LI&gt;&lt;/UL&gt;
&lt;P class=ConsoleCode&gt;PS iis:\&amp;gt; Get-Download&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Get titles of all items in DownloadCENTER&lt;/LI&gt;&lt;/UL&gt;
&lt;P class=ConsoleCode&gt;PS iis:\&amp;gt; Get-Download | Select Title&lt;/P&gt;
&lt;P&gt;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.&lt;/P&gt;
&lt;P class=ConsoleCode&gt;PS iis:\&amp;gt; Get-AuthorBlog TobinTitus | Select Title&lt;/P&gt;
&lt;P&gt;I can do the same witht he raw blog output:&lt;/P&gt;
&lt;P class=ConsoleCode&gt;PS iis:\&amp;gt; Get-Blog -last 5 | Select pubDate, Creator, Title&lt;/P&gt;
&lt;P&gt;Happy reading.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/photos/tobint/images/1671449/original.aspx"&gt;&lt;IMG title="IIS.NET Blogs in Powershell" style="WIDTH:561px;HEIGHT:279px;" height=279 alt="IIS.NET Blogs in Powershell" src="http://blogs.msdn.com/photos/tobint/images/1671449/original.aspx" width=561 align=middle border=0&gt;&lt;/A&gt;&lt;/P&gt;&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=1577140" width="1" height="1"&gt;</description><category domain="http://blogs.iis.net/tobintitus/archive/tags/PowerShell/default.aspx">PowerShell</category><category domain="http://blogs.iis.net/tobintitus/archive/tags/Download/default.aspx">Download</category><category domain="http://blogs.iis.net/tobintitus/archive/tags/IIS.NET/default.aspx">IIS.NET</category></item><item><title>Extending Microsoft.Web.Administration through PowerShell  (Part II)</title><link>http://blogs.iis.net/tobintitus/archive/2006/12/01/more-on-iis-7-administration-with-powershell.aspx</link><pubDate>Fri, 01 Dec 2006 17:03:00 GMT</pubDate><guid isPermaLink="false">50bcf3b4-f6fe-4638-adff-0c150e922e99:1483181</guid><dc:creator>TobinTitus</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.iis.net/tobintitus/rsscomments.aspx?PostID=1483181</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.iis.net/tobintitus/commentapi.aspx?PostID=1483181</wfw:comment><comments>http://blogs.iis.net/tobintitus/archive/2006/12/01/more-on-iis-7-administration-with-powershell.aspx#comments</comments><description>&lt;P&gt;In my &lt;A class="" href="http://blogs.iis.net/tobintitus/archive/2006/11/30/powershell-and-microsoft-web-administration.aspx"&gt;previous post&lt;/A&gt;, I showed you how easy it was to leverage your knowledge of the IIS 7 managed SDK in Windows PowerShell.&amp;nbsp; We loaded the IIS 7 managed assemblies and then traversed the object model to display site information and stop application pools.&amp;nbsp; While this in itself was pretty cool, I don't think I quite got my point across about how powerful IIS 7 and PowerShell are together. As such, I wanted to show you some more fun things to do with PowerShell in the name of easy IIS 7 administration.&lt;/P&gt;
&lt;P&gt;First, our examples still required a great deal of typing and piping and filtering.&amp;nbsp; Let's modify our profile script from my previous post by adding at least one new global variable that will give us access to the ServerManager without much typing.&amp;nbsp; Add the following line to your profile script from my previous post.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;new-variable iismgr -value (New-Object Microsoft.Web.Administration.ServerManager) -scope "global"&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;(if you don't have a profile script yet, go back to my &lt;A class="" href="http://blogs.iis.net/tobintitus/archive/2006/11/30/powershell-and-microsoft-web-administration.aspx"&gt;previous post&lt;/A&gt; to learn&amp;nbsp;how to create one).&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Note:&lt;/STRONG&gt; If you signed your script before, you'll have to do it again after modifying the script&lt;/P&gt;
&lt;P&gt;Open a new instance of PowerShell and now you can access the site collection just by typing:&lt;/P&gt;
&lt;P&gt;PS C:\&amp;gt; &lt;STRONG&gt;$iismgr.Sites&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;That's considerably smaller than our previous examples.&amp;nbsp; But let's not stop there.&amp;nbsp; What happens if I want to search the site collection? PowerShell has some fun syntax for this as well. I simply pipe the output of my SiteCollection to a "Where-Object" cmdlet and then specify what site I'm looking for:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;$iismgr.Sites | Where-Object {$_.Name -match "^Default*"}&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;This is still&amp;nbsp;quite a bit of typing when all I really want to do is find the default website.&amp;nbsp;You may ask "Wouldn't it be easier if we could just add a "Find" method to the SiteCollection object?" Well I'm glad &lt;EM&gt;you&lt;/EM&gt; asked *cough*!&amp;nbsp; Next, we are going to do just that! Open up another instance of notepad and add the following XML to it:&lt;/P&gt;
&lt;DIV style="FONT-FAMILY:Courier;"&gt;&amp;lt;?xml version="1.0" encoding="utf-8" ?&amp;gt;&lt;BR&gt;&amp;lt;!-- *******************************************************************&lt;BR&gt;Copyright (c) Microsoft Corporation.&amp;nbsp; All rights reserved.&lt;BR&gt;&amp;nbsp;&lt;BR&gt;THIS SAMPLE CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY &lt;BR&gt;OF ANY KIND,WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO &lt;BR&gt;THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR&lt;BR&gt;PURPOSE. IF THIS CODE AND INFORMATION IS MODIFIED, THE ENTIRE RISK OF USE&lt;BR&gt;OR RESULTS IN CONNECTION WITH THE USE OF THIS CODE AND INFORMATION &lt;BR&gt;REMAINS WITH THE USER.&lt;BR&gt;******************************************************************** --&amp;gt; 
&lt;P&gt;&amp;lt;Types&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;lt;Type&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Name&amp;gt;Microsoft.Web.Administration.SiteCollection&amp;lt;/Name&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;lt;Members&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ScriptMethod&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Name&amp;gt;Find&amp;lt;/Name&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Script&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $rtr = "";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if ( $args[0] ) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;$name = $args[0];&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $rtr = ((New-Object Microsoft.Web.Administration.ServerManager).Sites | Where-Object {$_.Name -match $name}) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $rtr = "No sites found." &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $rtr&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Script&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ScriptMethod&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Members&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/Type&amp;gt;&lt;BR&gt;&amp;lt;/Types&amp;gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;What we've done is identified that we want to add a scripted method to the Microsoft.Web.Administration.SiteCollection object. In our case,&amp;nbsp;I've added a "Find" method&amp;nbsp;by&amp;nbsp;using the same cmdlet that we typed before to search the site collection. The&amp;nbsp;difference is, this type I use the $args array variable to check for a parameter and use it if one is available.&amp;nbsp; Now, save this file into your %windir%\system32\WindowsPowerShell\v1.0\ directory as "iis.types.ps1xml".&amp;nbsp; Once you've saved the file, sign it the same way you signed your profile script.&amp;nbsp; Keep in mind that these xml files contain code, so signing your xml is required to keep your PowerShell experience a secure one.&amp;nbsp; Now, open your profile script (again) and add the following lines to the end:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;new-variable iissites -value (New-Object Microsoft.Web.Administration.ServerManager).Sites -scope "global"&lt;BR&gt;new-variable iisapppools -value (New-Object Microsoft.Web.Administration.ServerManager).ApplicationPools -scope "global"&lt;BR&gt;update-typedata -append (join-path -path $PSHome -childPath "iis.types.ps1xml")&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Note: &lt;/STRONG&gt;Once again, you'll have to re-sign this profile if your execution policy requires signed scripts.&lt;/P&gt;
&lt;P&gt;Notice that I added two more variables: $iissites and $iisapppools. These variables allow me to access the site collection and application pool collection with a simple keyword.&amp;nbsp; Lets try them out in PowerShell. Make sure you open a new instance of PowerShell so your profile script and xml type data are updated properly. Once your new instance of PowerShell is open, type the following:&lt;/P&gt;
&lt;P&gt;PS C:\&amp;gt; &lt;STRONG&gt;$iissites.Find("^Default*")&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;PowerShell will do all the work for you and you have MUCH less typing to do.&lt;/P&gt;
&lt;P&gt;Another alternative to using xml files is to simply create a function and add it to your profile. For instance, we can create a function called "findsite" that provides the same functionality as our previous example. Either type the following command into PowerShell or add it to your profile script:&lt;/P&gt;
&lt;P&gt;PS C:\&amp;gt; &lt;STRONG&gt;function findsite { $name=$args[0]; ((New-Object Microsoft.Web.Administration.ServerManager).Sites | Where-Object {$_.Name -match $name});&lt;/STRONG&gt; &lt;STRONG&gt;} }&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Now you can search for a site using the following syntax:&lt;/P&gt;
&lt;P&gt;PS C:\&amp;gt; &lt;STRONG&gt;findsite default*&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Whatever way we choose to extend Microsoft.Web.Administration and/or PowerShell, we can use our output as we did before:&lt;/P&gt;
&lt;P&gt;PS C:\&amp;gt; &lt;STRONG&gt;(findsite default*).Id&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The previous line should display the Id of the default web site.&amp;nbsp; We can also stop the website:&lt;/P&gt;
&lt;P&gt;PS C:\&amp;gt; &lt;STRONG&gt;(findsite default*).Stop()&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;We can keep taking this to extremes and truncate every operation that we perform on a semi-regular basis.&amp;nbsp; These scripts are not one-offs. Each script function we create or append to an existing object model can be reused and piped as input to another function.&amp;nbsp; The possibilities are endless and completely customizable to your needs.&lt;/P&gt;&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=1483181" width="1" height="1"&gt;</description><category domain="http://blogs.iis.net/tobintitus/archive/tags/IIS+7/default.aspx">IIS 7</category><category domain="http://blogs.iis.net/tobintitus/archive/tags/PowerShell/default.aspx">PowerShell</category></item><item><title>Accessing Microsoft.Web.Administration through PowerShell (Part I)</title><link>http://blogs.iis.net/tobintitus/archive/2006/11/30/powershell-and-microsoft-web-administration.aspx</link><pubDate>Fri, 01 Dec 2006 04:09:00 GMT</pubDate><guid isPermaLink="false">50bcf3b4-f6fe-4638-adff-0c150e922e99:1482586</guid><dc:creator>TobinTitus</dc:creator><slash:comments>12</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.iis.net/tobintitus/rsscomments.aspx?PostID=1482586</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.iis.net/tobintitus/commentapi.aspx?PostID=1482586</wfw:comment><comments>http://blogs.iis.net/tobintitus/archive/2006/11/30/powershell-and-microsoft-web-administration.aspx#comments</comments><description>&lt;P&gt;I've caught the PowerShell bug. In between stints with my ever-expanding code samples, I play with PowerShell a lot.&amp;nbsp; I thought I'd share a quick example of how to load Microsoft.Web.Administration.dll and use it to perform some basic tasks.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Note: &lt;/STRONG&gt;I'm running these samples on Windows Vista RTM, but I have no reason to believe this will not work on the PowerShell release candidates for the Vista RC* builds that are &lt;A class="" title="available now" href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx"&gt;available now&lt;/A&gt;.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;So let's get started.&lt;/P&gt;
&lt;P&gt;First, PowerShell has no idea where Microsoft.Web.Administration.DLL is so you have to tell it how to load it. Anyone who has written code to&amp;nbsp;dynamically load an assembly should be familiar with this syntax.&amp;nbsp; Type the following command&lt;/P&gt;
&lt;P&gt;PS C:\&amp;gt; &lt;STRONG&gt;[System.Reflection.Assembly]::LoadFrom( "C:\windows\system32\inetsrv\Microsoft.Web.Administration.dll" )&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;The path to your assembly may change depending on your install.&amp;nbsp; I'll show you later how to use environment variables to calculate the correct path.&amp;nbsp; In the mean time the out put of the line above display something like the following:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="FONT-FAMILY:COURIER;"&gt;GAC&amp;nbsp;&amp;nbsp;Version&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Location &lt;/DIV&gt;
&lt;DIV style="FONT-FAMILY:COURIER;"&gt;---&amp;nbsp;&amp;nbsp;-------&amp;nbsp;&amp;nbsp;&amp;nbsp; -------- &lt;/DIV&gt;
&lt;DIV style="FONT-FAMILY:COURIER;"&gt;True v2.0.50727 C:\Windows\assembly\GAC_MSIL\Microsoft.Web.Administration\7.0.0.0__31bf3856ad364e35\Microsoft.... &lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Once the assembly is loaded you can use PowerShell's "New-Object" command to create a ServerManager object that is defined in Microsoft.Web.Administration.&lt;/P&gt;
&lt;P&gt;PS C:\&amp;gt; &lt;STRONG&gt;(New-Object Microsoft.Web.Administration.ServerManager)&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;This doesn't give you much except the list of properties the ServerManager exposes:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="FONT-FAMILY:COURIER;"&gt;ApplicationDefaults&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.Web.Administration.ApplicationDefaults&lt;BR&gt;ApplicationPoolDefaults&amp;nbsp; :&lt;BR&gt;ApplicationPools&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :&lt;BR&gt;SiteDefaults&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.Web.Administration.SiteDefaults&lt;BR&gt;Sites&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : {Default Web Site}&lt;BR&gt;VirtualDirectoryDefaults : Microsoft.Web.Administration.VirtualDirectoryDefaults&lt;BR&gt;WorkerProcesses&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : {} &lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;To get more detail, you need to use the properties and methods of the ServerManager object to drill down and get the information we want. The ServerManager provides access to all of the sites on your machine through a SiteCollection object. This SiteCollection is made available through the "Sites" property of the ServerManager.&amp;nbsp; 
&lt;P&gt;PS C:\&amp;gt; &lt;STRONG&gt;(New-Object Microsoft.Web.Administration.ServerManager).Sites&lt;/STRONG&gt; 
&lt;P&gt;Which will produce&amp;nbsp;a list view of all the sites and their associated property names/values. &lt;BR&gt;&lt;BR&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="FONT-FAMILY:COURIER;"&gt;ApplicationDefaults&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.Web.Administration.ApplicationDefaults&lt;BR&gt;Applications&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : {DefaultAppPool, Classic .NET AppPool}&lt;BR&gt;Bindings&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : {}&lt;BR&gt;Id&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 1&lt;BR&gt;Limits&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.Web.Administration.SiteLimits&lt;BR&gt;LogFile&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.Web.Administration.SiteLogFile&lt;BR&gt;Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Default Web Site&lt;BR&gt;ServerAutoStart&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : True&lt;BR&gt;State&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Started&lt;BR&gt;TraceFailedRequestsLogging : Microsoft.Web.Administration.SiteTraceFailedRequestsLogging&lt;BR&gt;VirtualDirectoryDefaults&amp;nbsp;&amp;nbsp; : Microsoft.Web.Administration.VirtualDirectoryDefaults&lt;BR&gt;ElementTagName&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : site&lt;BR&gt;IsLocallyStored&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : True&lt;BR&gt;RawAttributes&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : {name, id, serverAutoStart} &lt;/DIV&gt;
&lt;P style="FONT-FAMILY:COURIER;"&gt;ApplicationDefaults&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.Web.Administration.ApplicationDefaults&lt;BR&gt;Applications&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : {DefaultAppPool}&lt;BR&gt;Bindings&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : {}&lt;BR&gt;Id&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 2&lt;BR&gt;Limits&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.Web.Administration.SiteLimits&lt;BR&gt;LogFile&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Microsoft.Web.Administration.SiteLogFile&lt;BR&gt;Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Test Web Site 1&lt;BR&gt;ServerAutoStart&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : False&lt;BR&gt;State&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Stopped&lt;BR&gt;TraceFailedRequestsLogging : Microsoft.Web.Administration.SiteTraceFailedRequestsLogging&lt;BR&gt;VirtualDirectoryDefaults&amp;nbsp;&amp;nbsp; : Microsoft.Web.Administration.VirtualDirectoryDefaults&lt;BR&gt;ElementTagName&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : site&lt;BR&gt;IsLocallyStored&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : True&lt;BR&gt;RawAttributes&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : {name, id, serverAutoStart} &lt;BR&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Of course, this isn't the easiest view to read, so let's say we just list the site names by piping our site list to&amp;nbsp;the "ForEach-Object" command in PowerShell and display a list of site names only:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;PS C:\&amp;gt; &lt;STRONG&gt;(New-Object Microsoft.Web.Administration.ServerManager).Sites | ForEach-Object {$_.Name}&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;This looks much more concise:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="FONT-FAMILY:COURIER;"&gt;Default Web Site&lt;BR&gt;Test Web Site 1 &lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;We could also use the Select-Object syntax to query the list into a table format:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;PS C:\&amp;gt; &lt;STRONG&gt;(New-Object Microsoft.Web.Administration.ServerManager).Sites | Select Id, Name&lt;/STRONG&gt;&lt;/P&gt;
&lt;DIV style="FONT-FAMILY:COURIER;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Id Name&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -- ----&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 Default Web Site&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2 Test Web Site 1&lt;/DIV&gt;
&lt;P&gt;Now lets use PowerShell to manage application pools. We can fit several commands on one line by using the semi-colon.&amp;nbsp; The following command-line is actually four different operations: Storing the application pool collection into a variable, displaying the name and runtime status of the first application pool, stopping the first application pool, then displaying the name and status again.&lt;/P&gt;
&lt;P&gt;PS C:\&amp;gt; &lt;STRONG&gt;$pools=(New-Object Microsoft.Web.Administration.ServerManager).ApplicationPools; $pools.Item(0) | Select Name, State;$pools.Item(0).Stop(); $pools.Item(0) | Select Name, State&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Running this sample should display the following:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="FONT-FAMILY:COURIER;"&gt;Name&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; State&lt;BR&gt;----&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -----&lt;BR&gt;DefaultAppPool&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Started&lt;BR&gt;Stopped&lt;BR&gt;DefaultAppPool&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Stopped&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This is nice, but we can do this already with appcmd.exe right? Well, to some extent.&amp;nbsp; We don't get the features of PowerShell that allow us to format our output the data to our liking. Also, as a developer, I find it much easier to use the API syntax I'm already familiar with than to remember appcmd.exe syntax.&amp;nbsp; Furthermore, PowerShell allows us to use WMI alongside our managed code calls, and unlike appcmd.exe, you can extend PowerShell and cmdlets.&amp;nbsp;PowerShell gives you the ability to easily manage multiple servers from one command prompt on one machine.&amp;nbsp; Watch the PowerShell/IIS 7 interview on &lt;A class="" title=Channel9 href="http://channel9.msdn.com/Showpost.aspx?postid=256994"&gt;Channel9&lt;/A&gt; if you want to see this remote administration in action.&lt;/P&gt;
&lt;P&gt;One last thing that PowerShell brings to the table is the ability to "spot-weld" our object models (as &lt;SPAN&gt;&lt;A class="" title="Scott Hanselman" href="http://www.hanselman.com/blog/CategoryView.aspx?category=PowerShell"&gt;&lt;STRONG&gt;Scott&lt;/STRONG&gt; Hanselman&lt;/A&gt;&lt;/SPAN&gt;&amp;nbsp;quipped). You can create/modify/extend type data and formatting to your hearts desire.&amp;nbsp; For more information on this, check out the PowerShell documentation found in the PowerShell install, or in the &lt;A class="" title="PowerShell documentation set" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=B4720B00-9A66-430F-BD56-EC48BFCA154F&amp;amp;displaylang=en"&gt;PowerShell documentation set&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;So, I would be remiss in this post if I didn't try to make your PowerShell / IIS 7.0 life easier.&amp;nbsp; As such, I've created a profile script that loads all the IIS 7.0 managed assemblies for you.&amp;nbsp; The script is simple and contains more&amp;nbsp; echo commands than actual working script lines.&lt;/P&gt;
&lt;P&gt;To install this script run the following command inside PowerShell:&lt;/P&gt;
&lt;DIV style="FONT-FAMILY:Courier;"&gt;PS C:&amp;gt; &lt;STRONG&gt;if ( test-path $profile ) { echo "Path exists." } else { new-item -path $profile -itemtype file -force }; notepad $profile&lt;/STRONG&gt;&lt;/DIV&gt;
&lt;P&gt;This will create a profile path for you if you don't already have one, then open up your profile in notepad.&amp;nbsp; If you haven't added anything to the file, it will obviously display an empty file.&amp;nbsp; Paste the following in notepad when it opens:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="FONT-FAMILY:Courier;"&gt;echo "Microsoft IIS 7.0 Environment Loader"&lt;BR&gt;echo "Copyright (C) 2006 Microsoft Corporation. All rights reserved."&lt;BR&gt;echo "&amp;nbsp; Loading IIS 7.0 Managed Assemblies"&lt;BR&gt;&lt;BR&gt;$inetsrvDir = (join-path -path $env:windir -childPath "\system32\inetsrv\")&lt;BR&gt;Get-ChildItem -Path (join-path -path $inetsrvDir -childPath "Microsoft*.dll") | ForEach-Object {[System.Reflection.Assembly]::LoadFrom( (join-path -path $inetsrvDir -childPath $_.Name)) }&lt;BR&gt;&lt;BR&gt;echo "&amp;nbsp; Assemblies loaded."&lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now, save the profile and close notepad.&amp;nbsp; You will likely have to sign this script &lt;EM&gt;or&lt;/EM&gt; change your script execution policy to something very weak&amp;nbsp;to make this script run properly (obviously I'm not recommending the latter).&amp;nbsp;To find out more about signing scripts, type "get-help about_signing" in PowerShell.&amp;nbsp;The instructions to create a self-signed certificate found in that help file are as follows:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="FONT-FAMILY:Courier;"&gt;In an SDK Command Prompt window, run the following commands.&lt;BR&gt;The first command creates a local certificate authority for your computer.&lt;BR&gt;The second command generates a personal certificate from the certificate authority:&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;makecert -n "CN=PowerShell Local Certificate Root" -a sha1 `&lt;BR&gt;&amp;nbsp;&amp;nbsp; -eku 1.3.6.1.5.5.7.3.3 -r -sv root.pvk root.cer `&lt;BR&gt;&amp;nbsp;&amp;nbsp; -ss Root -sr localMachine&lt;BR&gt;makecert -pe -n "CN=PowerShell User" -ss MY -a sha1 `&lt;BR&gt;&amp;nbsp;&amp;nbsp; -eku 1.3.6.1.5.5.7.3.3 -iv root.pvk -ic root.cer&lt;BR&gt;&amp;nbsp;&amp;nbsp; MakeCert will prompt you for a private key password.&lt;/STRONG&gt; &lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Go ahead and make a certificate for yourself following those instructions. To sign your profile, within PowerShell type the following:&lt;/P&gt;
&lt;DIV style="FONT-FAMILY:Courier;"&gt;PS C:\&amp;gt;&lt;STRONG&gt;Set-AuthenticodeSignature $profile @(get-childitem cert:\CurrentUser\My -codesigning)[0] &lt;/STRONG&gt;&lt;/DIV&gt;
&lt;P&gt;So far, you've created a certificate and signed your script. Now, you will have to change your&amp;nbsp;script&amp;nbsp;execution policy&amp;nbsp;down at least one level from the default.&amp;nbsp; The default doesn't allow scripts at all.&amp;nbsp; To get scripts to execute, at the minimum you'll have to set it to "AllSigned" to allow only signed scripts to execute.&amp;nbsp; In this mode, each time you execute a script from a new publisher, you'll be asked what level of trust to assign to the&amp;nbsp;publisher (unless you respond to the prompt to "Always Run" or "Never Run" scripts from that publisher)&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;DIV style="FONT-FAMILY:Courier;"&gt;Do you want to run software from this untrusted publisher?&lt;BR&gt;File C:\Users\TobinT\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 is published by CN=PowerShell User&lt;BR&gt;and is not trusted on your system. Only run scripts from trusted publishers.&lt;BR&gt;[V] Never run&amp;nbsp; [D] Do not run&amp;nbsp; [R] Run once&amp;nbsp; [A] Always run&amp;nbsp; [?] Help (default is "D"): &lt;/DIV&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now, each new instance of PowerShell that you run will automatically load the IIS 7.0 managed assemblies.&amp;nbsp; I know it seems like a great deal of work, but it really isn't once you've made a few rounds around inside PowerShell. Consider that you only have to create the script once and then you have full the full range of the managed IIS 7.0 SDK at your fingertips inside PowerShell.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;If you have problems, feel free to leave comments and I'll do my best to help you.&lt;/P&gt;&lt;img src="http://blogs.iis.net/aggbug.aspx?PostID=1482586" width="1" height="1"&gt;</description><category domain="http://blogs.iis.net/tobintitus/archive/tags/IIS+7/default.aspx">IIS 7</category><category domain="http://blogs.iis.net/tobintitus/archive/tags/PowerShell/default.aspx">PowerShell</category><category domain="http://blogs.iis.net/tobintitus/archive/tags/SDK/default.aspx">SDK</category></item></channel></rss>