我已经构建了一个小的PowerShell脚本来检查服务是否已启动。如果没有启动,请尝试启动它,然后等待一分钟再次检查。继续重复此过程,直到服务成功启动。我发现循环不像我预期的那样,我似乎必须在循环中重新分配服务变量才能获得更新状态。这是我的代码:
$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}
}
如果我运行的代码没有第三行(带注释的那一行),我得到以下输出。我可以检查Windows服务管理器,并在第一次循环后显然启动了服务。为什么需要第三行?
鉴于此行为,是否有更好的方法来编写此代码?
谢谢
答案 0 :(得分:22)
我认为您的代码可能过于复杂:如果您只是检查服务是否正在运行,如果没有,请运行它然后停止重新评估,以下内容就足够了:
$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'
}
}
答案 1 :(得分:2)
鉴于$arrService = Get-Service -Name $ServiceName
,$arrService.Status
是静态属性,对应于调用时的值。需要时使用$arrService.Refresh()
将属性更新为当前值。
MSDN ~ ServiceController.Refresh()
通过将属性重置为其当前值来刷新属性值。
答案 2 :(得分:1)
一个可能更简单的解决方案:
get-service "servicename*" | Where {$_.Status -eq 'Stopped'} | start-service
答案 3 :(得分:0)
[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
}
答案 4 :(得分:0)
结合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')
{
Stop-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'
}
}
}
答案 5 :(得分:0)
下面是一个紧凑的脚本,它将检查是否“正在运行”并尝试启动服务,直到该服务返回运行状态。
$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"
答案 6 :(得分:0)
尝试使事情尽可能顺利-我在这里建议稍微修改GuyWhoLikesPowershell的建议。
我用一会儿替换了if和直到-并检查了“已停止”,因为如果状态为“正在启动”或“正在停止”,我都不想启动。
$Service = 'ServiceName'
while ((Get-Service $Service).Status -eq 'Stopped')
{
Start-Service $Service -ErrorAction SilentlyContinue
Start-Sleep 10
}
Return "$($Service) has STARTED"
答案 7 :(得分:0)
$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'
}
}
我们是否可以对多个服务使用相同的脚本并在服务关闭时发送一封电子邮件。