【问题标题】:PowerShell: Restart Service By Executable NamePowerShell:按可执行名称重新启动服务
【发布时间】:2011-08-18 01:33:28
【问题描述】:

全部

我实现了我的第一个 PowerShell 脚本,它进行了一些设置、设置注册表项,然后最终需要重新启动服务。问题是我只有可执行文件的名称,但没有服务名称。 Restart-Service 只能与服务名称一起使用。谷歌搜索(以及 Binging)并没有给我带来太多结果。

我想知道是否有办法通过可执行名称重新启动服务?

我知道我可以通过可执行文件名获取进程,但是仅仅杀死进程并重新启动它不是一个好的选择,因为服务启动/停止函数没有被调用并且它可能无法正常工作。

谢谢。

【问题讨论】:

    标签: windows scripting powershell windows-services


    【解决方案1】:

    您可以尝试使用 wmi 并执行以下操作:

    (gwmi win32_service | ?{$_.pathname -match "\\executable.exe "}) | Restart-Service
    

    【讨论】:

    • 您无法通过管道将 WMI 服务实例传送到 Restart-Service cmdlet。对象不是同一类型。
    • @Shay:试试管道……做得很好!
    • 我在@Shay 的解决方案中关于匹配的cmets 也适用于这个解决方案。这将匹配可执行文件:“MyExecutable.exe”、“AnotherExecutable.exe”、“executable.exec.exe”等。"\\executable.exe\b" 会更好,但“\executable.exe.new.exe”也会匹配(我知道,不太可能)。
    • @Rynant - OP 可能知道可执行文件及其路径甚至参数等。OP 可以指定整体。而且您似乎不知道svchost.exe 是如何工作的。服务不使用它作为可执行路径。
    • 我知道svchost.exe 是什么,并且您不会通过匹配svchost.exe 进程来重新启动服务。有些服务将其用作可执行路径。如果我运行:gwmi win32_service -filter "PathName like '%svchost.exe%'",我将获得 119 项服务。我的意思是 $chost.exe% 将匹配 svchost.exe
    【解决方案2】:
    Get-WmiObject -Class Win32_Service -Filter "PathName LIKE '%PartOfTheName%'" -ComputerName PC1 | Foreach-Object{
        $_.StopService()
        $_.StartService()   
    }
    

    【讨论】:

    • 如果有多个服务具有相同的 .exe。我有多个使用 sqlservr.exe 的服务。另外,如果有一个服务使用“AnotherExename.exe”(“%”通配符将导致它匹配);不太可能,但可能。
    • 你可以扩展代码来处理多个对象,我会在一分钟内更新它。如果要匹配服务名称的部分内容,请将字符串括在 % 中。
    • 我并不是说比赛应该不那么严格,而是更严格。如果有一个名为“chost.exe”的服务怎么办? '%chost.exe' 也将匹配 'svchost.exe'。 PathName 参数还包括参数(例如'msiexec.exe /V')。 '%\chost.exe%' 会更好,但不是 100% 万无一失,因为它会匹配 'chost.exec.exe' 我知道我很痛苦,但我只是想处理所有情况:-P
    • @Ryhant,我可以使用以下命令提取图像名称:Get-WmiObject -Class Win32_Service | Foreach-Object { Split-Path -Leaf ($_.PathName -split('\s\-|/'))[0].Trim('"')} 。它也适合你,我们可以写一个更好的解决方案。
    【解决方案3】:

    您可以使用 WMI 做到这一点:

    $process = Get-Process sqlservr| select -ExpandProperty Id
    
    Get-WmiObject win32_Service| 
        where {$process -contains $_.ProcessId}|
        foreach {Restart-Service $_.Name}
    

    编辑:更改脚本以重新启动服务,而不仅仅是停止它。

    【讨论】:

      【解决方案4】:
      #set by logic to determine if the service will restart or not
       $global:ServerWillRestart=$true 
      
      #can be found using the name column of Get-services cmdlet
       $serviceName="Set name of the service" 
      if($global:ServerWillRestart){
           $service =Get-Service | where{ $_.Name -eq $serviceName}
      do{
          Write-output "The service $ServiceName will is being stopped"
          Stop-Service $service
          Start-Sleep -s 2
      }
      while($service.WaitForStatus("Stopped"))
      
      do{
          Write-Output "The service $ServiceName will is being started"
          Start-Service $service
          Start-Sleep -s 2
      }
      while($service.WaitForStatus("Running"))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-25
        • 1970-01-01
        • 1970-01-01
        • 2011-04-21
        • 1970-01-01
        • 2021-08-16
        • 1970-01-01
        相关资源
        最近更新 更多