DSC:如何停止和启动Windows服务

时间:2016-02-16 14:33:03

标签: ms-release-management dsc

我想用DSC(期望状态配置)做一件非常简单的事情:

停止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我在微软发布管理中使用它,在这里,似乎'MyTestConfig2'不再执行(或其他出错的地方未提及在日志中。)

如何在发布管理的上下文中使用dsc实现这个简单的场景?或者甚至有更好的方法来做这样的事情?

3 个答案:

答案 0 :(得分:2)

最简单的方法是创建一个将Name和State作为键的服务资源。随意扩展这个简单的服务资源(我会在找到时间时尝试使用https://github.com/nanalakshmanan/nServiceManager

答案 1 :(得分:0)

Afer Daniel Mann的帖子我提出了这个最小的解决方案:

[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
    }

}

答案 2 :(得分:0)

至少对我来说,以下效果最好:

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

然后:

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

是的,使它变得更复杂,但分裂似乎对某些服务效果最好。