【问题标题】:How to ensure that service has been stopped or started using PowerShell?如何使用 PowerShell 确保服务已停止或启动?
【发布时间】:2019-02-13 10:02:44
【问题描述】:

我正在VSTS/Azure DevOps 管道中运行一个任务来停止和卸载窗口服务列表。我在这里做的是在代码下面运行并使用睡眠方法来确保上述方法已经完成。

Function DeleteService([string] $ServiceName) 
{
    TRY{

        $Service = Get-WmiObject -Class Win32_Service -Filter "Name='$ServiceName'"  

        if ($Service -ne $null) 
        {
            Write-Output "Stopping window service - '$ServiceName'"         
            $Service.StopService()     
            # Adding a sleep for ten seconds to let the process stop the service completely
            Start-Sleep -m 10000 
            Write-Output "Stopping Window service - '$ServiceName' completed"   


            Write-Output "Uninstalling window service - '$ServiceName'"         
            $Service.Delete()   
            # Adding a sleep for ten seconds to let the process stop the service completely
            Start-Sleep -m 10000
            Write-Output "Uninstalling window service - '$ServiceName' completed"   

        } 
        else 
        {
            Write-Output "Window service - '$ServiceName' does not exist. Uninstallation Complete"
        }
    }
    CATCH
    {
        $ErrorMessage = $_.Exception.Message    
        Write-Error " ********************** Error in uninstalling window service : $ServiceName with exception $ErrorMessage ********************** "
    }
}

在 PowerShell 中是否有更好的方法可以确认服务已停止,现在我可以继续。这样我就不必在代码中添加这样的补丁了。

因为,正如我从Microsoft site 所研究的那样,这些命令将消息发送到Windows Service Controller。他们没有完成任务。所以我很怀疑如何编写这样的代码,这些代码将与正确的准时执行同步运行。

【问题讨论】:

  • 获取服务、停止服务和删除服务 (documentation link) [编辑 - PSv6 仅适用于删除服务,因此可能无济于事]
  • 这些方法在移动到下一行之前是否完成了它们的工作?
  • 它们是命令而不是方法,是的,它们是同步的。请注意编辑我关于 PSv6 的帖子 - 不确定您的管道支持/使用的版本。

标签: c# .net powershell azure-devops


【解决方案1】:

如果您使用的是 PS v6,则可以使用 Remove-Service,因为这将停止并删除服务:

if (Get-Service $ServiceName -ErrorAction SilentlyContinue) {
    Remove-Service $ServiceName -Verbose
} 
else {
    Write-Output "Window service - '$ServiceName' does not exist. Uninstallation Complete"
}

如果您使用的是较低版本,我会使用 Stop-ServiceGet-CimInstance(而不是 Get-WmiObject):

if (Get-Service $ServiceName -ErrorAction SilentlyContinue) {
    Stop-Service $ServiceName -Verbose
    Get-CimInstance -ClassName Win32_Service -Filter "Name='$ServiceName'" | Remove-CimInstance
} 
else {
    Write-Output "Window service - '$ServiceName' does not exist. Uninstallation Complete"
}

【讨论】:

  • 一旦执行此行 - “Remove-Service $ServiceName -Verbose”。我可以确定在下一行中该服务已从系统中删除吗?
  • 是的,如果命令完成,服务将被删除,如果无法删除服务,您将收到终止错误。
【解决方案2】:

您可以使用Get-Service 来检查服务的状态,而不是使用Get-WmiObject

$service = Get-Service -Name 'VSS'
Write-Host $service.Status
# Stopped/Running

所以如果你想确保服务被停止然后继续删除,你可以用while循环包装状态检查。

while ($service.Status -ne 'Running')
{
  ....
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-25
    • 1970-01-01
    • 2018-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多