Powershell 脚本在满足条件后不退出循环并在失败条件下被捕获
Powershell Script Not Exiting Loop after Conditions are Met and Getting Caught on Failure Condition
我正在编写一个 powershell 脚本来停止和启动远程服务器上的服务。如果重新启动操作失败,我希望脚本发送电子邮件警报。
脚本的目标是停止服务,休眠几秒钟,然后检查服务。如果服务不是运行ning,请尝试启动服务并休眠,然后再检查。每次脚本无法启动服务时,它都会向重试计数 +1,如果重试计数超过最大重试次数,脚本将触发失败通知。如果服务是 运行ning,它应该将重启操作标记为完成并退出循环。
我遇到的问题是,当我第一次 运行 脚本时,它进入循环,检查服务并错误地将其标记为完成。之后我去检查服务时,服务显示已停止。当我第二次 运行 脚本时,它停止服务,进入循环,尝试重新启动服务,循环 3 次,然后捕捉到旨在触发和电子邮件警报的失败条件。它一直在失败条件下循环,几十次,直到我强制退出。
我整晚都在为这个问题挠头,我想不出我哪里错了。我将 post 下面的脚本:
$VerbosePreference = "continue"
$remoteServer = 'My-RemoteServer01'
$serviceName = 'MSSQLServerOLAPService'
$service = Get-Service -name $ServiceName
$maxRetries = 2
$retryCount = 0
$restartComplete = $false
stop-service -name $serviceName
write-verbose 'Service Stopped - Sleep 15s'
start-sleep -s 15
write-verbose "Attempt to restart service '$retryCount' "
while ($restartComplete -eq $false){
if ($service.status -eq 'Running')
{
$restartComplete = $true
write-verbose "restart complete"
}
else {
if ($retryCount -ge $maxRetries)
{
write-verbose "Service Restart Failed - Begin Alert"
$smtpServer = ('smtp.mymailserver.com', 00)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$dateString = get-date
$msg.From = 'no-reply@mymailserver.com'
$msg.To.Add('L3LYZA@mymailserver.com')
$msg.subject = 'URGENT ALERT - Service ' + $service + 'is' + $service.status + 'on' + $remoteServer + '.'
$msg.body = ([string]$dateString) + 'Service' + $service + 'is' + $service.status + 'on' + $remoteServer + '.'
$smtp.send($msg)
write-verbose "Alert Sent - Complete"
}
else {
if ($service.status -ne 'Running')
{
start-service -name $serviceName
write-verbose 'Service Restarting - Sleep 45s'
start-sleep -s 45
$retryCount++
}
}
}
}
编辑:解决方案最终改变了我检查服务状态的方式。我还在失败条件中添加了一个 throw。
$VerbosePreference = "continue"
$remoteServer = 'My-RemoteServer'
$serviceName = 'MSSQLServerOLAPService'
$service = Get-Service -name $ServiceName
$maxRetries = 2
$retryCount = 0
$restartComplete = $false
stop-service -name $serviceName
write-verbose 'Service Stopped - Sleep 15s'
start-sleep -s 15
write-verbose "Attempt to restart service '$break' "
while ($restartComplete -eq $false){
if ((Get-Service $serviceName).Status -eq 'Running')
{
$restartComplete = $true
write-verbose "restart complete"
}
else {
if ($retryCount -ge $maxRetries)
{
write-verbose "Service Restart Failed - Begin Alert"
$smtpServer = ('smtp.mymailserver.com', 00)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$dateString = get-date
$msg.From = 'noreply@mymailserver.com'
$msg.To.Add('L3LYZA@mymailserver.com')
$msg.subject = 'URGENT ALERT - Service ' + $service + 'is' + $service.status + 'on' + $remoteServer + '.'
$msg.body = ([string]$dateString) + 'Service' + $service + 'is' + $service.status + 'on' + $remoteServer + '.'
$smtp.send($msg)
write-verbose "Alert Sent - Complete"
Throw "service restart failed exit condition met"
}
else {
if ((Get-Service $serviceName).Status -ne 'Running')
{
start-service -name $serviceName
write-verbose 'Service Restarting - Sleep 45s'
start-sleep -s 45
$retryCount++
}
}
}
}
不确定这是否是错误,但发现了一些似乎是错误的东西。
您在第 3 行检查服务状态,但在第 9 行停止服务。然后在第 16 行检查状态是否为 运行ning。您需要再次 运行 Get-Service 以获取服务的更新状态。
您可以通过以下方式完成此操作:
(Get-Service $serviceName).Status
我的建议如下:
$VerbosePreference = "continue"
$remoteServer = 'My-RemoteServer01'
$serviceName = 'MSSQLServerOLAPService'
$service = Get-Service -name $ServiceName
$maxRetries = 2
$retryCount = 0
$restartComplete = $false
stop-service -name $serviceName
write-verbose 'Service Stopped - Sleep 15s'
start-sleep -s 15
write-verbose "Attempt to restart service '$retryCount' "
start-service -name $serviceName
while ($restartComplete -eq $false) {
if ((Get-Service $serviceName).Status -eq 'Running') {
$restartComplete = $true
write-verbose "restart complete"
}
else {
if ($retryCount -ge $maxRetries) {
write-verbose "Service Restart Failed - Begin Alert"
$smtpServer = "smtp.mymailserver.com"
$dateString = get-date
$mailFrom = 'no-reply@mymailserver.com'
$mailTo('L3LYZA@mymailserver.com')
$mailSubject = 'URGENT ALERT - Service ' + $service + 'is' + $service.status + 'on' + $remoteServer + '.'
$mailBody = ([string]$dateString) + 'Service' + $service + 'is' + $service.status + 'on' + $remoteServer + '.'
Send-MailMessage -SmtpServer $smtpserver -From $mailFrom -To $mailTo -Subject $mailSubject -Body $mailBody
write-verbose "Alert Sent - Complete"
}
else {
if ($service.status -ne 'Running') {
start-service -name $serviceName
write-verbose 'Service Restarting - Sleep 45s'
start-sleep -s 45
# Get an updated status from the service:
$service = Get-Service -name $ServiceName
$retryCount++
}
}
}
}
请记住,我将邮件更改为本机 Powershell Send-MailMessage。您选择“Net.Mail.MailMessage”可能是有原因的,所以如果是,请将其改回。
我正在编写一个 powershell 脚本来停止和启动远程服务器上的服务。如果重新启动操作失败,我希望脚本发送电子邮件警报。
脚本的目标是停止服务,休眠几秒钟,然后检查服务。如果服务不是运行ning,请尝试启动服务并休眠,然后再检查。每次脚本无法启动服务时,它都会向重试计数 +1,如果重试计数超过最大重试次数,脚本将触发失败通知。如果服务是 运行ning,它应该将重启操作标记为完成并退出循环。
我遇到的问题是,当我第一次 运行 脚本时,它进入循环,检查服务并错误地将其标记为完成。之后我去检查服务时,服务显示已停止。当我第二次 运行 脚本时,它停止服务,进入循环,尝试重新启动服务,循环 3 次,然后捕捉到旨在触发和电子邮件警报的失败条件。它一直在失败条件下循环,几十次,直到我强制退出。
我整晚都在为这个问题挠头,我想不出我哪里错了。我将 post 下面的脚本:
$VerbosePreference = "continue"
$remoteServer = 'My-RemoteServer01'
$serviceName = 'MSSQLServerOLAPService'
$service = Get-Service -name $ServiceName
$maxRetries = 2
$retryCount = 0
$restartComplete = $false
stop-service -name $serviceName
write-verbose 'Service Stopped - Sleep 15s'
start-sleep -s 15
write-verbose "Attempt to restart service '$retryCount' "
while ($restartComplete -eq $false){
if ($service.status -eq 'Running')
{
$restartComplete = $true
write-verbose "restart complete"
}
else {
if ($retryCount -ge $maxRetries)
{
write-verbose "Service Restart Failed - Begin Alert"
$smtpServer = ('smtp.mymailserver.com', 00)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$dateString = get-date
$msg.From = 'no-reply@mymailserver.com'
$msg.To.Add('L3LYZA@mymailserver.com')
$msg.subject = 'URGENT ALERT - Service ' + $service + 'is' + $service.status + 'on' + $remoteServer + '.'
$msg.body = ([string]$dateString) + 'Service' + $service + 'is' + $service.status + 'on' + $remoteServer + '.'
$smtp.send($msg)
write-verbose "Alert Sent - Complete"
}
else {
if ($service.status -ne 'Running')
{
start-service -name $serviceName
write-verbose 'Service Restarting - Sleep 45s'
start-sleep -s 45
$retryCount++
}
}
}
}
编辑:解决方案最终改变了我检查服务状态的方式。我还在失败条件中添加了一个 throw。
$VerbosePreference = "continue"
$remoteServer = 'My-RemoteServer'
$serviceName = 'MSSQLServerOLAPService'
$service = Get-Service -name $ServiceName
$maxRetries = 2
$retryCount = 0
$restartComplete = $false
stop-service -name $serviceName
write-verbose 'Service Stopped - Sleep 15s'
start-sleep -s 15
write-verbose "Attempt to restart service '$break' "
while ($restartComplete -eq $false){
if ((Get-Service $serviceName).Status -eq 'Running')
{
$restartComplete = $true
write-verbose "restart complete"
}
else {
if ($retryCount -ge $maxRetries)
{
write-verbose "Service Restart Failed - Begin Alert"
$smtpServer = ('smtp.mymailserver.com', 00)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$dateString = get-date
$msg.From = 'noreply@mymailserver.com'
$msg.To.Add('L3LYZA@mymailserver.com')
$msg.subject = 'URGENT ALERT - Service ' + $service + 'is' + $service.status + 'on' + $remoteServer + '.'
$msg.body = ([string]$dateString) + 'Service' + $service + 'is' + $service.status + 'on' + $remoteServer + '.'
$smtp.send($msg)
write-verbose "Alert Sent - Complete"
Throw "service restart failed exit condition met"
}
else {
if ((Get-Service $serviceName).Status -ne 'Running')
{
start-service -name $serviceName
write-verbose 'Service Restarting - Sleep 45s'
start-sleep -s 45
$retryCount++
}
}
}
}
不确定这是否是错误,但发现了一些似乎是错误的东西。
您在第 3 行检查服务状态,但在第 9 行停止服务。然后在第 16 行检查状态是否为 运行ning。您需要再次 运行 Get-Service 以获取服务的更新状态。
您可以通过以下方式完成此操作:
(Get-Service $serviceName).Status
我的建议如下:
$VerbosePreference = "continue"
$remoteServer = 'My-RemoteServer01'
$serviceName = 'MSSQLServerOLAPService'
$service = Get-Service -name $ServiceName
$maxRetries = 2
$retryCount = 0
$restartComplete = $false
stop-service -name $serviceName
write-verbose 'Service Stopped - Sleep 15s'
start-sleep -s 15
write-verbose "Attempt to restart service '$retryCount' "
start-service -name $serviceName
while ($restartComplete -eq $false) {
if ((Get-Service $serviceName).Status -eq 'Running') {
$restartComplete = $true
write-verbose "restart complete"
}
else {
if ($retryCount -ge $maxRetries) {
write-verbose "Service Restart Failed - Begin Alert"
$smtpServer = "smtp.mymailserver.com"
$dateString = get-date
$mailFrom = 'no-reply@mymailserver.com'
$mailTo('L3LYZA@mymailserver.com')
$mailSubject = 'URGENT ALERT - Service ' + $service + 'is' + $service.status + 'on' + $remoteServer + '.'
$mailBody = ([string]$dateString) + 'Service' + $service + 'is' + $service.status + 'on' + $remoteServer + '.'
Send-MailMessage -SmtpServer $smtpserver -From $mailFrom -To $mailTo -Subject $mailSubject -Body $mailBody
write-verbose "Alert Sent - Complete"
}
else {
if ($service.status -ne 'Running') {
start-service -name $serviceName
write-verbose 'Service Restarting - Sleep 45s'
start-sleep -s 45
# Get an updated status from the service:
$service = Get-Service -name $ServiceName
$retryCount++
}
}
}
}
请记住,我将邮件更改为本机 Powershell Send-MailMessage。您选择“Net.Mail.MailMessage”可能是有原因的,所以如果是,请将其改回。