使用 Powershell 同步停止远程服务

使用 Powershell 同步停止远程服务

我有一个用 Powershell 编写的自定义部署脚本。此脚本需要更新远程计算机上的服务,因此,它首先需要停止该服务才能修改可执行文件。

这似乎是个问题。

要同步停止服务,我可以使用net stop servicenamestop-service servicename。问题是这两个命令仅限于本地机器。

要停止远程计算机上的服务,我知道我可以使用该sc.exe程序:

sc.exe \\computername stop servicename

但这是异步的,所以我实际上不能使用它(嗯,sleep 5似乎可以做到,但那很肮脏)。

如何使用 Powershell 同步停止远程服务?

答案1

获取服务返回服务控制器对象,然后您可以使用它来操作服务。无论是本地还是远程都没关系。我有以下脚本来停止后台处理程序(打印后台处理程序)服务并等待它停止,最多 5 秒钟。我刚刚将 -Name 参数添加到 Get-Service,我能够在远程服务器上停止后台处理程序。

笔记:就我的情况而言,两台服务器都是 Server 2008 R2。您的情况可能会有所不同。

Set-StrictMode -Version "2.0"

[System.ServiceProcess.ServiceController]$service = Get-Service -Name "Spooler" -ComputerName "remote_server.domain.com"

[int]$waitCount = 5
do
{
    $waitCount--

    switch($service.Status)
    {
        { @(
        [System.ServiceProcess.ServiceControllerStatus]::ContinuePending,
        [System.ServiceProcess.ServiceControllerStatus]::PausePending,
        [System.ServiceProcess.ServiceControllerStatus]::StartPending,
        [System.ServiceProcess.ServiceControllerStatus]::StopPending) -contains $_ }
        {
            # A status change is pending. Do nothing.
            break;
        }

        { @(
        [System.ServiceProcess.ServiceControllerStatus]::Paused,
        [System.ServiceProcess.ServiceControllerStatus]::Running) -contains $_ }
        {
            # The service is paused or running. We need to stop it.
            $service.Stop()
            break;
        }

        [System.ServiceProcess.ServiceControllerStatus]::Stopped
        {
            # This is the service state that we want, so do nothing.
            break;
        }
    }

    # Sleep, then refresh the service object.
    Sleep -Seconds 1
    $service.Refresh()

} while (($service.Status -ne [System.ServiceProcess.ServiceControllerStatus]::Stopped) -and ($waitCount -gt 0))

还有设置服务它将接受计算机名称参数,但如果该服务具有依赖服务,它似乎无法停止该服务。

答案2

PowerShell 2 添加了很多用于访问远程计算机的功能。

以下是一些有用的 cmdlet(来自 PowerShell 的信息get-help):

Enter-PSSession

摘要
开始与远程计算机的交互式会话。

描述
Enter-PSSession cmdlet 启动与单个远程计算机的交互式会话。在会话期间,您键入的命令将在远程计算机上运行,​​就像您直接在远程计算机上键入一样。您一次只能有一个交互式会话。

通常,使用 ComputerName 参数指定远程计算机的名称。但是,也可以使用通过 New-PSSession 创建的会话作为交互式会话。

要结束交互式会话并断开与远程计算机的连接,请使用 Exit-PSSession cmdlet,或键入“exit”。

New-PSSession

摘要
创建与本地或远程计算机的持久连接。

描述
New-PSSession cmdlet 在本地或远程计算机上创建 Windows PowerShell 会话 (PSSession)。创建 PSSession 时,Windows PowerShell 会与远程计算机建立持久连接。

使用 PSSession 运行多个共享数据(例如函数或变量值)的命令。要在 PSSession 中运行命令,请使用 Invoke-Command cmdlet。要使用 PSSession 直接与远程计算机交互,请使用 Enter-PSSession cmdlet。有关详细信息,请参阅 about_PSSessions。

Invoke-Command

摘要
在本地和远程计算机上运行命令。

描述
Invoke-Command cmdlet 在本地或远程计算机上运行命令并返回命令的所有输出,包括错误。使用单个 Invoke-Command 命令,您可以在多台计算机上运行命令。

要在远程计算机上运行单个命令,请使用 ComputerName 参数。要运行一系列共享数据的相关命令,请在远程计算机上创建 PSSession(持久连接),然后使用 Invoke-Command 的 Session 参数在 PSSession 中运行命令。

更多信息:嘿,脚本专家!告诉我有关 Windows PowerShell 2.0 中的远程处理的信息

答案3

我会调查类似的事情执行程序。它将net stop在远程机器上执行,从而获得同步部分,但它可以远程完成(毕竟这是 PsExec 的重点)。

相关内容