powershell报告服务器正常运行时间是否超过阈值

时间:2018-01-29 12:01:04

标签: windows powershell server active-directory windows-server-2012-r2

我想创建一个powershell脚本来检查域上的所有服务器(Windows 2012 R2),并在服务器运行时间超过您在脚本中设置的阈值时发送电子邮件报告(这种情况是30天)。但我有一个问题,看起来函数不适用于我的ForEach循环。

到目前为止我的代码:

# Variables for sending the report
$sender = "serviceaccount@domain.com"
$receiver = "administrator@domain.no"

# Find all the servers in the domain that need to be checked
Get-ADComputer -filter * -properties operatingsystem | where {$_.operatingsystem -match "server"} | select name | export-csv c:\script\serverlist.csv -NotypeInformation

$computer = import-csv .\serverlist.csv

# Set the Threshold Limit and Deadline
$Threshold = -30
$Deadline = (Get-Date).AddDays($Threshold)

# Function that checks the uptime
function Get-Uptime {
   $os = Get-WmiObject win32_operatingsystem
   $uptime = (Get-Date) - ($os.ConvertToDateTime($os.lastbootuptime))
   $display = "Uptime: " + $Uptime.Days + " days" 
   Write-Output $display
}

# Then run a check on all the servers to see if the uptime is longer than the threshold
ForEach ($computer in $computer) 
    {
    If ($uptime -ge $Deadline) 
      {
      Send-MailMessage -From $sender -To $receiver -Subject "Server $computer need to be rebooted" -Body "Server has been up for more than $Threshold days" -Priority High -dno onSuccess, onFailure -SmtpServer "mailserver.domain.com"
      }
    }

# End of script

2 个答案:

答案 0 :(得分:2)

您忘记在循环中执行函数Get-Uptime,您还必须在计算机上远程运行命令。

# Variables for sending the report
$sender = "serviceaccount@domain.com"
$receiver = "administrator@domain.no"

$computers = Get-ADComputer -filter * -properties operatingsystem | where {$_.operatingsystem -match "server"} | select name

# Set the Threshold Limit and Deadline
$Threshold = -30
$Deadline = (Get-Date).AddDays($Threshold)

$Remote_Credentials = Get-Credentials
#Run a check on all the servers to see if the uptime is longer than the threshold
    ForEach ($computer in $computers) 
    {
        #Remotly invoke the Commands to check uptime
        $uptime = (Get-Date) - ((Get-WmiObject win32_operatingsystem).ConvertToDateTime((Get-WmiObject win32_operatingsystem -ComputerName $computer -Credential $Remote_Credentials).lastbootuptime))

        If ($uptime -ge $Deadline) 
        {
          Send-MailMessage -From $sender -To $receiver -Subject "Server $computer need to be rebooted" -Body "Server has been up for more than $Threshold days" -Priority High -dno onSuccess, onFailure -SmtpServer "mailserver.domain.com"a
        }
    }

如果您不想为每台通过限制的计算机发送电子邮件,而只是为计算机只写一封电子邮件,则可以更改最后一部分:

If ($uptime -ge $Deadline) 
            {
              $subject += "Server $computer need to be rebooted" -Body "Server has been up for more than $Threshold days"
            }

在Foreach循环后发送邮件:

Send-MailMessage -From $sender -To $receiver -Subject $Subject -Priority High -dno onSuccess, onFailure -SmtpServer "mailserver.domain.com"
#Dont forget to reset $subject afterwards: $subject = $0

答案 1 :(得分:1)

您的ForEach循环结构不正确;你试图用作"索引变量" ($computer)包含您正在迭代的集合的相同变量($computer)。将$computer = Import-CSV ...更改为$computers = ...,并将ForEach更改为ForEach ($Computer in $Computers) ...

此外,正如其他人所指出的那样(我最初忽略了这一点),你永远不会调用你的Get-Uptime功能。由于Get-WMIObject需要-ComputerName参数,我会重写它:

function Get-Uptime {
    param (
        [string]$ComputerName = "localhost"
    )
    $os = Get-WmiObject -ComputerName $ComputerName -Class Win32_OperatingSystem
    $uptime = (Get-Date) - ($os.ConvertToDateTime($os.lastbootuptime))
    return $uptime
}

并在ForEach循环中调用它:

ForEach ($Computer in $Computers) {
    if ((Get-Uptime -ComputerName $Computer) -ge $Deadline) {
        Send-MailMessage ...
    } #ENDIF
} #END-ForEach