• CarlosAg Blog

    SEO made easy with IIS URL Rewrite 2.0 SEO templates


    A few weeks ago my team released the version 2.0 of the URL Rewrite for IIS. URL Rewrite is probably the most powerful Rewrite engine for Web Applications. It gives you many features including Inbound Rewriting (ie. Rewrite the URL, Redirect to another URL, Abort Requests, use of Maps, and more), and in Version 2.0 it also includes Outbound Rewriting so that you can rewrite URLs or any markup as the content is being sent back even if its generated using PHP, ASP.NET or any other technology.

    It also includes a very powerful User Interface that allows you to test your regular expressions and even better it includes a set of templates for common types of Rules. Some of those rules are incredibly valuable for SEO (Search Engine Optimization) purposes. The SEO rules are:

    1. Enforce Lowercase URLs. It will make sure that every URL is used with only lower case and if not it will redirect with a 301 to the lower-case version.
    2. Enforce a Canonical Domain Name. It will help you specify what domain name you want to use for your site and it will redirect the traffic to the right host name.
    3. Append or Remove the Trailing Slash. It will make sure your request either include or not include the trailing slash depending on your preference.


    For more information on the SEO Templates look at:

    What is really cool is that you can use the SEO Toolkit to run it against your application and you probably will get some violations around lower-case, or canonical domains, etc. And after seeing those you can use URL Rewrite 2.0 to fix them with one click.

    I have personally used it in my Web site, try the following three URLs and all of them will be redirected to the canonical form ( and you will see URL Rewrite in action:


    Note that at the end those templates just translate to web.config settings that become part of your application that can be XCOPY with it. This works with ASP.NET, PHP, or any other server technology including static files. Below is the output of the Canonical Host Name rule which I use on my Web site’s web.config.

    <?xml version="1.0" encoding="UTF-8"?>
    <rule name="CanonicalHostNameRule1">
    <match url="(.*)" />
    <add input="{HTTP_HOST}" pattern="^www\.carlosag\.net$" negate="true" />
    <action type="Redirect" url="{R:1}" />

    There are many more features that I could talk, but for now this was just a quick SEO related post.

  • CarlosAg Blog

    IIS 7.0 Manager for Windows XP, 2003 and Vista SP1

    Technorati Tags:

    Last Wednesday we released the IIS Manager 7.0 client for Windows XP SP2, Windows Server 2003 and Windows Vista SP1.
    This is basically the IIS 7.0 Manager GUI that provides the ability to connect remotely to a Windows Server 2008 running the Web Management Service (WMSVC) to manage IIS 7.0 remotely.

    There are several key differences in this version of IIS Manager and its remote infrastructure:

    1) It allows for the first time users without administrative privileges to connect and manage their web sites and applications remotely

    2) It runs over SSL, no more DCOM, which makes this a firewall friendly feature easy to setup.

    3) Runs as a smart client, which means if a new feature is installed on the server it will automatically download the updated versions to the client machines.

    You can download it from:

    IIS.NET Web Site


    To learn more about remote management and how to install it:

    Now, to really show you what this is, I created a very simple demo that briefly shows the remote management capabilities over SSL. (Below there is a transcript in case my accent makes it difficult to understand my english :))


    The purpose of this demonstration is to show you how easy it is to manage IIS 7.0 running in Windows Server 2008, from any machine that has Windows XP or Windows 2003 or Windows Vista by downloading the IIS Manager 7.0 that runs on all of those platforms.

    Now, today I am not going to focus on the details of how to configure it and how to setup the server to support remote management, but mainly just focus on the client aspect.

    On of the most interesting aspects of this remote management infrastructure is that it now uses an architecture that uses HTTPS to communicate to the server making this a nice firewall friendly remote management feature. Another key feature of this functionality is that it allows users without administrative privileges to connect and manage their Web Sites or their applications in a delegated way, where an administrator can restrict which options they can modify or not.

    OK, so to show you this I have here a Windows Server 2008 installed with IIS 7.0, and as you would expect I can manage it locally quite easily using IIS Manager, whether its adding a Web Site or managing the configuration from both IIS or ASP.NET I can do it here.

    This is all good, but now turns out I don’t want to connect locally but instead be able to remotely from my development machine connect to the server and still be able to do that and have the same experience as if I was locally logged on to the machine.

    To show this, I have here a Virtual PC image running a clean install of Windows XP SP2, the only thing it has installed additionally is the .NET Framework 2.0 which is the only requirement for the installation of IIS Manager 7.

    I have already downloaded the IIS Manager installer which takes only about 3MB of disk, that you can find at http://www. or

    Installing it is really simple and fast, just double click the icon and click next…

    Once installed I can now connect to any machine running Windows Server 2008 that has been configured to support remote management. To do that I just need to choose the option “Connect To Server/Site/Application” from the File Menu or the Start Page.

    Today, I will not drill down on the multiple differences between these connections, so for now I will just show how you can connect and manage the entire server by using a Windows Administrator account.

    Another interesting feature of the remote management platform is that if some new feature built on top of the UI Management extensibility API is installed on the server, when I connect again to the server, it will automatically prompt me if I want to get the new functionliaty and I can choose which features to install or not.

    To summarize, the IIS Manager 7 for Windows XP SP2, 2003 SP1 and Vista SP1 is available now, it only depends on the .NET FX 2.0 and it will allow you to connect to a remote server to manage it and have the same rich experience as if you were locally but using its new SSL remoting architecture.

  • CarlosAg Blog

    Looking for an Icon Editor?


    If you are like me and every now and then develop applications that you want to create an icon for, and you don't have the money to spend on a nice commercial tool (or rather spend it in Halo 3, RockBand or Guitar Hero III), then you probably face the problem that tools don't tend to support saving bitmaps as icons.

    In the past I was using the old icon editor that came with mhh… was it Visual Basic 3? and life use to be good cause back then, icons were mostly used at 16 colors and you mostly cared for 16x16 or 32x32 sizes and the tool was decent for those scenarios. But now that icons can use thousands of colors and that you can use up to size of 256x256 it's certainly not a professional look icon when all you have is a 32x32 16 colors icon.

    So then I decide that I was going to build my own icon editor and started coding it in managed code, at the middle of it I was looking over the internet for the icon format and sure enough I was reading all the details of the format, headers, API's, etc, when suddenly searching for a specific struct yield a result that basically stopped me from doing any more code.

    Basically there is a sample in MSDN that has all the support that I need.

    It supports creating an icon, adding multiple formats to it such as 16x16 - 16 color, or 48x48-24bit color, up to 128x128-32bit color. It then allows you to import a bitmap into them and mark the transparent colors (XOR Mask and AND Mask) and everything. Additionally supports extracting icons from files, although I'm sure it could do a better job with PNG compressed files and other stuff, it's still million times better than my old icon editor.

    Nice thing it even comes with the source code in C++ in case you are interested on learning more about icon files.

    The article is from September 1995, but its still great.

    The code and executable can be downloaded from here:

    Disclaimer: I do not know how good or bad is the source code nor I pretend to recommend it against any other commercial tool, I'm just saying that its good enough for my "hobbyist" projects and you might find it useful.

  • CarlosAg Blog

    Using Microsoft.Web.Administration in Windows PowerShell


    A couple of months ago I wrote about using LINQ with Microsoft.Web.Administration to manage and query IIS 7.0 configuration. Somebody came back to me and said that LINQ was very cool but that it was very much Developer oriented and that in a production server without VS or .NET 3.5 it wouldn't be an option. Indeed that is a very valid comment and so I decided to show similar stuff with a tool that is available in Windows and its more IT oriented, Windows PowerShell.

    So in this blog I will quickly mention some of the things you can easily do with Microsoft.Web.Administration inside Windows PowerShell.

    To start working with Microsoft.Web.Administration the first thing you need to do is load the assembly so that you can start using it. It is quite easy using the methods from the Assembly type.


    Once you have the assembly available then you will need to create an instance of our ServerManager class that gives you access to the entire configuration system.

    $iis = new-object Microsoft.Web.Administration.ServerManager

    The above line basically declares a variable called $iis that we will be able to use for all of our configuration tasks.

    Now to more interesting stuff.

    Getting the list of Sites

    Getting the list of sites is as easy as just accessing the Sites collection, this will output all the information about sites

    PS C:\ > $iis = new-object Microsoft.Web.Administration.ServerManager
    PS C:\ > $iis.sites
    ApplicationDefaults : Microsoft.Web.Administration.ApplicationDefaults
    Applications : {DefaultAppPool, DefaultAppPool, DefaultAppPool, DefaultAppPool...}
    Bindings : {}
    Id : 1
    Limits : Microsoft.Web.Administration.SiteLimits
    LogFile : Microsoft.Web.Administration.SiteLogFile
    Name : Default Web Site
    ServerAutoStart : True
    State : Started

    However, we can also specify the information we care and the format we want to use, for example:

    PS C:\ > $iis = new-object Microsoft.Web.Administration.ServerManager
    PS C:\ > $iis.sites | select-object Id, Name, State
    Id Name State
    -- ---- -----
    1 Default Web Site Started
    2 Site2 Started
    3 Site3 Started

    You can also use the where-object command to filter objects to get only the sites that are Stopped, and then we want to Start them.

    PS C:\ > $iis = new-object Microsoft.Web.Administration.ServerManager
    PS C:\ > $iis.sites | where-object {$_.State -eq "Stopped"} | foreach-object { $_.Start() }

    OK, now let's imagine I want to find all the applications that are configured to run in the Default ApplicationPool and move them to run in my NewAppPool. This is better to do it in three lines:

    PS C:\ > $iis = new-object Microsoft.Web.Administration.ServerManager
    PS C:\ > $iis.sites | foreach {
    $_.Applications | where { $_.ApplicationPoolName -eq 'DefaultAppPool' } |
    foreach { $_.ApplicationPoolName = 'NewAppPool' }
    PS C:\ > $iis.CommitChanges()

    Now let's say I want to find the top 20 distinct URL's of all the requests running in all my worker processes that has taken more than 1 second.

    PS C:\ > $iis = new-object Microsoft.Web.Administration.ServerManager
    PS C:\ > $iis.WorkerProcesses | foreach {
    $_.GetRequests(1000) | sort TimeElapsed -descending |
    select-object Url -unique -first 20 }

    OK, finally let's say I want to display a table of all the applications running under DefaultAppPool and display if Anonymous authentication is enabled or not. (Now this one is almost on the edge of "you should do it differently, but it is Ok if you are only reading a single value from the section):

    PS C:\ > $iis = new-object Microsoft.Web.Administration.ServerManager
    PS C:\ > $iis.Sites | foreach {
    $_.Applications | where { $_.ApplicationPoolName -eq 'DefaultAppPool' } |
    select-object Path,@{Name="AnonymousEnabled"; Expression = {

    Again, the interesting thing is that now you can access all the functionality from M.W.A. from Windows PowerShell very easily without the need of compiling code or anything else. It does take some time to get used to the syntax, but once you do it you can do very fancy stuff.

  • CarlosAg Blog

    See you at PDC


    Well, I’m really excited to be heading to PDC’05, it sure promise to be an interesting one where we can finally show off so many new technologies we have been working so hard during this past few months to create.

    I will be there along with many of my teammates from IIS trying to show off the really cool new features that we have built into the next version of IIS which I'm sure will rock your mind if you are a Web lover like me.

    So I really hope to meet a lot of you guys out there and try to answer any questions you might have.


  • CarlosAg Blog

    Internet Information Services (IIS) 7.0 Manager for Windows XP, 2003 and Windows Vista SP1 RC0 is available for download


    NOTE: RTM has been released see the following blog: 

    With the release of Windows Server 2008 RC0, in IIS we are also releasing the ability to manage the Web Server, the new FTP Server and the new modules remotely using IIS Manager 7.0.

    In the past with previous Beta we shipped similar functionality under a different name, however for the first time this is the real way we will be supporting this remote administration from different Windows versions when Windows Server 2008 final version comes along.

    The reason this release in particular is exiting is because for the first time all the UI extensibility is enabled for these platforms making it possible to build your own UI modules, install them in the server and have the clients that connect to your server automatically download the new functionality and use it as it was part of the IIS Manager release.

    Another reason this is important for us is because this is the first time we are releasing support for x64 which is something required for customers using Windows Vista 64 bit edition or any other 64 bit version of Windows.

    You can download and install them from:



    Note: This RC0 version will not be able to connect to any other older build of Windows 2008 Server including Beta 3, so if you need to still manage Beta 3 version you will need to install the Beta 3 build of the tool which can safely live side-by-side with the RC0 build.

  • CarlosAg Blog

    Very funny blog to read, Linux Hater's blog


    One of the things I try to regularly do is to read blogs that are not necessarily pro-Microsoft and one of my favorite ones is Miguel de Icaza's blog. The other day I was reading one blog post that caught my attention about a blog he says he is a "fan of" named "Linux Hater's blog". So of course I decided to give that a read and went and started reading the entries in there, and I just could not stop laughing and laughing, and before I noticed I had been reading for almost an hour. I do have to warn though, the vocabulary used is their entries is lets say fluid?.

    Disclaimer: I'm not saying that their entries are right or wrong, I just literally couldn't stop laughing about some of the comments and their replies, and in some cases I do think they are a bit biased and in some cases they do have a good message that could help advance the software industry in general.

    Anyway, if you want to read a very "funny-colorful-passionate" blog I think its worth a read:

  • CarlosAg Blog

    Faster IIS Web Sites Provisioning using Microsoft Web Administration


    Yesterday I got an email about some performance numbers that one of our customers were running into when creating remotely Web Sites, Applications, Application Pools and other tasks in IIS using Microsoft.Web.Administration. In case you don't know Microsoft.Web.Administration is a .NET library that exposes the IIS Configuration System.

    The code was using Microsoft.Web.Administration from PowerShell to create a single Application Pool, a new Web Site, and finally assign the Root Application to the new Application Pool, and it was measuring each of the tasks. The application then was called continually till 10,000 sites were created. They then created a very nice Excel Spreadsheet that had a chart with how long it took when performing each operation that clearly show how fast (or slow) things were depending on the existing number of sites in IIS.

    Funny enough the code was doing almost exactly what we use to measure in IIS 7.0 performance while provisioning. And that we ran into very similar numbers back a couple of years ago but we probably never share them. The results back in the day were showing a trend like the one below, where the Creation of the AppPool was quite fast (less than 400ms once you had 10,000 sites), the Application Pool assignment was taking almost 10 times more (almost 4 seconds) and the creation of the Sites was taking almost 20 times more (up to 8 seconds).


    Our test code looked something like this (removing all the Timing code):

    using(ServerManager m = new ServerManager()) {
    ApplicationPool pool = m.ApplicationPools.Add("MyPool");

    Site site = m.Sites.Add("MySite", ... "d:\inetpub\wwwroot");
    site.Applications["/"].AppPoolName = "MyPool";

    Back in those days (2005) the numbers were even worst, you would have to wait literally minutes to get a site created but we profiled it and understood exactly what the performance behavior was and we made it better.

    Here is how to make it faster

    1. Most importantly batch as many changes you need to do to our configuration system so that you only CommitChanges once, for example, creating the 10,000 sites and only Committing once will probably average 1,000 sites per second. More importantly you will reduce the load on the server since every time the configuration is changed our server has to process its changes and that incurs in other CPU cycles in WAS and W3SVC.
    2. The reason we noticed Application Pools was being slower at the beginning when using ServerManager locally was just an artifact of the fact that it’s the first operation being done in our Test Script. The reason is that when you create a ServerManager in reality nothing interesting happens other than we activate a COM object that parses the schema, however whenever you request a section that is when the real XML parsing of files happens. This means that the first operation (in this case accessing the AppPool collection) pays the price of parsing machine.config, root web.config and ApplicationHost.config, which is the file that grows considerably as new sites/pools are added.
    3. Definitely using ServerManager remotely (OpenRemote) will be several times slower because every time property is set or anything is changed the code actually hits the network to set the values in the remote objects, since on the client there are only client proxies. This means that setting appPool.Name actually goes through the network to set the values on the dllhost.exe hosting DCOM.
    4. Finally the most important one, the reason the Site creation is extremely slow is because the way our test code was creating the site and the application, in particular we are using the method m.Sites.Add() which has several overloads, where most of them provide a set of "friendly-non-performant” combinations. This is due to the fact that none of them receives a Site ID which forces us to automatically calculate one every time a Site will be added. We have implemented two algorithms for this (depending on a registry key called IncrementalSiteIDCreation) and both have the issue that we need to read all the sites first to make sure we don’t generate an ID that is already in use. This means that if you have 4,000 sites we have to read all 4,000 sites and that of course over the network translates to literally thousands of round trips.
      So bottom line use the m.Sites.CreateElement() followed by a m.Sites.Add(newSite) which will not create an ID for the Site that will not incur in the costs mentioned. Something like the snippet below. Notice that there is a little bit more code since you also need to create the Root Application and set the bindings, but this will proof useful since setting the AppPoolName requires the App anyway and you save all the Lookups on the Sites list as well.
    5. using(ServerManager m = new ServerManager()) {
      ApplicationPool pool = m.ApplicationPools.Add("MyPool");

      Site site = m.Sites.CreateElement("site");
      site.Name = "MySite"
      site.ID = "MySite".GetHashCode();

      Application app = site.Applications.Add("/", "d:\inetp...");
      app.AppPoolName = "MyPool";

    After all that story, what is important to realize is that there are ways to make this way faster and that you should use them if you are going to do any sort of massive creation of sites. With the two changes outlined above (Specify the Site ID yourself and don't lookup the Site again to get the App) the results were incredible we were back to under 350ms for all the tasks.

  • CarlosAg Blog

    Backgammon and Connect4 for Windows Mobile


    During the holidays my wife and I went back to visit our families in Mexico City where we are originally from. Again, during the flights I had enough spare time to build a couple of my favorite games, Backgammon and Connect4.

    I've already built both games for Windows using Visual Basic 5 almost 11 years ago but as you would imagine I was far from feeling proud of the implementation. So this time I started from scratch and ended up with what I think are better versions of them (still not the best code, but pretty decent for just a few hours of coding). In fact the AI for the Backgammon version is a bit better and the Connect4 is faster and more suited for a Mobile device.

    You can go with your PDA/Smartphone to to install both games or just click the images below to take you to the install page of each of them. Enjoy and feel free to add any feedback/features as comments to this blog post.

    The one thing I learned during the development of these versions is that you do want to download the Windows Mobile 6 SDK if you are going to target that version (which is what my cell phone has), since it will add new Visual Studio 2005 Project Templates and new Emulator images which will help you a lot. For example I was trying to use buttons in my forms, and testing it in Pocket PC worked, but as soon as I tried them in my cell phone it crashed with a NotSupportedException. When I installed the SDK and switched to target that platform, Visual Studio immediately warned me that my platform didn't supported buttons which was great.

    Bottom line I'm more and more amazed of how easy it is to build games in Windows Mobile and the things you can achieve with both Windows Mobile and the .NET Compact Framework.

  • CarlosAg Blog

    IIS 7.0 Remote Administration and Database Manager Video

    • 5 Comments published a very nice video that shows how you can enable IIS Manager and Database Manager and other modules for their customers.

    If you don't use as your ISP at least its interesting to see how IIS 7.0 and its Remote Administration capabilities over HTTPS and Delegated Management look like. Also you can see the Database Manager in action that you can download for free from

    First couple of minutes show how they expose this functionality to their customers, but If you just care to see the IIS 7.0 features running seek to minute 2:00.

Page 3 of 10 (91 items) 12345»