Tuesday, April 14, 2020

Change recycle settings of IIS AppPools using PowerShell & appcmd.exe

Background

The app pool recycle is a hack to hide our or .Net's poor memory management. When we refer poor .Net memory management, it means the LOH fragmentation which was not compacted in earlier versions of .Net CLR. Hence we need to set up the app pool recycle in IIS.

Changing or 'recycling' setting of an app pool in one server one time is easy and can be manual. But what if there are many app pools, servers and had to do multiple times. Obviously, it should be automated. This post is about some snippets about automating the same using some of the provided mechanisms.

AppCmd

This is a command which we can use to manipulate IIS programmatically from IIS 7 onwards. Location of appcmd.exe is [install drive]:\Windows\System32\inetsrv\appcmd.exe. Direct commands to manipulate IIS entities are very easy but chaining the commands is a little different. If we are from PowerShell background, we feel it very odd. It outputs XML and subsequent commands to read XML as input.

Below is a mix of PowerShell and AppCmd.exe to disable periodic recycling of app pools.

Import-Module WebAdministration
$pools= dir IIS:\AppPools
$pools | Foreach-Object{
    $appPoolName=$_.name
    $cmd="C:\Windows\System32\inetsrv\appcmd.exe set apppool /apppool.name: '$appPoolName' /-recycling.periodicRestart.schedule"
    Invoke-expression $cmd
}

As clear in the above snippet, the PowerShell iterates thought the AppPool and invoke the AppCmd.exe for each app pool with its name
Another drawback of AppCmd.exe is that we cannot manage remote machines using this command only. We need to combine with PowerShell to execute this command in the remote machine.

PowerShell

There are 2 PowerShell modules.

WebAdministration

  • This mainly gives a provider which we can query just like file system
  • Microsoft considers WebAdministration PowerShell module legacy and not bringing to Nano server. Clearly means someday WebAdministration will be discontinued from support.

IISAdministration


PowerShell Function to set Recycling

Though WebAdministration is considered legacy, this post uses that to achieve the job of managing AppPool recycling.

function Set-ApplicationPoolRecycleTimes {     
    param ([string]$ApplicationPoolName, [string[]]$RestartTimes)
    Import-Module WebAdministration       
    Clear-ItemProperty IIS:\AppPools\$ApplicationPoolName -Name Recycling.periodicRestart.schedule       
    foreach( $restartTime in $RestartTimes)
    {
        New-ItemProperty -Path "IIS:\AppPools\$ApplicationPoolName" -Name Recycling.periodicRestart.schedule -Value @{value=$restartTime}           
    }
}

It has 2 parameters. First it clears the existing settings and then applies the new settings.Below is the method to call function to clear recycling. Just skip the second parameter $RestartTimes to clear the property.

Set-ApplicationPoolRecycleTimes -ApplicationPoolName 'DefaultAppPool'

The code below shows how to call the function to set new times. The parameters can be given just comma-separated or as and string array.

Set-ApplicationPoolRecycleTimes -ApplicationPoolName "DefaultAppPool" -RestartTimes "1:00","2:00","14:00"

Please note that the times expected are in 24-hr clock format. If we use the AM or PM what the IIS manager shows, this script will error with cast exception.

Let's see how we can manage all the app pools in a machine.

Applying to all the pools

Just loop all the app pools and call the function.

$pools= dir IIS:\AppPools
#$pools | ForEach-Object { Set-ApplicationPoolRecycleTimes($_.name) }

PowerShell has Invoke-Command to run scripts in remote machines. The same method can be used to control IIS in remote machines.

References

https://www.habaneroconsulting.com/stories/insights/2013/set-the-specific-times-to-recycle-an-application-pool-with-powershell
https://forums.iis.net/t/1229302.aspx

No comments: