In the last few weeks I've annoyingly been having problems with an area on my Web site. It's basically ancient articles that are using ASP classic pages and for reasons unknown ASP classic locks up on these pages frequently. It's not an individual page, but ALL ASP classic pages lock up. Ah yes, gotta old tech gone bad. It's not super critical since the content is really old, but still a hassle since it's linked content that still gets quite a bit of traffic. When it happens all ASP classic in that AppPool dies. I've been having a hard time tracking this one down - I suspect an errant COM object I have a Web Monitor running on the server that's checking for failures and while the monitor can detect the failures when the timeouts occur, I didn't have a good way to just restart that particular application pool. I started putzing around with PowerShell, but - as so often seems the case - I can never get the PowerShell syntax right - I just don't use it enough and have to dig out cheat sheets etc. In any case, after about 20 minutes of that I decided to just create a small .NET Console Application that does the trick instead, and in a few minutes I had this:using System;
using System.Collections.Generic;
using System.Text;
using System.DirectoryServices;
namespace RecycleApplicationPool
{
class Program
{
static void Main(string[] args)
{
string appPoolName = "DefaultAppPool";
string machineName = "LOCALHOST";
if (args.Length > 0)
appPoolName = args[0];
if (args.Length > 1)
machineName = args[1];
string error = null;
DirectoryEntry root = null;
try
{
Console.WriteLine("Restarting Application Pool " + appPoolName + " on " + machineName + "...");
root = new DirectoryEntry("IIS://" + machineName + "/W3SVC/AppPools/" +appPoolName);
Console.WriteLine(root.InvokeGet("Name"));
root.Invoke("Recycle");
Console.WriteLine("Application Pool recycling complete...");
}
catch(Exception ex)
{
error = "Error: Unable to access AppPool: " + ex.Message;
}
if ( !string.IsNullOrEmpty(error) )
{
Console.WriteLine(error);
return;
}
}
}
}
To run in you basically provide the name of the ApplicationPool and optionally a machine name if it's not on the local box.
RecyleApplicationPool.exe "WestWindArticles"
And off it goes. What's nice about AppPool recycling versus doing a full IISRESET is that it only affects the AppPool, and more importantly AppPool recycles happen in a staggered fashion - the existing instance isn't shut down immediately until requests finish while a new instance is fired up to handle new requests.
So, now I can easily plug this Executable into my West Wind Web Monitor as an action to take when the site is not responding or timing out which is a big improvement than hanging for an unspecified amount of time.
I'm posting this fairly trivial bit of code just in case somebody (maybe myself a few months down the road) is searching for ApplicationPool recyling code. It's clearly trivial, but I've written batch files for this a bunch of times before and actually having a small utility around without having to worry whether Powershell is installed and configured right is actually an improvement. Next time I think about using PowerShell remind me that it's just easier to just build a small .NET Console app, 'k? :-)
Resources
Download Executable and VS Project© Rick Strahl, West Wind Technologies, 2005-2012Posted in IIS7 .NET Windows
Tweet
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();