我想停止一个Windows服务,它被挂起或卡住状态为Stopping
。我们使用的是混合操作系统,如Windows 2008/2012R2。
$ServerList = 'C:PowershellSCXAgentDSClist.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服务器1 OK OK已停止服务器2不能正常运行等。之前去年更新: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:PowershellSCXAgentDSClist.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" } }
错误信息:
ERROR:不能覆盖变量PID,因为它是只读或常量。getservice。ps1 (32): ERROR: At Line: 32 char: 3错误:+ $pid = Get-WmiObject -Computer $hostname -Class Win32_Service -Filter "Name='A…错误 : + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ERROR: + CategoryInfo: WriteError: (PID:String) [], SessionStateUnauthorizedAccessException错误:+ fulllyqualifiederrid: variablenotwwrititable
如果一个服务在收到停止请求后挂起,"强制停止"的唯一方法就是杀死进程,正如@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()
注意,一些服务被配置为不允许篡改它们的进程。在这种情况下,您可以尝试更改流程设置。如果这不起作用(或者由于某些原因不能这样做),您将不得不求助于重新启动系统。