更新
我正在编写一个 PowerShell 脚本来检查 Windows 服务并在停止时启动它们,由于我对它不熟悉,因此我在编写脚本方面遇到了困难。我想要做的是:
- 检查系统启动时间,如果系统刚刚启动,少于 10 分钟,则不会发生任何事情。
- 如果启动时间超过 10 分钟,请检查所有自动服务的状态,如果一个或多个服务停止,请尝试启动它们。
- 无论脚本是否可以成功启动服务,都会将包含服务器 IP 和名称、服务名称和结果的日志写回共享文件夹。
我查看了一些文章,发现了一些:
#Get current system boot time in second
Function Get-SystemUpTimeInSec
{
$uptime = Get-WmiObject -Class Win32_OperatingSystem
$uptime.ConvertToDateTime($uptime.LocalDateTime) – $uptime.ConvertToDateTime($uptime.LastBootUpTime)
}
Get-SystemUpTimeInSec | foreach {$_.TotalSeconds}
#Get stopped service
Get-WmiObject -Class Win32_Service -Filter "startmode = 'auto' AND state != 'running' AND exitcode = !0" | foreach {$_.Name}
我想知道如何将它们组合在一起来完成这个脚本?
2016 年 12 月 15 日
我花了几个小时检查这些功能,这是我目前在实验室中测试的脚本,因为我们有日志管理系统,所以我添加了日志写回。
然后我使用任务计划程序每 1 小时运行一次此脚本。以下命令是我用于计划任务的:
powershell.exe -ExecutionPolicy Bypass -Command "& c:\scripts\my-script.ps1"
脚本如下:
#Fire the log writeback, this sample is write back to log file
$timestamp = (get-date).ToString("yyyyMMddHHmmss")
$Logfile = "\\sharedfolder\reports\servicelogs\$(Get-Content env:computername).log"
Function LogWrite
{
Param ([string]$logstring)
Add-content $Logfile -value $logstring -Encoding UTF8
}
#Get current system boot time in second
Function Get-SystemUpTimeInSec
{
$uptime = Get-WmiObject -Class Win32_OperatingSystem
$uptime.ConvertToDateTime($uptime.LocalDateTime) – $uptime.ConvertToDateTime($uptime.LastBootUpTime)
}
$SysUpTimeInSec = Get-SystemUpTimeInSec | ForEach-Object {$_.TotalSeconds}
#Check the unexpected exist service
if ($SysUpTimeInSec -gt "900")
{
$ExistSvc = Get-WmiObject -Class Win32_Service -Filter "startmode = 'auto' AND state != 'running' AND exitcode != 0"
if ($null -eq $ExistSvc)
{
exit
}
elseif ($null -ne $ExistSvc)
{
foreach ($svc in $ExistSvc)
{
Start-Service $svc.Name
Start-Sleep -s 10
$PostExistSvc = Get-Service $svc.Name
if ($PostExistSvc.Status -eq "Running")
{
LogWrite "$((Get-Date).ToString()) $($svc.DisplayName) from $(Get-Content env:computername) was stopped unexpectedly, now has been successfully started."
}
elseif ($PostExistSvc.Status -eq "Stopped")
{
LogWrite "$((Get-Date).ToString()) $($svc.DisplayName) from $(Get-Content env:computername) was stopped unexpectedly, and cannot be started."
}
}
}
}
elseif ($SysUpTimeInSec -lt "900")
{
exit
}
答案1
如果您乐意使用该函数,则需要为 10 分钟组件添加一个 if 语句。不过,这将永远运行。只要您的机器运行时间超过 10 分钟,这将成立。
您可以使用其他类型的循环来每 15 分钟检查一次,而不是不断检查。
您还可以使用所需状态配置(DSC)来设置您希望服务执行的操作。https://msdn.microsoft.com/en-us/powershell/dsc/serviceresource
为了在代码中执行类似您的要求,我将使用该函数并向检查函数添加 600 秒(10 分钟),并放置 600 秒(10 分钟)的启动睡眠时间,以便它不会不断检查。
if(get-systemuptimeinsec -gt 600)
{
Get-WmiObject -Class Win32_Service -Filter "startmode = 'auto' AND state != 'running' AND exitcode = !0" | start-service
start-sleep -seconds 600
}
我还没有检查您的 WMI 过滤器,假设它输出的是您要查找的内容。
希望这可以帮助。
谢谢,蒂姆。