【问题标题】:Powershell Arrays - checking to see if services have stoppedPowershell Arrays - 检查服务是否已停止
【发布时间】:2014-06-23 11:25:41
【问题描述】:

我知道有一种更快的方法可以做到这一点,但我只是不知道如何处理它。我还需要它在 PowerShell V2 中工作,因为我还有需要处理的 Windows 2003 服务器。

基本上这会停止服务,然后检查这些服务是否已停止。我有一个位置可以在脚本的前面定义它们。我正在使用它来将代码部署到服务器,因此根据开发中的代码,我可能需要停止 1 到 4 个服务,并查看是否有一种方法可以定义服务,如果我不必在下面注释掉代码只使用 2 个服务而不是 4 个。

#Turn off Services
    stop-service $Service1 -force
#   stop-service $Service2 -force
#   stop-service $Service3 -force
#   stop-service $Service4 -force

$VerifyServiceStopped1 = Get-Service $Service1 | Where-Object {$_.status -eq "Stopped"} | select -last 1
#   $VerifyServiceStopped2 = Get-Service $Service2 | Where-Object {$_.status -eq "Stopped"} | select -last 1
#   $VerifyServiceStopped3 = Get-Service $Service3 | Where-Object {$_.status -eq "Stopped"} | select -last 1
#   $VerifyServiceStopped4 = Get-Service $Service4 | Where-Object {$_.status -eq "Stopped"} | select -last 1

    if ($VerifyServiceStopped1) {Write-Host $Service1' Stop = Pass (0)'} else {Write-Host $Service1' Stop = Fail (1000)'; Exit '1000'}
#   if ($VerifyServiceStopped2) {Write-Host $Service2' Stop = Pass (0)'} else {Write-Host $Service2' Stop = Fail (1001)'; Exit '1001'}
#   if ($VerifyServiceStopped3) {Write-Host $Service3' Stop = Pass (0)'} else {Write-Host $Service3' Stop = Fail (1002)'; Exit '1002'}
#   if ($VerifyServiceStopped4) {Write-Host $Service4' Stop = Pass (0)'} else {Write-Host $Service4' Stop = Fail (1003)'; Exit '1003'}

有什么建议吗?

谢谢

德怀特

【问题讨论】:

    标签: arrays powershell powershell-2.0


    【解决方案1】:

    大概是这样的吧?

    $services = @(
     'Service1',
     'Service2',
     'Service3',
     'Service4')
    
     Get-service | 
     Where { $Services -Contains $_.Name} |
     Foreach {
      #Stop Service
      #Verify Service
      #Restart Service
      }
    

    【讨论】:

    • 我尝试单独添加一些服务,然后在 Foreach { Get-Service | Stop-Service -WhatIf 将停止所有服务,所以不要认为这是通过 $services 正确传递。
    • 您正在将服务对象传递到 foreach 中,所以我认为您会使用 $_ |停止服务-whatif。 Get-Service 将返回并再次检索整个列表。
    • 就是这样 - 很酷 - 让我开始测试其他部分
    • $service1 = 'wwansvc' $service2 = 'wuauserv' $service3 = $service4 = $services = @( $service1, $service2, $service3, $service4) Get-service | Where { $Services -Contains $_.Name} | Foreach { $_ | stop-service -whatif } 很好,效果很好 - 然后我将开始以相同的格式合并验证行。
    【解决方案2】:

    我不确定你想如何处理这个问题,但由于数组已被标记:

    $services = @("ServiceName1","ServiceName2")
    
    #Turn off Services
    foreach($service in $services) {
        stop-service $Service1 -force
        $VerifyServiceStopped1 = Get-Service $Service1 | Where-Object {$_.status -eq "Stopped"} | select -last 1
        if ($VerifyServiceStopped1) {
            Write-Host $Service1' Stop = Pass (0)'
        } else {
            Write-Host $Service1' Stop = Fail (1000)'
            Exit '1000'
        }    
    }
    

    “所以根据开发中的代码,我可能需要停止 1 到 4 个服务”

    如果您无法定义该决策所涉及的逻辑,您打算如何实现自动化?

    【讨论】:

    • 为了回答这个问题,我们每年推送 400 多个自定义代码片段,因此希望尽可能设置一种简单的自动化。因此,这段代码需要 2 个服务才能停止 - 可以定义这两个,但不必触摸其余代码来注释掉未使用的行。然后我有类似的东西来停止 exe,放置松散的 exe 文件和 dll 之类的东西。遗憾的是,他们没有能力(知识)在这个阶段创建 setup.exe 或 msi。在此之前,我们被告知使用批处理文件来放置文件,但没有任何验证真正起作用。
    • 我明白,我几乎整天都在处理应用程序部署脚本。如果您担心的只是未使用的代码,请将-erroraction 'SilentlyContinue' 添加到您的停止服务 cmdlet。上面的代码只会对你在数组中定义的服务进行操作,那是你要找的吗?
    【解决方案3】:

    只是想提供完整的代码,以防其他人正在寻找类似的东西 - 感谢大家将想法融入其中,这非常有帮助。

    #Define Services 
         $Service1 = 'servicename'
         $Service2 = 
         $Service3 = 
         $Service4 = 
         $Service5 = 
         $Service6 = 
         $Service7 = 
         $Service8 =
         $Service9 = 
    
         $services = @(
         $Service1,
         $service2,
         $service3,
         $service4,
         $Service5,
         $Service6,
         $Service7,
         $Service8,
         $Service9)
    
    #Stop Services
    
         Get-service | 
         Where { $Services -Contains $_.Name} |
         Foreach {
    
         $_ | stop-service
    
         } 
    
         Set-Service |
         Where { $Services -Contains $_.Name} |
         Foreach {
    
         $_ | -startuptype "Disabled"
    
         }
    
    #Verify Services
    
         Get-service | 
         Where { $Services -Contains $_.Name} |
         Foreach {
    
         if ((Get-Service $_.Name).Status -eq "stopped") {Write-Host 'Service Start Pass (0)'} else {Write-Host 'Start Fail (1000)';Exit '1000'}
    
         }
    
    
    #Start Services
    
         Set-Service |
         Where { $Services -Contains $_.Name} |
         Foreach {
    
         $_ | -startuptype "Automatic"
    
         }
    
         Get-service | 
         Where { $Services -Contains $_.Name} |
         Foreach {
    
         $_ | start-service
    
         }
    
    
    #Verify Services
    
         Get-service | 
         Where { $Services -Contains $_.Name} |
         Foreach {
    
         if ((Get-Service $_.Name).Status -eq "running") {Write-Host 'Service Start Pass (0)'} else {Write-Host 'Start Fail (2000)';Exit '2000'}
    
         }
    

    这使我可以让某人列出他们需要停止/开始在那里部署自定义代码的任何服务 - 然后我将移动它以停止可执行文件以替换它们和其他文件以进行验证。遗憾的是,我们收到了一组 exe 和 dll 来热交换某些软件部署,所以这就是需要这样做的原因。我想要一种方法来定义每次部署需要移入和移出的内容,但不想在整个脚本中注释掉我不需要的行(即只有两个服务,因此需要在整个脚本中注释掉其他服务)。

    【讨论】:

      【解决方案4】:

      直接访问状态即可:

      > (Get-Service -Name "Windows Time").Status -eq "Stopped"
      $true
      

      if ((Get-Service -Name "Windows Time").Status -eq "Stopped")
      {
          Write-Host "Yep..."
      }
      

      或者如果你想真正简洁,你可以使用别名gsv

      > (gsv "Windows Time").Status -eq "Stopped"
      $true
      

      你也可以做一个函数:

      Function IsStopped ($name)
      {
          ((Get-Service $name).Status -eq "Stopped")
      }
      
      if (IsStopped "Windows Time")
      {
          Write-Host "foo"
      }
      

      【讨论】:

      • 我有什么工作 - 我的更多问题是我能否以这样的方式创建它以使其运行服务 1、2、3、4,但如果服务 3 和 4 不是,则不会产生错误t 定义。尝试设置一个模板文件来定义一直更改的位,然后让脚本的其余部分(这是它的一部分的一个小示例)完成其余部分,而无需手动注释掉所有会如果不使用,请参阅服务 3 和 4。同样,为了停止正在运行的 exe 和我需要做的其他类型的事情来放入这个自定义代码。
      • 如果您尝试停止不存在的服务,那么这些行中唯一会出错的事情。所以stop-service $Service1 -force -errorAction SilentlyContinue 会处理你的问题
      • 忽略错误几乎永远不是答案。确定你想要做什么,然后去做。如果您需要一个脚本来执行此操作,请找出已安装的一组服务,然后只运行那些 (gsv | where { $_.Name -eq "foo" -or $_.Name -eq "bar" } | %{ $_.Start() })。这样,当凌晨 3 点出现故障时,您将收到一条错误消息进行故障排除。
      • 另外,如果这是用于 DevOps 风格的部署,powershell 正是出于这个原因而具有 DSC (channel9.msdn.com/Events/TechEd/NorthAmerica/2013/…)。你告诉它世界应该如何,它会做出改变,停止和启动服务,并更新所需的文件。如果需要支持 Win7/2008R2 之前的操作系统,请查看 puppet/chef/stackoverflow.com/questions/4910034/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多