Set the specific times to recycle an application pool with PowerShell

When you first create an application pool for a SharePoint web application, the application pool by default will recycle sometime in the early morning. This is good and we want this, but it’s always nice to control when exactly IIS will recycle the application pool.

A screenshot showing the default specific times the application pool will recycle. In this case the application pool recycles at 1:29 AM.

To set this with the UI is easy, check out Configure an Application Pool to Recycle at a Scheduled Time (IIS 7). Microsoft goes on to show you how to set a time with appcmd.exe, but this command adds a new time and it doesn’t get rid of the existing time. What can I do if I want a new time to recycle the pool and I want to use PowerShell?

The value that contains the recycle times is the application pool’s Recycling.periodicRestart.schedule property. This property contains a collection of times, each of which defines a specific time the application pool will recycle.

If you want to simply set a single time like 4:00 a.m., import the WebAdministration PowerShell module that ships with IIS 7.0 and then use Set-ItemProperty to set the time. From an elevated PowerShell window run:

Import-Module WebAdministration
Set-ItemProperty -Path "IIS:\AppPools\Example Application Pool" -Name Recycling.periodicRestart.schedule -Value @{value="04:00"}

“Example Application Pool” is the name of the application pool (and if the name includes spaces like this one, you’ll need the surrounding quotes). This is the same name you would have specified for the application pool when you created the web application through either the UI or with the New-SPWebApplication cmdlet's -ApplicationPool parameter.

And just like that, it’s set, overwriting the previous 1:29 a.m. value:

We've updated the specific time from 1:29 to 4:00

That’s neat. You can stop reading at this point if this was all you wanted to do. I won’t mind, really. The rest is just a rambling yarn about a man and his farm and I won’t be offended in the slightest.

Now let’s say your using a custom farm solution developed by a vendor who thinks memory leaks are the side effects of a long night of drinking. As it were, you find your portal works best when you force a recycle of the application pool at lunch time which is coincidentally around the same time the 4 MB solution has eaten up 16 GB of memory on your SharePoint server. This is a good candidate for multiple recycles throughout the day. Let’s say once at 5:55 p.m. before the CEO starts work and again at 12:55 p.m. before everyone returns from lunch. At our example company everyone heads out at 5:00 p.m. so there’s no need to recycle again until the morning.

This time we can use Set-ItemProperty to set the 5:55 p.m. recycle, but if we use it again to recycle at 12:55 p.m. something unexpected happens:

Import-Module WebAdministration
Set-ItemProperty -Path "IIS:\AppPools\Example Application Pool" -Name Recycling.periodicRestart.schedule -Value @{value="05:55"}
Set-ItemProperty -Path "IIS:\AppPools\Example Application Pool" -Name Recycling.periodicRestart.schedule -Value @{value="12:55"}

A screenshot of the application recycling times showing only our second time, 12:55 applied

When we set the 12:55 p.m. recycle, it destroyed our 5:55 a.m. recycle, which makes sense. It makes sense because four paragraphs ago we saw Set-ItemProperty overwrote the default value with 4:00 a.m. If we want more than one recycle time we'll need some way to add multiple values.

Meet New-ItemProperty. It creates new properties and adds values to an existing property and in PowerShell this makes total sense. In this case, we can use Set-ItemProperty to set our 5:55 a.m. recycle and with changing two characters from our last script (an ‘S’ becomes an ‘N’ and a ‘t’ becomes a ‘w’), we can use New-ItemProperty to add our 12:55 p.m. recycle:

Import-Module WebAdministration
Set-ItemProperty -Path "IIS:\AppPools\Example Application Pool" -Name Recycling.periodicRestart.schedule -Value @{value="05:55"}
New-ItemProperty -Path "IIS:\AppPools\Example Application Pool" -Name Recycling.periodicRestart.schedule -Value @{value="12:55"}

A screenshot showing the correct application of both recycle times: 5:55 and 12:55

You know, since we’ve gone to all this trouble setting the value with PowerShell, while we’re here we can also verify the times with the Get-ItemProperty cmdlet by looking at the collections in the schedule property:

Get-ItemProperty "IIS:\AppPools\Example Application Pool" -Name Recycling.periodicRestart.schedule.collection

A screenshot showing the contents of the periodicRestart times

And this works fine. We could stop here and I could say this is how you can set multiple recycle times and we’d all be fine. Finer still, we can generalize this assuming we don’t know before hand how many recycling times we need for the application pool (humour me). Using Set-ItemProperty complicates the issue so instead of overwriting whatever times are there we can delete everything in the property with Clear-ItemProperty and use only New-ItemProperty to add times.

Let’s look at this in an example that would better reflect a general case using a function.

function Set-ApplicationPoolRecycleTimes {

	param (
		[string]$ApplicationPoolName,
		[string[]]$RestartTimes
	)
	
	Import-Module WebAdministration
	
	Write-Output "Updating recycle times for $ApplicationPoolName"
	
	# Delete all existing recycle times
	Clear-ItemProperty IIS:\AppPools\$ApplicationPoolName -Name Recycling.periodicRestart.schedule
	
	foreach ($restartTime in $RestartTimes) {

		Write-Output "Adding recycle at $restartTime"
		# Set the application pool to restart at the time we want
		New-ItemProperty -Path "IIS:\AppPools\$ApplicationPoolName" -Name Recycling.periodicRestart.schedule -Value @{value=$restartTime}
		
	} # End foreach restarttime
	
} # End function Set-ApplicationPoolRecycleTimes

Before we use our function, I was just informed that our CEO wants to work late and would very much appreciate if we “did the restarty thing to make the website not slow.” So let's add another recycle at 5:00 p.m.:

$apppoolname = "Example Application Pool"
$restartat = @("05:55", "12:55", "17:00")

Set-ApplicationPoolRecycleTimes -ApplicationPoolName $apppoolname -RestartTimes $restartat

A screenshot showing our threerecycle times: 5:55 AM, 12:55 PM, and 5:00 PM

How’s that for the most climactic article on PowerShell you’ve read today? Now that you’ve set the application pool recycling times, you can focus your efforts on getting your solution vendor to learn how to use SPDisposeCheck. Seriously, you shouldn't normally need to restart the application pool more than once a day.

References

Stories say it best.

Are you ready to make your workplace awesome? We're keen to hear what you have in mind.

Interested in learning more about the work we do?

Explore our culture and transformation services.

Our commitment to reconciliation

Learn how Habanero is responding to the Truth and Reconciliation Calls to Action as a settler-owned company operating on Indigenous territories across what is now called Canada.

Read about our commitment