Automating IIS actions with PowerShell – Create Multiple Sites

I’m working towards a more complex SignalR based post, but in the mean time part of the work on that involves setting up a few ASP.NET web apps.

If you’re after a more comprehensive guide check out this post on learn.iis.net by Thomas Deml. I’ve summarised the steps required to get some basic .NET 4 web applications deployed.

Objective
To create N identical websites in local IIS, each with an incrementing name Id. Each linked to the same application directory. The exact reason as to why will come in a future post, for now consider it an exercise in manipulating IIS via PowerShell.

s1.site.local
s2.site.local

Step 1 – Ensure you’re running the scripts in x86 mode.

Which seems quite common a problem, with a stackoverflow question. I haven’t worked a way around this yet, but this is the error when not running as x86:

New-Item : Cannot retrieve the dynamic parameters for the cmdlet. Retrieving the COM class factory for component with CLSID {688EEEE5-6A7E-422F-B2E1-6AF00DC944A6} failed due to the following error: 80040154.
At line:1 char:9
+ New-Item <<<< AppPools\test-app-pool
+ CategoryInfo : InvalidArgument: (:) [New-Item], ParameterBindingException
+ FullyQualifiedErrorId : GetDynamicParametersException,Microsoft.PowerShell.Commands.NewItemCommand

Step 2 – Import-Module WebAdministration
This loads the IIS namespace which allows you to just navigate in the same way you would the filesystem

> CD IIS:\

Step 3 – Create & Configure App Pool

    New-Item AppPools\test.pool

    Set-ItemProperty IIS:\AppPools\test.pool -name "enable32BitAppOnWin64" -Value "true"

    Set-ItemProperty IIS:\AppPools\test.pool -name "managedRuntimeVersion" -Value "v4.0"

NOTE: here I didn’t have any luck storing the app pool path in a variable then using Set-ItemProperty, hence the repeating.

Step 4 – Variables

    $sitesToCreate = 10
    $path = "C:\dev\project-x\App.Web"
    $appPool = "test.pool"

Step 5 – Create Site & Link AppPool Loop

For N(10) to zero:

  • Create a new site
  • Set binding info and physical path
  • Set the app pool
    while ($sitesToCreate -gt 0)
    { 
        $siteName = "s" + $sitesToCreate + ".site.local"
        $siteWithIISPrefix = "IIS:\Sites\" + $siteName
        Write-Host "Creating: " $siteName
        
        $site = New-Item $siteWithIISPrefix -bindings @{protocol="http";bindingInformation="*:80:" + $siteName } -physicalPath $path
        
        Set-ItemProperty IIS:\Sites\$siteName -name applicationPool -value $appPool
        $sitesToCreate--
    }

Note: ‘appPool’ is a text variable, not the ‘Get-Item’. Set-ItemProperty operates on a path not a variable representing the item.

We’re done

One last note, to get these to resolve correctly on your local developer machine you’ll need to modify your hosts file.

IIS multisite

The complete code up as a Github Gist.

Migrating a Legacy Web Forms Application to Web Forms MVP

Since I put “Legacy” in the post title to begin with, I would like to share some quotes from the often quoted Michael Feathers author of Working Effectively with Legacy Code. If you haven’t read it, you should – it comes highly recommended by many developers including Scott Hanselman on this Hanselminutes episode. But full disclosure I myself have only read a few random sections of it here and there.

Working Effectively with Legacy Code

What do you think about when you hear the term legacy code? If you are at all like me, you think of tangled, unintelligible structure, code that you have to change but don’t really understand. You think of sleepless nights trying to add in features that should be easy to add, and you think of demoralization, the sense that everyone on the team is so sick of a code base that it seems beyond care, the sort of code that you just wish would die.
–Feathers

This I strongly agree with, not to say that legacy code is always “unintelligible” or you want the code “to die”, but very often it requires a much larger unit of time to change when compared to more desirable (maintainable) code, which leads to this quote:

In the industry, legacy code is often used as a slang term for difficult-to-change code that we don’t understand.
–Feathers

This can be remedied in part by unit-tests…

Code without tests is bad code. It doesn’t matter how well written it is; it doesn’t matter how pretty or object-oriented or well-encapsulated it is. With tests, we can change the behavior of our code quickly and verifiably. Without them, we really don’t know if our code is getting better or worse.
–Feathers

That last quote from Feathers helps to outline my motives…

At my current place of employment we have a flagship application that was originally built using ASP.NET 1.1. Then slowly migrated to .NET framework 2.0 and then immediately converted for .NET framework 3.5. That task itself was not trivial, and now there is a new challenge to make the code more maintainable.

The legacy system was written in … but it worked, and it worked great … It was legacy because it wasn’t done with new and shiny…
–Hanselman

Hanselman makes a good point even though I paraphrased so it’s a more general statement. This applies to the application I’m working on improving. The application was in fact working “fine” in its .NET 1.1 form, but making changes/improvements was difficult. When I say difficult in this case I, in particular mean for new developers not familiar with the code base and application. Being the newest developer to work on this, I wanted the code base to improve so we could all make changes and improvements with confidence going forward.

This is the first in yet another series of posts from me. This series will focus on how we’ve gone about undertaking this migration. I’ll attempt to make each post stand reasonably alone to demonstrate migrating a specific application component from Web Forms to the Model-View-Presenter (MVP) pattern and in particular the Web Forms MVP framework.

Some of the objectives that we’re trying to achieve from this framework migration include:

blog.fossmo.net MVP diagram

This also leads down the path of improved development practices for the team:

silverbullet

So then what…

Web Forms by design does not lend itself to achieving all the objectives listed above and it is hoped that the use of the Web Forms MVP framework will take us down a better path. I say this with full understanding that there is no such thing as a Silver Bullet in software development, and that the adoption of a pattern and a supporting framework are just steps we are taking.

We’ve come this far in the post and I haven’t exactly outlined what Web Forms MVP is and why it’s our choice. So first, how about the obligatory pasting of the front page quote from the official project site:

The ASP.NET Web Forms MVP project is about bringing the love back to Web Forms through a renewed approach to using it – an approach that facilitates separation of concerns and testability whilst maintaining the rapid development that Web Forms was built to deliver.
WebFormsMVP.com

The choice to use Web Forms MVP as the framework to help us achieve the MVP pattern in our application, comes from the knowledge of successful implementations by Readify on large scale sites such as Grays Online. Along with an active community of developers working on the framework and its acceptance into the CodePlex Foundation.

Examples coming up…

Now that we’ve got the background and I’ve publicly committed to “better code” and “testable code”, the next post in this series will be about moving your OnLoad & Page_Load methods out of your code-behind files and some of the challenges.

Victoria.NET January 2010 Session

I just got home from a slightly longer than usual Melbourne Vic.NET session, it was a very intense night, so intense I’ve got a second post lined up just to cover the second presentation. But first there were a few announcements:

  • David Burela reminded us of the April Cloud Camp.
  • Mahesh reminded us of the Silverlight Code Camp weekend end of January. I’m confirmed to be attending this.
  • Also that the User Group is looking for company sponsorship, as the current budget is shrinking

The two topics of the evening were:

  1. An overview and walk-through of some of the features in ASP.NET MVC 2, presented by Malcolm Sheridan and
  2. Command Query Responsibility Segregation, presented by Udi Dahan that I discuss in greater detail here [link coming soon].

The ASP.NET MVC 2 talk was a quick walk through with tips:
The take-away notes were:

  • Areas are useful in particular the ability to have them in a separate project (though that’s currently not functional in the RC). MSDN Link.
  • When using areas be careful on how your routes are impacted
  • Improved validation and custom validation options, through the use of ValidationAttribute interface
  • Validation re-use, in conjunction with Dynamic Data.
  • Other miscellanous improvements, such as shorter AcceptVerbs; Get/Post.

ASP.NET MVC 1.0 Out and Free (as in Free Speech)

So if you feel the need go nuts; using it, customising and contributing – http://www.codeplex.com/aspnet.

For detailed information go right to the source: Scott Guthrie’s Blog post along with Scott Hanselman’s Blog Post that has some additional information.

More Links: