【问题标题】:How to force stops one or more services that is in a state of 'stop pending'如何强制停止处于“停止挂起”状态的一项或多项服务
【发布时间】:2016-09-19 02:14:09
【问题描述】:

我想停止一个 Windows 服务,但它挂起或卡在Stopping 状态。我们正在使用混合操作系统,例如 Windows 2008/2012R2。

$ServerList = 'C:\Powershell\SCXAgentDSC\list.txt'  
$SCXAgents = Get-Content -Path $ServerList  

foreach ($scxagent in $SCXAgents) {
  $Hostname = $scxagent
  Write-Host $Hostname
  #Ping host
  $IP = (Test-Connection $hostname -Count 1 -ErrorAction SilentlyContinue |
        Select-Object -ExpandProperty ProtocolAddress)
  if ($IP -eq $null) {
    continue
  }
  #Get state of service 
  $servicestate = Get-Service -ComputerName $Hostname service_name -ErrorAction SilentlyContinue
  #If service is stopped or does not exist, continue otherwise set to stopped and disabled
  if ($servicestate.status -eq 'Stopped' -or $servicestate.status -eq $null) {
    continue
  } else {
    (Get-Service -ComputerName $Hostname service_name).Stop()
    Set-Service -ComputerName $Hostname -Name service_name -StartupType Disabled
    Write-Host "stopped services" -BackgroundColor yellow
    $RPMLines = Get-Service -ComputerName $Hostname service_name

    if ($RPMLines.status -match "Stopped") {
      $ServiceStatus = "STOPPED"
    } else {
      $ServiceStatus = "RUNNING"
    }
    # Port testing (22 and 1270)
    try {
      if ((New-Object System.Net.Sockets.TcpClient("$scxagent", "1270")).Connected -eq $true) {
        $AgentPortStatus = "OK"
      } else {
        $AgentPortStatus = "NOT OK"
      }
    } catch {
      $AgentPortStatus = "NOT OK"
    }
    try {
      if ((New-Object System.Net.Sockets.TcpClient("$scxagent", "22")).Connected) {
        $sshstatus = "OK"
      } else {
        $sshstatus = "NOT OK"
      }
    } catch {
      $sshstatus = "NOT OK"
    }

    Write-Output "$scxagent | SSH : $sshstatus | AgentPort : $AgentPortStatus | AgentServStatus : $ServiceStatus"
  }
}

另外,在我的代码上方,我希望将输出格式化为一行,对吗?例如:

scxagent sshstatus AgentPortStatus AgentServStatus
Server1 OK OK 已停止
Server2 不正常 不正常 正在运行
等等

最后更新:

if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator")) {
  $arguments = "& '" + $myinvocation.mycommand.definition + "'"
  Start-Process powershell -Verb runAs -ArgumentList $arguments
  break
}

$ServerList = 'C:\Powershell\SCXAgentDSC\list.txt'  
$SCXAgents = Get-Content -Path $ServerList  

foreach ($scxagent in $SCXAgents) {
  $Hostname = $scxagent
  Write-Host $Hostname
  #Ping host
  $IP = (Test-Connection $hostname -Count 1 -ErrorAction SilentlyContinue |
        Select-Object -ExpandProperty ProtocolAddress)
  if ($IP -eq $null) {
    continue
  }
  #Get state of service 
  $servicestate = Get-Service -ComputerName $Hostname service_name -ErrorAction SilentlyContinue
  #If service is stopped or does not exist, continue otherwise set to stopped and disabled
  if ($servicestate.Status -eq 'Stopped' -or $servicestate.Status -eq $null) {
    continue
  } else {
    $pid = Get-WmiObject -Computer $hostname -Class Win32_Service -Filter "Name='service_name'" |
           Select-Object -Expand ProcessID

    (Get-Process -Computer $hostname -PID $pid).Kill()

    (Get-Service -ComputerName $Hostname service_name).Stop()
    Set-Service -ComputerName $Hostname -Name service_name -StartupType Disabled
    Write-Host "stopped services" -BackgroundColor yellow

    $RPMLines = Get-Service -ComputerName $Hostname service_name

    if ($RPMLines.Status -match "Stopped") {
      $ServiceStatus = "stop"
    } else {
      $ServiceStatus = "start"
    }
    # Port testing (22 and 1270)
    try {
      if ((New-Object System.Net.Sockets.TcpClient("$scxagent", "1270")).Connected -eq $true ) {
        $AgentPortStatus = "OK"
      } else {
        $AgentPortStatus = "NOT OK"
      }
    } catch {
      $AgentPortStatus = "NOT OK"
    }
    try {
      if ((New-Object System.Net.Sockets.TcpClient("$scxagent", "22")).Connected) {
        $sshstatus = "OK"
      } else {
        $sshstatus = "NOT OK"
      }
    } catch {
      $sshstatus = "NOT OK"
    }

    Write-Output "$scxagent | SSH : $sshstatus | AgentPort : $AgentPortStatus | AgentServStatus : $ServiceStatus"

    Read-Host -Prompt "Press Enter to continue"
  }
}

错误信息:

错误:无法覆盖变量 PID,因为它是只读的或常量。
getservice.ps1 (32): 错误: At Line: 32 char: 3
错误:+ $pid = Get-WmiObject -Computer $hostname -Class Win32_Service -Filter "Name='A ...
错误:+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
错误:+ CategoryInfo:WriteError:(PID:String)[],SessionStateUnauthorizedAccessException
错误:+FullyQualifiedErrorId:VariableNotWritable

【问题讨论】:

  • 这通常发生在与服务相关的进程“卡住”时。您需要找到该进程并使用 stop-process 将其终止,然后再次尝试停止该服务。

标签: windows powershell service


【解决方案1】:

如果服务在收到停止请求后挂起,那么“强制停止”的唯一方法就是终止进程,正如@autsvet 已经提到的那样。使用PID识别进程:

$processID = Get-WmiObject -Computer $hostname -Class Win32_Service -Filter "Name='service_name'" |
             Select-Object -Expand ProcessID

(Get-Process -Computer $hostname -PID $processID).Kill()

请注意,某些服务被配置为不允许篡改其进程。在这种情况下,您可以尝试change the process settings。如果这不起作用(或者由于某种原因您不能这样做),您将不得不重新启动系统。

【讨论】:

  • 只有你才能知道你的代码输出是否是你想要的。也请不要混淆问题。一次将您的问题集中在一个问题上。
  • 我非常了解您,但我只是不想提出与此相关的新问题。好吧,我可以考虑一下吗?
  • 我收到类似“错误:无法覆盖变量 PID,因为它是只读或常量。”的错误。
  • 编辑您的问题并显示您更新的代码以及完整的错误消息。
  • *打自己一巴掌* 对不起,我的错误。 $PIDautomatic variable,因此您需要使用不同的变量名。
猜你喜欢
  • 2014-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多