【发布时间】:2017-11-30 20:30:48
【问题描述】:
当我运行我的脚本时,它会重新启动我的 csv 文件中列出的服务器,并且还会监控我的机器何时在线、何时离线以及何时恢复的进度。发生这种情况时,它们会附加到日志文件中,因此我可以看到进度,因为脚本在脚本块中运行。由于某些奇怪的原因,当它尝试重新启动多个服务器时,它产生的日志文件总是不同的。有时一切都按原样显示,有时会列出所有在线的服务器,但当列出哪些服务器在重新启动期间离线时,它可能只显示 15 台服务器中的 10 台。但是当我手动检查我的所有服务器时,它们都会在重新启动期间重新上线,但日志文件没有记录它。
我正在重新启动的服务器范围从 2008r2 服务器到 2012。较旧的服务器需要更长的时间才能重新启动,而不是较新的服务器。我在想的事情是,由于这一切都是在 Parallel 中发生的,因此日志文件缺少记录这些服务器的进度,因为其中一些服务器在某些混淆脚本的同时离线。如果是这种情况,我将如何解决这个问题?
#Credentials used to invoke commands on servers
$Creds = Get-Credential
Function Write-and-Log ($Message)
{
Write-Host (Get-Date -Format ("[yyyy-MM-dd HH:mm:ss] ")) "$message" -ForegroundColor Yellow
(Get-Date -Format ("[yyyy-MM-dd HH:mm:ss] ")) + "$message" | out-file $logfilename -Append
}
#variables
$ScriptRoot = Split-Path $MyInvocation.MyCommand.Path
$StartTime = Get-Date -Format "yyyyMMddHHmmss_"
$csvfile = $ScriptRoot + "\" + "servers.csv"
$logdir = $ScriptRoot + "\serverLogs\"
$logfilename = $logdir + $StartTime + "Reboot.log"
#Import servers from vms2deploy.csv file
$Servers = Import-Csv -Path $csvfile
#Script block for rebooting servers
$deploy_Reboot_scriptBlock = {
(gwmi -Class Win32_OperatingSystem -ComputerName "$env:computername").Win32Shutdown(6)
}
#End of Scriptblock
#script block for monitoring servers
$monitor = {
Param ( $Computer, $logfile, $logfile1 , $logfile2,
[Parameter(ValueFromPipeline=$False,Mandatory=$False)]
[int]$timeout=5
)
$MAX_PINGTIME = $timeout * 60
$max_iterations = $MAX_PINGTIME/5
function ping-host {
param($pc)
$status = Get-WmiObject -Class Win32_PingStatus -Filter "Address='$pc'"
if( $status.statuscode -eq 0) {
return 1
} else {
return 0
}
}
if(ping-host -pc $computer) {
(Get-Date -Format ("[yyyy-MM-dd HH:mm:ss] ")) + "$Computer is online; Waiting for it to go offline" | out-file $logfile -Append
$status = "online"
for ($i=0; $i -le $max_iterations; $i++) {
if (!(ping-host -pc $computer )) {
break
}
Start-Sleep -Seconds 5
if($i -eq $max_iterations) {
(Get-Date -Format ("[yyyy-MM-dd HH:mm:ss] ")) + "$Computer never went down in last $timeout minutes" | out-file $logfile -Append
(Get-Date -Format ("[yyyy-MM-dd HH:mm:ss] ")) + "Check that reboot is initiated properly" | out-file $logfile -Append
show-notification -type "error" -text "$computer is still ONLINE; Check that reboot is initiated properly" -title "Computer is not rebooting"
exit
}
}
(Get-Date -Format ("[yyyy-MM-dd HH:mm:ss] ")) + "$Computer is offline now; monitoring for online status" | out-file $logfile1 -Append
} else {
(Get-Date -Format ("[yyyy-MM-dd HH:mm:ss] ")) + "$Computer is offline; Monitoring for online status" | out-file $logfile -Append
$status = "offline"
}
for ($i=0; $i -le $max_iterations; $i++) {
if ((ping-host -pc $computer )) {
break
}
Start-Sleep -Seconds 5
if($i -eq $max_iterations) {
(Get-Date -Format ("[yyyy-MM-dd HH:mm:ss] ")) + "Your computer never came back online in last $MAX_PINGTIME seconds" | out-file $logfile -Append
(Get-Date -Format ("[yyyy-MM-dd HH:mm:ss] ")) + "Check that nothing is preventing starup" | out-file $logfile -Append
show-notification -type "error" -text "$Computer is NOT coming online; Something is preventing its startup" -title "Computer failed to start"
exit
}
}
(Get-Date -Format ("[yyyy-MM-dd HH:mm:ss] ")) + "$Computer is Online Now; Task done; exiting" | out-file $logfile2 -Append
show-notification -type "info" -text "$Computer is online" -title "$Computer successfully restarted"
}
#scriptblock end
Foreach ($server in $Servers){
$Session = $Server.name
Write-and-Log ":Info: Restart command issued to $Session"
New-PSSession -ComputerName $Session -Credential $Creds
Invoke-Command -ComputerName $Session -ScriptBlock $deploy_Reboot_scriptblock -AsJob -Credential $Creds
$Computer = $Session
$logfile = $logdir + $StartTime + "monitor.log"
$logfile1 = $logdir + $StartTime + "monitor1.log"
$logfile2 = $logdir + $StartTime + "monitor2.log"
Write-And-Log "Monitoring reboot process for $computer"
$jobs_tab += @{ $server = start-job -name $server -scriptblock $monitor -argumentlist $Computer, $logfile, $logfile1, $logfile2 }
}
#track the job progress
do{
#do not repeat too often
Start-Sleep -Seconds 10
Write-And-Log "Checking to see status of reboot jobs"
$running_jobs = 0
foreach ($server in $Servers) {
if ($($jobs_tab.Get_Item($server)).state -eq "running") {
$running_jobs++
}
}
#until we are out of active jobs
} until ($running_jobs -eq 0)
日志文件结果 监控日志
[2017-11-30 12:18:17] server1 is online; Waiting for it to go offline
[2017-11-30 12:18:17] server2 is online; Waiting for it to go offline
[2017-11-30 12:18:18] server3 is online; Waiting for it to go offline
[2017-11-30 12:18:19] server4 is online; Waiting for it to go offline
[2017-11-30 12:18:19] server5 is online; Waiting for it to go offline
[2017-11-30 12:18:20] server6 is online; Waiting for it to go offline
[2017-11-30 12:18:20] server7 is online; Waiting for it to go offline
[2017-11-30 12:18:21] server8 is online; Waiting for it to go offline
[2017-11-30 12:18:21] server9 is online; Waiting for it to go offline
[2017-11-30 12:18:22] server10 is online; Waiting for it to go offline
[2017-11-30 12:18:25] server11 is online; Waiting for it to go offline
[2017-11-30 12:18:27] server12 is online; Waiting for it to go offline
[2017-11-30 12:18:32] server13 is online; Waiting for it to go offline
[2017-11-30 12:18:33] server14 is online; Waiting for it to go offline
monitor1 日志
[2017-11-30 12:18:32] server1 is offline now; monitoring for online status
[2017-11-30 12:18:35] server2 is offline now; monitoring for online status
[2017-11-30 12:18:36] server3 is offline now; monitoring for online status
[2017-11-30 12:18:36] server4 is offline now; monitoring for online status
[2017-11-30 12:18:37] server5 is offline now; monitoring for online status
[2017-11-30 12:18:38] server6 is offline now; monitoring for online status
[2017-11-30 12:18:39] server7 is offline now; monitoring for online status
[2017-11-30 12:18:39] server8 is offline now; monitoring for online status
[2017-11-30 12:18:41] server9 is offline now; monitoring for online status
[2017-11-30 12:18:44] server10 is offline now; monitoring for online status
[2017-11-30 12:18:45] server11 is offline now; monitoring for online status
[2017-11-30 12:18:46] server12 is offline now; monitoring for online status
monitor2 日志
[2017-11-30 12:18:41] server1 is Online Now; Task done; exiting
[2017-11-30 12:18:44] server2 is Online Now; Task done; exiting
[2017-11-30 12:18:45] server3 is Online Now; Task done; exiting
[2017-11-30 12:18:45] server3 is Online Now; Task done; exiting
[2017-11-30 12:18:46] server4 is Online Now; Task done; exiting
[2017-11-30 12:18:47] server5 is Online Now; Task done; exiting
[2017-11-30 12:18:48] server6 is Online Now; Task done; exiting
[2017-11-30 12:18:48] server7 is Online Now; Task done; exiting
[2017-11-30 12:18:50] server8 is Online Now; Task done; exiting
[2017-11-30 12:18:53] server9 is Online Now; Task done; exiting
[2017-11-30 12:18:54] server10 is Online Now; Task done; exiting
[2017-11-30 12:18:55] server11 is Online Now; Task done; exiting
正如您在第一个监控日志之后看到的那样,它们不匹配。每个日志应该有相同数量的服务器。它们的顺序可能不同,但它们都应该在那里。
【问题讨论】:
-
您可能会因为多个作业尝试同时写入同一个日志而遇到共享冲突。
-
@Shawn Esterman 进行了这些更改,但得到了相同的结果。唯一具有相同时间戳的日志是重新启动日志。该日志仅显示正在为服务器运行的脚本,并告诉我作业必须完成多长时间。它对我的脚本块中的日志没有任何更改
-
@TheMadTechnician 我也有类似的想法所以我尝试拆分日志文件。之前三个监视器日志文件只是一个,拆分它们后我希望不会再有任何问题,但它们仍然存在。
标签: multithreading powershell logging monitoring restart