Monday, June 26, 2017

Setting Application Pool Recycling Values with PowerShell

As I mentioned a while ago, I'm working on a new PowerShell book (See http://tfl09.blogspot.co.uk/2017/04/my-next-powershell-book.html for details! In writing the book, I've been creating simple scripts to do useful things. In researching them, I found a number of aspects really well covered, reference wise. Other things were not covered well if at all. I hope to post some things I've discovered in the coming months.

With IIS, you can create applications that run in application pools. An application is some set of web pages (with related executables). An application pool is a process, or processes, that run this application. This provides process isolation between applications reducing the impact a badly behaved application can have on other applications running on the same server. Resource leaks can bring an entire web server down, for example.

One way to minimise these sorts of issues is to recycle the application pool - just stop then restart the processes running the application. A neat trick that reduces the risks of resource leaks. One downside is that any state within the application is lost. Needless to say, there are other ways to save state that are not affected by an application pool restart. For a fuller look at the things you can do to configure application pools, see: https://technet.microsoft.com/en-us/library/cc745955.aspx. This document is old, but is a good starting point (and worked fine on IIS 10 for my needs).

You set application pool recycling values, using PowerShell, by setting item properties on certain items within the WebAdministration provider (the IIS: drive). This is simple, but the property names are not all that obvious at first.

What I wanted to do was:

  • Set specific times at which to recycle the application pool
  • Set the pool to automatically if private memory rises beyond a limit, say 1GB.
  • Set the pool to recycle the pool after the pool processes a certain number of requests, say 1 million.

In PowerShell, once you know where to look, this is simple:

# Set Application Pool Restart time
Clear-ItemProperty IIS:\AppPools\WWW2Pool -Name Recycling.periodicRestart.schedule
$RestartAt = @('07:55', '19:55') 
New-ItemProperty -Path 'IIS:\AppPools\WWW2Pool' -Name Recycling.periodicRestart.schedule -Value $RestartAt

# Set Application Pool Maximum Private memory
Clear-ItemProperty IIS:\AppPools\WWW2Pool -Name Recycling.periodicRestart.privatememory
[int32] $PrivMemMax = 1GB
Set-ItemProperty -Path "IIS:\AppPools\WWW2Pool" -Name Recycling.periodicRestart.privateMemory -Value $PrivMemMax

# Set max requests before a recycle
Clear-ItemProperty IIS:\AppPools\WWW2Pool -Name Recycling.periodicRestart.requests
[int32] $MaxRequests = 100000
Set-ItemProperty -Path "IIS:\AppPools\www2POOL" -Name Recycling.periodicRestart.requests -Value $MaxRequests

Some things that caught me out a bit:
1. Finding out the property names. In the case of recycling after 1m hits, the property name is 'Recycling.periodicRestart.PrivateMemory'. I suspect this naming is used by the provider to access the underlying XML that IIS actually uses to hold configuration information.
2. Finding values is easy, if there is one. I found the easitest way to set these values was to first clear the property, then set it.
3. Some item properties take properties of a certain type. It helps to specify the type (as shown above) as some times PowerShell tries to be helpful which can confuse the provider.