多应用池环境下IIS内存超限重启脚本报错求助
IIS多应用池环境下内存监控重启脚本修复
问题背景
部署Web应用并配置单个工作进程,需求是当IIS内存占用超限时自动重启服务。脚本在单应用池环境正常运行,但多应用池服务器上执行时报错:
Cannot find an overload for "Round" and the argument count: "2".
At I:\MONITOR\check-memory-exception-iis.ps1:7 char:1
- $process_dump32_output = [Math]::Round($process_dump32.privatememorys ...
+ CategoryInfo : NotSpecified: (:) [], MethodException + FullyQualifiedErrorId : MethodCountCouldNotFindBest
错误原因
多应用池环境下,Get-Process w3wp会返回多个w3wp进程对象的集合,而非单个对象。此时$process_dump32.privatememorysize64返回的是一个数值数组,而.NET的[Math]::Round方法没有针对数组的2参数重载(即同时指定数值和小数位数),因此触发方法匹配错误。
修复后的脚本
# 获取所有w3wp进程并计算总私有内存(字节) $totalPrivateMemory = (Get-Process w3wp | Measure-Object -Property PrivateMemorySize64 -Sum).Sum # 对总内存值保留2位小数 $process_dump32_output = [Math]::Round($totalPrivateMemory, 2) Write-Output $process_dump32_output # 定义日期变量,用于邮件主题 $Date = Get-Date -Format "yyyy-MM-dd HH:mm:ss" #Email Settings $EmailBody = 'IIS内存占用超过800MB,已自动重启服务' $subject_mail = "IIS内存占用超过800MB - $Date" $MailFrom = 'email@example.com' $MailTo = 'email2@example.com' $smtpServer = '10.0.0.1' $smtpPort = '587' $secpasswd1 = ConvertTo-SecureString "Paassword" -AsPlainText -Force $mycreds1 = New-Object System.Management.Automation.PSCredential ("notification", $secpasswd1) $encoding = [System.Text.Encoding]::UTF8 If ($process_dump32_output -lt 800000000) { # 内存低于800MB,不执行操作 } Else { # 停止并重启IIS服务 Stop-Service W3SVC Start-Sleep -Seconds 5 Start-Service W3SVC # 发送通知邮件 Send-MailMessage -From $MailFrom -To $MailTo -Subject $subject_mail -Body $EmailBody -Encoding $encoding -SmtpServer $smtpServer -Port $smtpPort -Credential $mycreds1 }
关键修改说明
- 多进程内存计算:使用
Measure-Object汇总所有w3wp进程的PrivateMemorySize64值,得到总内存占用量(单个数值),解决了数组无法直接Round的问题。 - 变量补全:添加
$Date变量的定义,避免邮件主题中因未定义变量导致的空值问题。 - 邮件内容优化:调整邮件正文和主题的描述,更清晰传达告警信息。
- 可选优化建议:如果不需要重启整个IIS服务(影响所有应用池),可改为仅重启目标应用池,示例代码如下:
# 替换原停止/重启W3SVC的代码 Import-Module WebAdministration Restart-WebAppPool -Name "你的目标应用池名称"
内容的提问来源于stack exchange,提问作者Gild
相关产品推荐
相关产品推荐

