Pare de forma síncrona um serviço remoto com o Powershell

3

Eu tenho um script de implantação personalizado escrito no Powershell. Este script precisa atualizar um serviço em uma máquina remota e, como tal, primeiro precisa pará-lo para poder modificar os arquivos executáveis.

Isso parece ser um problema.

Para interromper um serviço de forma síncrona, posso usar net stop servicename ou stop-service servicename . O problema é que esses dois comandos estão confinados à máquina local.

Para interromper um serviço em uma máquina remota, sei que posso usar o programa sc.exe :

sc.exe \computername stop servicename

Mas isso é assíncrono, então eu não posso realmente usá-lo (bem, sleep 5 parece fazer isso, mas isso é um pouco sujo).

Como posso parar de forma síncrona um serviço remoto usando o Powershell?

    
por zneak 11.07.2012 / 23:12

3 respostas

4

Get-Service retorna um objeto ServiceController , que você pode usar para manipular o serviço. Não importa se é local ou remoto. Eu tenho o script abaixo para parar o serviço de spooler (spooler de impressão) e aguardar que ele pare, até 5 segundos. Acabei de adicionar o parâmetro -Name ao Get-Service e consegui parar o spooler em um servidor remoto.

Nota: Ambos os servidores no meu caso eram o Server 2008 R2. Sua milhagem pode variar.

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))

Também existe Set-Service que aceitará um parâmetro de nome de computador, mas não parece ser capaz de interromper um serviço se esse serviço tiver serviços dependentes.

    
por 12.07.2012 / 00:21
2

O PowerShell 2 adicionou muitas coisas para acessar computadores remotos com ele.

Veja alguns cmdlets úteis para pesquisar (informações do get-help do PowerShell):

Enter-PSSession :

SYNOPSIS
Starts an interactive session with a remote computer.

DESCRIPTION
The Enter-PSSession cmdlet starts an interactive session with a single remote computer. During the session, the commands that you type run on the remote computer, just as though you were typing directly on the remote computer. Youcan have only one interactive session at a time.

Typically, you use the ComputerName parameter to specify the name of the remote computer. However, you can also use a session that you create by using New-PSSession for the interactive session.

To end the interactive session and disconnect from the remote computer, use the Exit-PSSession cmdlet, or type "exit".

New-PSSession :

SYNOPSIS
Creates a persistent connection to a local or remote computer.

DESCRIPTION
The New-PSSession cmdlet creates a Windows PowerShell session (PSSession) on a local or remote computer. When you create a PSSession, Windows PowerShell establishes a persistent connection to the remote computer.

Use a PSSession to run multiple commands that share data, such as a function or the value of a variable. To run commands in a PSSession, use the Invoke-Command cmdlet. To use the PSSession to interact directly with a remote computer, use the Enter-PSSession cmdlet. For more information, see about_PSSessions.

Invoke-Command :

SYNOPSIS
Runs commands on local and remote computers.

DESCRIPTION
The Invoke-Command cmdlet runs commands on a local or remote computer and returns all output from the commands, including errors. With a single Invoke-Command command, you can run commands on multiple computers.

To run a single command on a remote computer, use the ComputerName parameter. To run a series of related commands that share data, create a PSSession (a persistent connection) on the remote computer, and then use the Session parameter of Invoke-Command to run the command in the PSSession.

Mais informações: Ei, Scripting Guy! Me fale sobre o Remoting no Windows PowerShell 2.0

    
por 11.07.2012 / 23:56
1

Eu procuraria algo como PsExec . Ele executará o net stop na máquina remota e, assim, obterá a parte síncrona, mas isso pode ser feito remotamente (esse é o ponto do PsExec depois de tudo).

    
por 11.07.2012 / 23:25