서비스가 시작되었는지 확인하는 Powershell 스크립트, 시작되지 않은 경우 시작
서비스가 시작되었는지 확인하기 위해 작은 파워셸 스크립트를 만들었습니다.시작되지 않은 경우 시작을 시도한 후 1분간 기다렸다가 다시 확인합니다.서비스가 성공적으로 시작될 때까지 이 프로세스를 반복합니다.업데이트된 상태를 얻으려면 루프 내에서 서비스 변수를 다시 할당해야 한다는 점에서 루프가 예상한 방식으로 작동하지 않습니다.내 코드는 다음과 같습니다.
$ServiceName = 'Serenade'
$arrService = Get-Service -Name $ServiceName
if ($arrService.Status -ne 'Running'){
$ServiceStarted = $false}
Else{$ServiceStarted = $true}
while ($ServiceStarted -ne $true){
Start-Service $ServiceName
write-host $arrService.status
write-host 'Service started'
Start-Sleep -seconds 60
$arrService = Get-Service -Name $ServiceName #Why is this line needed?
if ($arrService.Status -eq 'Running'){
$ServiceStarted = $true}
}
세 번째 마지막 줄(댓글이 있는 줄) 없이 코드를 실행하면 다음과 같은 출력이 표시됩니다.윈도우 서비스 관리자를 확인할 수 있으며 첫 번째 루프 이후에 서비스가 시작된 것이 분명합니다.왜 마지막 세 번째 줄이 필요합니까?
이러한 동작을 고려할 때, 이 코드를 작성하는 더 나은 방법이 있습니까?
감사해요.
코드가 너무 복잡할 수 있습니다.서비스가 실행 중인지 확인하고 실행되지 않으면 실행하고 재평가를 중지하는 경우 다음과 같이 하면 됩니다.
$ServiceName = 'Serenade'
$arrService = Get-Service -Name $ServiceName
while ($arrService.Status -ne 'Running')
{
Start-Service $ServiceName
write-host $arrService.status
write-host 'Service starting'
Start-Sleep -seconds 60
$arrService.Refresh()
if ($arrService.Status -eq 'Running')
{
Write-Host 'Service is now Running'
}
}
더 간단한 솔루션:
get-service "servicename*" | Where {$_.Status -neq 'Running'} | start-service
해진정$arrService = Get-Service -Name $ServiceName
,$arrService.Status
호출 시 값에 해당하는 정적 속성입니다. 사용$arrService.Refresh()
속성을 현재 값으로 갱신해야 할 경우.
속성을 현재 값으로 재설정하여 속성 값을 새로 고칩니다.
Alaa Akoum과 Nick Eagle의 솔루션을 결합하여 일련의 Windows 서비스를 반복 실행하고 실행 중인 경우 이를 중지할 수 있었습니다.
# stop the following Windows services in the specified order:
[Array] $Services = 'Service1','Service2','Service3','Service4','Service5';
# loop through each service, if its running, stop it
foreach($ServiceName in $Services)
{
$arrService = Get-Service -Name $ServiceName
write-host $ServiceName
while ($arrService.Status -eq 'Running')
{
Stop-Service $ServiceName
write-host $arrService.status
write-host 'Service stopping'
Start-Sleep -seconds 60
$arrService.Refresh()
if ($arrService.Status -eq 'Stopped')
{
Write-Host 'Service is now Stopped'
}
}
}
일련의 서비스가 실행되고 있지 않은 경우에도 동일한 작업을 수행하여 서비스를 시작할 수 있습니다.
# start the following Windows services in the specified order:
[Array] $Services = 'Service1','Service2','Service3','Service4','Service5';
# loop through each service, if its not running, start it
foreach($ServiceName in $Services)
{
$arrService = Get-Service -Name $ServiceName
write-host $ServiceName
while ($arrService.Status -ne 'Running')
{
Start-Service $ServiceName
write-host $arrService.status
write-host 'Service starting'
Start-Sleep -seconds 60
$arrService.Refresh()
if ($arrService.Status -eq 'Running')
{
Write-Host 'Service is now Running'
}
}
}
아래는 "실행 중"인지 확인하고 서비스가 실행 중으로 돌아올 때까지 서비스 시작을 시도하는 컴팩트 스크립트입니다.
$Service = 'ServiceName'
If ((Get-Service $Service).Status -ne 'Running') {
do {
Start-Service $Service -ErrorAction SilentlyContinue
Start-Sleep 10
} until ((Get-Service $Service).Status -eq 'Running')
} Return "$($Service) has STARTED"
$ServiceName = 'Serenade'
$arrService = Get-Service -Name $ServiceName
while ($arrService.Status -ne 'Running')
{
Start-Service $ServiceName
write-host $arrService.status
write-host 'Service starting'
Start-Sleep -seconds 60
$arrService.Refresh()
if ($arrService.Status -eq 'Running')
{
Write-Host 'Service is now Running'
}
}
여러 서비스에 대해 동일한 스크립트를 사용하고 서비스가 중단된 경우 단일 이메일을 보낼 수 있습니까?
[Array] $servers = "Server1","server2";
$service='YOUR SERVICE'
foreach($server in $servers)
{
$srvc = Get-WmiObject -query "SELECT * FROM win32_service WHERE name LIKE '$service' " -computername $server ;
$res=Write-Output $srvc | Format-Table -AutoSize $server, $fmtMode, $fmtState, $fmtStatus ;
$srvc.startservice()
$res
}
맥락
우리는 다양한 변형이 있는 제품을 가지고 있고 한 번에 작업을 합니다.각 버전에는 고유한 서비스가 있습니다.여러 사람이 동일한 버전에서 작업하고 한 사람이 서비스를 중단하는 경우 다른 사람이 원격으로 시스템에 연결하여 수정해야 합니다.
해결책
그래서 여러 인스턴스를 관리할 수 있는 것을 만들었습니다.다행히도 그들 모두는 같은 접두사를 가지고 있고,Get-Service
"스캐너"를 사용할 수 있습니다.
$ServiceName = 'ASService_*'; # Your wildcard goes here.
while ($true)
{
Get-Service $ServiceName | Where {$_.Status -eq 'Stopped'} | Foreach-Object {
Start-Service $_;
# Logging it so that you know it was you.
Get-Date;
Write-Output "``$($_.Name)`` has stopped running.";
}
Start-Sleep -Seconds 1;
}
로그에 관심이 없는 경우 이 작업을 더욱 단순화할 수 있습니다.
$ServiceName = 'ASService_*'; # Your wildcard goes here.
while ($true)
{
Get-Service $ServiceName | Where {$_.Status -eq 'Stopped'} | Foreach-Object { Start-Service $_ };
Start-Sleep -Seconds 1;
}
가능한 한 일을 부드럽게 하려고 노력하는 것 - 저는 파워셸을 좋아하는 남자의 제안을 약간 수정하는 것을 제안합니다.
if와 until을 잠시 1개로 교체했습니다. 상태가 "시작"인지 "중지"인지 여부를 시작하고 싶지 않기 때문에 "중지"를 확인합니다.
$Service = 'ServiceName'
while ((Get-Service $Service).Status -eq 'Stopped')
{
Start-Service $Service -ErrorAction SilentlyContinue
Start-Sleep 10
}
Return "$($Service) has STARTED"
Enterprise FizzBuzz의 정신으로 오류 및 보류 중인 서비스 상태에 대한 광범위한 로깅 및 처리가 포함된 버전을 작성했습니다.대부분의 사용 사례에서 과도하게 설계되었을 가능성이 높습니다.이 버전은 Windows 스케줄링된 작업에서 일정 간격으로 호출되도록 특별히 제작되었습니다.중지하기 전에 각 실행에 대해 지정된 횟수만큼 실행됩니다.
<#
.SYNOPSIS
This script attempts to Start the specified Windows service if the service is stopped and logs its attempts to a file.
It's intended to be deployed as a Windows Scheduled Task that runs every few minutes.
Please ensure the Scheduled Task interval is longer than (($secondsBeforeRetry + 10s) * $maxTries) to avoid concurrent running script instances.
The script first checks the existence of the log file and if not found creates a new one.
It then checks the status of the specified Windows service.
If it's not Stopped (implicitly Running), no actions occur and the script completes without logging anything.
If it's Stopped, the script attempts to Start it and logs success or failure.
If the service is still Stopped, the script will try to Start it again up to $maxTries times.
If the service is in a Starting (StartPending) or Stopping (StopPending) state, the script will recheck its status for
up to three $secondsBeforeRetry intervals to see if it changes.
If the service is still Pending after three checks, the process is likely hung and the script will attempt to force taskkill it.
References:
List of ServiceControllerStatus states: https://learn.microsoft.com/en-us/dotnet/api/system.serviceprocess.servicecontrollerstatus?view=dotnet-plat-ext-6.0
The script does not handle the Paused, PausedPending, or ContinuePending service states.
#>
param (
# Specifies the service name
[Parameter(Mandatory = $true)]
[string]$serviceName,
# Specifies the directory for the log file
[Parameter(Mandatory = $false)]
[string]$logPath = 'C:\Scripts\Logs',
# Specifies the max number of service Start attempts per run
[Parameter(Mandatory = $false)]
[int]$maxTries = 3,
# Specifies the number of seconds to wait before trying again after a failed start attempt or before rechecking a Pending status
[Parameter(Mandatory = $false)]
[int]$secondsBeforeRetry = 30
)
$service = Get-Service $serviceName
$logName = $serviceName + 'AutoRestartLog.txt'
$logFullPath = Join-Path -Path $logPath -ChildPath $logName
if(!(Test-Path -Path $logFullPath)) {
$timestamp = (Get-Date -Format yyyy-MM-dd--HH-mm-ss)
New-Item -Path $logPath -Name $logName -ItemType "file" -Value "## Log file for $serviceName auto-start script ##`n## Created [$timestamp] ##`n" -Force
Start-Sleep -s 1
}
if ($service.Status -eq 'Stopped') {
$tries = 0
while (($tries -lt $maxTries) -and ($service.Status -ne 'Running')) {
if ($tries -eq 0) {
$timestamp = (Get-Date -Format yyyy-MM-dd--HH-mm-ss)
$logSvcStoppedMsg = "[$timestamp] $serviceName service status is $($service.Status), attempting to Start. Will try up to $maxTries times."
Add-Content -Path $logFullPath -Value $logSvcStoppedMsg
}
try {
Start-Service $ServiceName -ErrorAction Stop # Throws exception if command fails, for example if the service is Disabled
$tries += 1
Start-Sleep -s 10
$service.Refresh()
if ($service.Status -eq 'Running') {
$timestamp = (Get-Date -Format yyyy-MM-dd--HH-mm-ss)
$logSvcStartSuccessMsg = "[$timestamp] Attempt #$tries - $serviceName service status is now $($service.Status)"
Add-Content -Path $logFullPath -Value $logSvcStartSuccessMsg
}
}
catch {
$errorMsg = $_
$tries += 1
Start-Sleep -s 10
$service.Refresh()
$timestamp = (Get-Date -Format yyyy-MM-dd--HH-mm-ss)
$logSvcStartExceptionMsg = "[$timestamp] Attempt #$tries - $serviceName service status is $($service.Status) and failed to start with error:`n $errorMsg"
Add-Content -Path $logFullPath -Value $logSvcStartExceptionMsg
if ($tries -ne $maxTries) {
Start-Sleep -s $secondsBeforeRetry
}
}
$service.Refresh()
if (($service.Status -eq 'StartPending') -or ($service.Status -eq 'StopPending')) {
$maxStateChecks = 3
$stateChecks = 0
while (($stateChecks -lt $maxStateChecks) -and (($service.Status -eq 'StartPending') -or ($service.Status -eq 'StopPending'))) {
$timestamp = (Get-Date -Format yyyy-MM-dd--HH-mm-ss)
$logSvcStillPendingMsg = "[$timestamp] Attempt #$tries - $serviceName service status is $($service.Status). This may indicate the service is hung in the Starting or Stopping state. Waiting another $secondsBeforeRetry seconds before checking again."
Add-Content -Path $logFullPath -Value $logSvcStillPendingMsg
$stateChecks += 1
if ($stateChecks -ne $maxStateChecks) {
Start-Sleep -s $secondsBeforeRetry
}
$service.Refresh()
if ($service.Status -eq 'Running') {
$timestamp = (Get-Date -Format yyyy-MM-dd--HH-mm-ss)
$logSvcStartSuccessMsg = "[$timestamp] Attempt #$tries - $serviceName service status is now $($service.Status)"
Add-Content -Path $logFullPath -Value $logSvcStartSuccessMsg
} elseif ($service.Status -eq 'Stopped') {
$timestamp = (Get-Date -Format yyyy-MM-dd--HH-mm-ss)
$logSvcStoppedAfterPendingMsg = "[$timestamp] Attempt #$tries - $serviceName service status is now $($service.Status). If any Start attempts remain the script will try again on the next loop."
Add-Content -Path $logFullPath -Value $logSvcStoppedAfterPendingMsg
}
}
$service.Refresh()
if (($stateChecks -eq $maxStateChecks) -and (($service.Status -eq 'StartPending') -or ($service.Status -eq 'StopPending'))) {
$timestamp = (Get-Date -Format yyyy-MM-dd--HH-mm-ss)
$logSvcStuckPendingMsg = "[$timestamp] Attempt #$tries - $serviceName service status appears stuck in a Pending (Starting or Stopping) state. Attempting to force kill process."
Add-Content -Path $logFullPath -Value $logSvcStuckPendingMsg
$servicePID = Get-CimInstance -Class Win32_Service -Filter "Name LIKE '$serviceName'" | Select-Object -ExpandProperty ProcessId
$resultMsg = taskkill /pid $servicePID /f
$timestamp = (Get-Date -Format yyyy-MM-dd--HH-mm-ss)
$logSvcTaskKillMsg = "[$timestamp] Attempt #$tries - taskkill result:`n $resultMsg"
Add-Content -Path $logFullPath -Value $logSvcTaskKillMsg
Start-Sleep -s 10
$service.Refresh()
$timestamp = (Get-Date -Format yyyy-MM-dd--HH-mm-ss)
$logSvcStatusMsg = "[$timestamp] Attempt #$tries - $serviceName service status is now $($service.Status)"
Add-Content -Path $logFullPath -Value $logSvcStatusMsg
}
}
if (($tries -eq $maxTries) -and ($service.Status -ne 'Running')) {
$timestamp = (Get-Date -Format yyyy-MM-dd--HH-mm-ss)
$logNoMoreAttemptsMsg = "[$timestamp] $serviceName service status is $($service.Status) after $maxTries Start attempts. This run of the script will not continue trying to Start the service."
Add-Content -Path $logFullPath -Value $logNoMoreAttemptsMsg
}
}
# Add line break at end of log file entry
Add-Content -Path $logFullPath -Value "`n"
}
다음과 같은 로그 파일이 출력됩니다.
## Log file for Netman auto-start script ##
## Created [2022-07-11--22-55-38] ##
[2022-07-11--23-25-53] Netman service status is Stopped, attempting to Start. Will try up to 3 times.
[2022-07-11--23-26-03] Attempt #1 - Netman service status is Stopped and failed to start with error:
Service 'Network Connections (Netman)' cannot be started due to the following error: Cannot start service Netman on computer '.'.
[2022-07-11--23-26-43] Attempt #2 - Netman service status is Stopped and failed to start with error:
Service 'Network Connections (Netman)' cannot be started due to the following error: Cannot start service Netman on computer '.'.
[2022-07-11--23-27-23] Attempt #3 - Netman service status is Stopped and failed to start with error:
Service 'Network Connections (Netman)' cannot be started due to the following error: Cannot start service Netman on computer '.'.
[2022-07-11--23-27-53] Netman service status is Stopped after 3 Start attempts. This run of the script will not continue trying to Start the service.
[2022-07-12--01-46-15] Netman service status is Stopped, attempting to Start. Will try up to 3 times.
[2022-07-12--01-46-25] Attempt #1 - Netman service status is now Running
서비스가 중지된 경우 서비스 시작
Get-Service "servicename*" | Where {$_.Status -ne 'Stopped'} | Start-Service
언급URL : https://stackoverflow.com/questions/35064964/powershell-script-to-check-if-service-is-started-if-not-then-start-it
'programing' 카테고리의 다른 글
도커 오류로 도커 컨테이너를 삭제할 수 없습니다. 충돌: 리포지토리 참조를 제거할 수 없습니다. (0) | 2023.08.04 |
---|---|
jQuery: print_r() 디스플레이 등가물? (0) | 2023.08.04 |
Aspect Fit(측면 맞춤 (0) | 2023.08.04 |
HTML5 비디오 치수 (0) | 2023.08.04 |
LINQ를 SQL에 사용하면 SQL 주입을 방지할 수 있습니다. (0) | 2023.08.04 |