The Script
What the script does:
- Logs the initial state of the app pool.
- Logs details about the worker processes before stopping the app pool.
- Increases the shutdown time limit to give more control.
- Stops and restarts the app pool, logging how long it takes and any errors.
- Logs worker process details after the app pool is restarted.
$AppPoolName = "App"
$LogFilePath = "C:\Scripts\Logs\App.txt"
Import-Module WebAdministration
# Function to log messages with a timestamp
function Write-Log {
param (
[string]$Message
)
$timestamp = Get-Date
$formattedMessage = "$timestamp - $Message"
Add-Content -Path $LogFilePath -Value $formattedMessage
}
# Log initial state of the application pool
$initialState = (Get-WebAppPoolState -Name $AppPoolName).Value
Write-Log "Initial state of Application Pool '$AppPoolName': $initialState"
# Log worker process details before stopping (if available)
$preStopProcesses = Get-WmiObject Win32_Process | Where-Object {
$_.CommandLine -match $AppPoolName -and $_.Name -eq "w3wp.exe"
}
if ($preStopProcesses) {
foreach ($process in $preStopProcesses) {
Write-Log "Pre-stop Process ID: $($process.ProcessId), Memory Usage: $([math]::Round($process.WorkingSetSize/1MB, 2)) MB"
}
} else {
Write-Log "No running worker processes found for '$AppPoolName'."
}
# Increase the shutdown time limit to 300 seconds (5 minutes)
Set-ItemProperty "IIS:\AppPools\$AppPoolName" -Name "shutdownTimeLimit" -Value "00:05:00"
# Attempt to stop the application pool and log shutdown duration
try {
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
Stop-WebAppPool -Name $AppPoolName
$stopwatch.Stop()
Write-Log "Stopped Application Pool '$AppPoolName' in $($stopwatch.Elapsed.TotalSeconds) seconds."
} catch {
Write-Log "Error stopping Application Pool '$AppPoolName': $_"
}
# Log state after stopping
$postStopState = (Get-WebAppPoolState -Name $AppPoolName).Value
Write-Log "State of Application Pool '$AppPoolName' after stop command: $postStopState"
# Start the application pool
try {
Start-WebAppPool -Name $AppPoolName
Write-Log "Started Application Pool '$AppPoolName' successfully."
} catch {
Write-Log "Error starting Application Pool '$AppPoolName': $_"
}
# Log state after starting
$finalState = (Get-WebAppPoolState -Name $AppPoolName).Value
Write-Log "Final state of Application Pool '$AppPoolName' after start command: $finalState"
# Log worker process details after starting
$postStartProcesses = Get-WmiObject Win32_Process | Where-Object {
$_.CommandLine -match $AppPoolName -and $_.Name -eq "w3wp.exe"
}
if ($postStartProcesses) {
foreach ($process in $postStartProcesses) {
Write-Log "Post-start Process ID: $($process.ProcessId), Memory Usage: $([math]::Round($process.WorkingSetSize/1MB, 2)) MB"
}
} else {
Write-Log "No running worker processes found for '$AppPoolName' after start."
}
Explanation
Logging Functionality: The Write-Log function just logs messages to a file with a timestamp. It keeps track of what’s going on when things start and stop.
Managing App Pool State: The script uses Get-WebAppPoolState, Stop-WebAppPool, and Start-WebAppPool cmdlets from the WebAdministration module.
Worker Process Details: I use Get-WmiObject to grab info about the worker processes (w3wp.exe) tied to the app pool. It logs process IDs and memory usage before stopping and after starting the app pool.
Shutdown Time Limit: Bumping the shutdown time limit to 300 seconds gives ongoing requests a better chance to finish before the app pool shuts down.