Reputation: 1904
I want to stop a Windows service and it's hung or stuck with a status of Stopping
. We are using mixed operating systems such as 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"
}
}
Also, Above my code I'd like to have output formatted into the one line, am I correct? e.g.:
scxagent sshstatus AgentPortStatus AgentServStatus Server1 OK OK STOPPED Server2 NOT OK NOT OK RUNNING etc.
Last Update:
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"
}
}
Error Message:
ERROR: Cannot overwrite variable PID because it is read-only or constant. getservice.ps1 (32): ERROR: At Line: 32 char: 3 ERROR: + $pid = Get-WmiObject -Computer $hostname -Class Win32_Service -Filter "Name='A ... ERROR: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ERROR: + CategoryInfo : WriteError: (PID:String) [], SessionStateUnauthorizedAccessException ERROR: + FullyQualifiedErrorId : VariableNotWritable
Upvotes: 1
Views: 3250
Reputation: 200293
If a service hangs after receiving a stop request the only way to "force-stop" it is killing the process, as @autsvet already mentioned. Use the PID to identify the process:
$processID = Get-WmiObject -Computer $hostname -Class Win32_Service -Filter "Name='service_name'" |
Select-Object -Expand ProcessID
(Get-Process -Computer $hostname -PID $processID).Kill()
Note that some services are configured to not allow tampering with their process. In such cases you could try to change the process settings. If that doesn't work (or you can't do it for some reason) you'll have to resort to rebooting the system.
Upvotes: 2