【问题标题】:Powershell script to check if service is started, if not then start itPowershell脚本检查服务是否启动,如果没有启动它
【发布时间】:2016-05-06 00:48:44
【问题描述】:

我已经构建了一个小型 powershell 脚本来检查服务是否已启动。如果未启动,请尝试启动它,然后等待一分钟并再次检查。不断重复这个过程,直到服务启动成功。我发现循环的行为不像我预期的那样,我似乎必须在循环中重新分配服务变量才能获得更新的状态。这是我的代码:

$ServiceName = 'Serenade'
$arrService = Get-Service -Name $ServiceName

if ($arrService.Status -ne 'Running'){
$ServiceStarted = $false}
Else{$ServiceStarted = $true}

while ($ServiceStarted -ne $true){
Start-Service $ServiceName
write-host $arrService.status
write-host 'Service started'
Start-Sleep -seconds 60
$arrService = Get-Service -Name $ServiceName #Why is this line needed?
if ($arrService.Status -eq 'Running'){
$ServiceStarted = $true}
}

如果我在没有倒数第三行(带有注释的行)的情况下运行代码,我会得到以下输出。我可以签入 Windows 服务管理器,并且该服务在第一个循环之后显然已启动。为什么需要倒数第三行?

鉴于这种行为,是否有更好的方法来编写此代码?

谢谢

【问题讨论】:

  • 因为存储了服务的可变状态,为了让它工作,需要再次获取服务的状态。
  • 我不是在检查倒数第二行的状态吗?带有if($arrService.Status...的那个?
  • 您是,但您正在从已设置的变量中检查它,如果没有该行来更新该变量,则不会再次调用该变量。
  • 对不起,我是个ps新手。我打算查看服务的状态,如果它是“正在运行”,请将 $ServiceStarted 变量更改为 true。完成后,将重新评估初始循环条件,并再次检查 $ServiceStarted 变量,所以它不会找到更新后的值 true 吗?
  • 你想要完成什么?检查服务是否正在运行,如果它没有运行则启动。在开始之前停止重新评估?

标签: powershell


【解决方案1】:
$ServiceName = 'Serenade'
$arrService = Get-Service -Name $ServiceName

while ($arrService.Status -ne 'Running')
{

    Start-Service $ServiceName
    write-host $arrService.status
    write-host 'Service starting'
    Start-Sleep -seconds 60
    $arrService.Refresh()
    if ($arrService.Status -eq 'Running')
    {
        Write-Host 'Service is now Running'
    }

}

我们能否对多个服务使用相同的脚本,并在服务出现故障时发送一封电子邮件。

【讨论】:

    【解决方案2】:

    尽量让事情顺利进行——我在这里建议稍微修改一下 GuyWhoLikesPowershell 的建议。

    我用一段时间替换了 if 和 until - 我检查了“Stopped”,因为如果状态是“starting”或“Stopping”,我不想开始。

    $Service = 'ServiceName'
    while ((Get-Service $Service).Status -eq 'Stopped') 
    {
        Start-Service $Service -ErrorAction SilentlyContinue
        Start-Sleep 10
    } 
    Return "$($Service) has STARTED"
    

    【讨论】:

      【解决方案3】:

      下面是一个紧凑的脚本,它将检查是否“正在运行”并尝试启动服务,直到服务返回为运行状态。

      $Service = 'ServiceName'
      If ((Get-Service $Service).Status -ne 'Running') {
         do {
             Start-Service $Service -ErrorAction SilentlyContinue
             Start-Sleep 10
         } until ((Get-Service $Service).Status -eq 'Running')
      } Return "$($Service) has STARTED"
      

      【讨论】:

        【解决方案4】:

        一个可能更简单的解决方案:

        get-service "servicename*" | Where {$_.Status -eq 'Stopped'} | start-service
        

        【讨论】:

          【解决方案5】:

          结合 Alaa Akoum 和 Nick Eagle 的解决方案,我可以循环访问一系列 Windows 服务,并在它们正在运行时停止它们。

          # stop the following Windows services in the specified order:
          [Array] $Services = 'Service1','Service2','Service3','Service4','Service5';
          
          # loop through each service, if its running, stop it
          foreach($ServiceName in $Services)
          {
              $arrService = Get-Service -Name $ServiceName
              write-host $ServiceName
              while ($arrService.Status -eq 'Running')
              {
                  Stop-Service $ServiceName
                  write-host $arrService.status
                  write-host 'Service stopping'
                  Start-Sleep -seconds 60
                  $arrService.Refresh()
                  if ($arrService.Status -eq 'Stopped')
                      {
                        Write-Host 'Service is now Stopped'
                      }
               }
           }
          

          同样可以启动一系列服务,如果它们没有运行:

          # start the following Windows services in the specified order:
          [Array] $Services = 'Service1','Service2','Service3','Service4','Service5';
          
          # loop through each service, if its not running, start it
          foreach($ServiceName in $Services)
          {
              $arrService = Get-Service -Name $ServiceName
              write-host $ServiceName
              while ($arrService.Status -ne 'Running')
              {
                  Start-Service $ServiceName
                  write-host $arrService.status
                  write-host 'Service starting'
                  Start-Sleep -seconds 60
                  $arrService.Refresh()
                  if ($arrService.Status -eq 'Running')
                  {
                    Write-Host 'Service is now Running'
                  }
              }
          }
          

          【讨论】:

            【解决方案6】:

            给定$arrService = Get-Service -Name $ServiceName$arrService.Status 是一个静态 属性,对应于调用时的值。需要时使用$arrService.Refresh() 将属性更新为当前值。

            MSDN ~ ServiceController.Refresh()

            通过将属性重置为其当前值来刷新属性值。

            【讨论】:

            • 谢谢,这正是我不明白的。
            【解决方案7】:

            我认为您的代码可能过于复杂:如果您只是检查服务是否正在运行,如果没有,则运行它然后停止重新评估,以下就足够了:

            Good point on the refresh.

            $ServiceName = 'Serenade'
            $arrService = Get-Service -Name $ServiceName
            
            while ($arrService.Status -ne 'Running')
            {
            
                Start-Service $ServiceName
                write-host $arrService.status
                write-host 'Service starting'
                Start-Sleep -seconds 60
                $arrService.Refresh()
                if ($arrService.Status -eq 'Running')
                {
                    Write-Host 'Service is now Running'
                }
            
            }
            

            【讨论】:

            • 在我的电脑“服务”类成员有这个值状态:运行状态:OK
            • 做了一个稍微改动的版本的要点,使设置应该启动的多个服务更容易:gist.github.com/JohnyWS/6d0df355bfa63b05e5405c1c3939c69b
            • 我们是否 100% 确定这可行 - arrService 如何更新?下面的评论暗示了它也是一个静态属性的想法。
            【解决方案8】:
            [Array] $servers = "Server1","server2";
            $service='YOUR SERVICE'
            
            foreach($server in $servers)
            
            {
                $srvc = Get-WmiObject -query "SELECT * FROM win32_service  WHERE   name LIKE '$service' " -computername $server  ;
                $res=Write-Output $srvc | Format-Table -AutoSize $server, $fmtMode, $fmtState, $fmtStatus ;  
               $srvc.startservice() 
               $res
            }
            

            【讨论】:

            • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
            • 如何允许检查多个服务?
            • 嵌套第二个 for 循环并拥有第二个服务数组
            猜你喜欢
            • 2018-05-11
            • 1970-01-01
            • 1970-01-01
            • 2023-03-20
            • 1970-01-01
            • 2019-11-16
            • 1970-01-01
            • 2012-09-26
            • 1970-01-01
            相关资源
            最近更新 更多