【问题标题】:How to upgrade windows service using PowerShell Desired State Configuration如何使用 PowerShell Desired State Configuration 升级 Windows 服务
【发布时间】:2016-02-09 21:43:49
【问题描述】:

以下是我的配置示例,安装工作正常,但如果我将 '\\BuildMachine\Output\MyService.exe' 替换为较新版本,则 DSC 失败并出现文件正在使用错误。使用 DSC 升级 Windows 服务的正确方法是什么?谢谢。

Configuration ServiceTestConfiguration {
    Import-DscResource -ModuleName PSDesiredStateConfiguration
    Import-DscResource -ModuleName xPSDesiredStateConfiguration

    Node localhost
    {
        File EnsureLatestServiceExist {
            Ensure = 'Present'
            Type = 'File'
            Checksum = 'ModifiedDate'
            SourcePath = '\\BuildMachine\Output\MyService.exe'
            DestinationPath = 'c:\MyService\MyService.exe'
        }

        xService EnsureServiceStarted {
            Ensure = 'Present'
            DependsOn = '[File]EnsureLatestServiceExist'
            Name = 'MyService'
            DisplayName = 'My Service'
            Description = 'My Service'
            Path = 'c:\MyService\MyService.exe'
            StartupType = 'Automatic'
            State = 'Running'
        }
    }
}

【问题讨论】:

  • 我不确定您是否可以使用内置资源执行此操作。大约 6 个月前,我开始编写 DSC 解决方案,在对内置内容进行了一些修改后,我选择创建自定义资源来部署我们的服务。这使我能够编写完全自定义的逻辑来满足我们的需求,从而允许比较二进制文件和配置。我认为你应该考虑走这条路。 msdn.microsoft.com/en-us/powershell/dsc/authoringresource

标签: powershell service dsc


【解决方案1】:

我还没有找到实现此目的的内置方法,但脚本资源几乎可以让您做任何事情。

添加一个脚本资源,用于检查远程(源)文件是否已更新。如果远程文件已更新,请停止服务。使文件资源依赖于脚本资源,以便它在文件复制之前运行。 Service 资源将最后运行并再次启动服务。

Script StopServiceCheck
{
    SetScript = 
    {
        Stop-Service -Name ServiceName -Force
    }
    TestScript = 
    {
        $LocalFile = "C:\Path\To\Local.exe"
        $RemoteFile = "\\Path\To\Remote.exe"

        #Returns false if the remote file is newer than the local file or use -eq
        return ((Get-Item -Path $RemoteFile).LastWriteTime -le (Get-Item -Path $LocalFile).LastWriteTime) 
    }
    GetScript = 
    {
        $LocalFile = "C:\Path\To\Local.exe"
        $RemoteFile = "\\Path\To\Remote.exe"
        $return = @{Result = "Executables match"}

        If ((Get-Item -Path $RemoteFile).LastWriteTime -gt (Get-Item -Path $LocalFile).LastWriteTime) { $return.Result = "Remote file is newer" }

        return $return
    }
}

【讨论】:

    【解决方案2】:

    开源 PowerShell 模块 Carbon 具有为此目的的自定义 DSC 资源:http://get-carbon.org/Carbon_Service.html

    【讨论】:

    • 但这并不能解决升级到新 exe 时的“文件正在使用”问题。这不是这里要问的问题吗?
    【解决方案3】:

    这不是一种想要的状态,而是两种想要的状态。

    第一个期望状态是:服务已正确关闭并准备好进行维护

    第二个期望状态是:服务处于活动状态并使用最新版本的代码运行

    把它写成两个脚本。

    【讨论】:

    • 这与我所了解的有关期望状态的所有内容背道而驰,您不会说第一步、第二步等……现在这个建议正好相反,它说我有一个期望的状态这取决于先发生的另一件事。
    • @AaronStainback DSC 是您用于部署软件的配置管理工具。在部署的上下文中,它有两种状态。如果您只是使用 DSC 来强制执行正确的配置,那么是的,您只需一个脚本来强制执行该配置。但是您的部署需要“离线”状态。
    • 抱歉,我只是不同意,说我必须先运行一个配置才能运行另一个配置,否则事情会中断,这违背了 DSC 的主要目的。 DSC 的承诺是推送配置并使其无论系统的当前状态如何。我不需要知道有关系统当前状态的任何信息。我正在开发一个自定义资源,该资源将在文件更改时停止服务,这应该可以完成我正在寻找的内容。
    • 在您的示例中,您已经准备好将这个所需的状态分解为 2 个资源。你真的需要编写一个自定义资源来一步完成你想做的事情。我真的认为这是你前进的方向。
    猜你喜欢
    • 2022-10-15
    • 2018-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    相关资源
    最近更新 更多