DSC: как остановить и запустить службу Windows

Я хочу сделать очень простую вещь с DSC (Desired State Configuration):

Остановите службу Windows, разверните файлы и, наконец, снова запустите службу. Таким образом, у меня было следующее:

Service ServicesStop
{
    Name = "TheTestService"
    State = "Stopped"
}

File CopyDeploymentBits
{  
  Ensure = "Present"
  Type = "Directory"
  Recurse = $true
  SourcePath = $applicationPath
  DestinationPath = $deployOutputPath
}

Service ServicesStart
{
    Name = "TheTestService"
    StartupType = "Automatic"
    State = "Running"
}

Но, к сожалению, это не работает, так как нельзя дважды использовать одно и то же имя (Name = "TheTestService") в конфигурации (почему? имеет смысл) в качестве обходного пути я пробовал что-то вроде этого

Configuration MyTestConfig {
    Node $env:COMPUTERNAME {
        Service ServicesStop
        {
            Name = "TheTestService"
            State = "Stopped"
        }

        File CopyDeploymentBits
        {  
          Ensure = "Present"
          Type = "Directory"
          Recurse = $true
          SourcePath = $applicationPath
          DestinationPath = $deployOutputPath
        }
    }
}

Configuration MyTestConfig2 {
    Node $env:COMPUTERNAME {
        Service ServicesStart
        {
            Name = "TheTestService"
            StartupType = "Automatic"
            State = "Running"
        }
    }
}

MyTestConfig
MyTestConfig2

Выглядит безумно - но это работает!

К сожалению, я не использую простой DSC, я использую его с Microsoft Release Management, и здесь кажется, что MyTestConfig2 больше не выполняется (или что-то еще идет не так, что не упоминается в журналах ).

Как я могу реализовать этот простой сценарий с помощью dsc в контексте управления выпусками? Или есть еще лучший способ сделать что-то подобное?


person timtos    schedule 16.02.2016    source источник
comment
См. этот вопрос: stackoverflow.com/questions/35302781/   -  person Daniel Mann    schedule 16.02.2016
comment
Это плохая новость! Возможно, лучше использовать Chef. Я думаю, чтобы помнить, что это хорошо работает с их решением. Но большое спасибо за ваш вклад и ссылку (если ссылка когда-либо не работает, «решение» выглядит следующим образом: напишите свой собственный ресурс DSC).   -  person timtos    schedule 17.02.2016
comment
@DanielMann - возможно, вы хотели бы опубликовать ответ, который я могу принять? Вы указали мне правильное направление. :)   -  person timtos    schedule 25.02.2016


Ответы (3)


Самый простой способ — создать сервисный ресурс, который принимает в качестве ключа имя и состояние. Не стесняйтесь расширять этот простой служебный ресурс (я постараюсь добраться до него, когда найду время) https://github.com/nanalakshmanan/nServiceManager

person Nana Lakshmanan    schedule 25.02.2016
comment
Спасибо за ваш вклад. Выглядит очень хорошо. После сообщения Дэниела Манна я придумал сокращенное решение, которое только что опубликовал, поэтому я хотел бы отдать ему должное, но ваш ответ - это, по крайней мере, голосование! :) Спасибо еще раз. - person timtos; 25.02.2016

После публикации Даниэля Манна я придумал это минимальное решение:

[DscResource()]
class InstallStopCopyStartServiceResource {
    [DscProperty(Key)]
    [string]$ServiceName

    [DscProperty(Mandatory)]
    [string] $SourcePath

    [DscProperty(Mandatory)]
    [string] $DestinationPath

    [void] Set()
    {
        $needsInstallation = $false;

        $testService = Get-Service | Where-Object {$_.Name -eq $this.ServiceName}
        if ($testService -eq $null) 
        {
            $needsInstallation = $true;
        } elseif ($testService.Status -eq "Running") 
        {
            Stop-Service $this.ServiceName
        } 

        # Due to stupid Copy-Item behavior we first delete all old files
        # (https://social.technet.microsoft.com/Forums/office/en-US/20b9d259-90d9-4e51-a125-c0f3dafb498c/copyitem-not-overwriting-exising-files-but-creating-additional-subfolder?forum=winserverpowershell)
        Remove-Item -Path $this.DestinationPath -Recurse -Force -ErrorAction SilentlyContinue

        # Copy files
        Copy-Item -Path $this.SourcePath -Destination $this.DestinationPath -Recurse -Force

        if ($needsInstallation -eq $true) 
        {
            # Install service
            $param = 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\installUtil ' + $this.DestinationPath  + '\service.exe'
            Invoke-Expression $param
        }

        # Start the service
        Start-Service $this.ServiceName

        # Configure service
        Set-Service $this.ServiceName -StartupType "Automatic"
    }

    [bool] Test()
    {
        # Always perform all steps
        return $false
    }

    [InstallStopCopyStartServiceResource] Get()
    {
        return $this
    }

}
person timtos    schedule 25.02.2016

По крайней мере, для меня лучше всего работает следующее:

# Configure the Service 1st
Service Servicewuauserv {
    Name = 'wuauserv'
    BuiltInAccount = 'LocalSystem'
    State = 'Running'
}

А потом:

# Ensure it is running
ServiceSet wuauserv {
     Name = 'wuauserv'
     BuiltInAccount = 'LocalSystem'
     State = 'Running'
}

Да, это усложняет задачу, но разделение лучше всего работает с некоторыми сервисами.

person Joerg Hochwald    schedule 29.05.2017