2014-09-29 38 views
3

说我有两大块这样的:如何根据以前的资源执行情况有条件地执行Powershell DSC中的资源?

Configuration TestConfig 
{ 
    Node ('localhost') { 
     File foo { 
      DestinationPath = 'C:\foo.txt' 
      Contents = 'Bar' 
     } 
     Script dothing { 
      SetScript = {'Baz' | set-content C:\foo.txt} 
      TestScript = {return $false} 
      GetScript = { 
       return @{ 
        GetScript = '' 
        SetScript = '' 
        TestScript = '' 
        Credential = $Credential 
        Result = (Invoke-Expression -Command $TestScript) 
       } 
      } 
      DependsOn = '[File]foo' 
     } 
    } 
} 

我建了一个试验,做这样的事情,但它似乎像服务资源获取文件资源的测试输出,无论执行的 - 也就是说,如果它实际上对文件做了任何事情。

VERBOSE: [MACHINENAME]: LCM: [ Start Set  ] 
VERBOSE: [MACHINENAME]: LCM: [ Start Resource ] [[File]foo] 
VERBOSE: [MACHINENAME]: LCM: [ Start Test  ] [[File]foo] 
VERBOSE: [MACHINENAME]:       [[File]foo] The destination object was found and no action is required. 
VERBOSE: [MACHINENAME]: LCM: [ End Test  ] [[File]foo] in 0.0040 seconds. 
VERBOSE: [MACHINENAME]: LCM: [ Skip Set  ] [[File]foo] 
VERBOSE: [MACHINENAME]: LCM: [ End Resource ] [[File]foo] 
VERBOSE: [MACHINENAME]: LCM: [ Start Resource ] [[Script]dothing] 
VERBOSE: [MACHINENAME]: LCM: [ Start Test  ] [[Script]dothing] 
VERBOSE: [MACHINENAME]: LCM: [ End Test  ] [[Script]dothing] in 0.0050 seconds. 
VERBOSE: [MACHINENAME]: LCM: [ Start Set  ] [[Script]dothing] 
VERBOSE: [MACHINENAME]: LCM: [ End Set  ] [[Script]dothing] in 0.0060 seconds. 
VERBOSE: [MACHINENAME]: LCM: [ End Resource ] [[Script]dothing] 
VERBOSE: [MACHINENAME]: LCM: [ End Set  ] 
VERBOSE: [MACHINENAME]: LCM: [ End Set  ] in 0.0390 seconds. 

人为的例子不谈,我怎么能只拥有脚本资源执行只有当文件资源实际上做了什么?

我在这里的用例是检查一个文件是否在远程位置发生了变化,如果是,将它复制到本地机器,然后重新启动服务。如果文件没有改变,我显然不想重新启动服务,但是我看不到一个好的幂等方法来做到这一点,因为文件正在使用散列测试 - 我必须有我的服务重新启动步骤执行相同的文件散列检查。

回答

3

我不认为DSC中有任何本地内置的东西,它可以让一个资源检测是否在相同配置运行中为不同资源实际执行了“Set-TargetResource”函数。

但是,以下脚本资源将按照您的要求进行操作,但它们使用全局脚本级别的变量进行通信,因此如果您有多个服务在单个DSC中进行配置,它们会中断。 ConfigureService脚本资源更新本地配置文件并设置RestartService资源读取的标志以检查是否进行了更改。这有点脏,但它有效。

Script ConfigureService { 
    GetScript = { return $null; } 
    TestScript = { 
     # compare remote and local file contents and return 
     # $true if they match, or $false if they're different 
     $source = "D:\temp\dsctest\source.txt"; 
     $target = "D:\temp\dsctest\target.txt"; 
     $isMatch = [System.IO.File]::ReadAllText($target) -eq [System.IO.File]::ReadAllText($source); 
     # set a flag for the RestartService resource to read 
     $script:serviceChanged = -not $isMatch; 
     write-verbose "isMatch = $isMatch"; 
     return $isMatch; 
    } 
    SetScript = { 
     # overwrite the local file 
     $source = "D:\temp\dsctest\source.txt"; 
     $target = "D:\temp\dsctest\target.txt"; 
     $content = [System.IO.File]::ReadAllText($source); 
     write-verbose "overwriting config"; 
     [System.IO.File]::WriteAllText($target, $content); 
    } 
} 

Script RestartService { 
    DependsOn = "[Script]ConfigureService" 
    GetScript = { return $null; } 
    TestScript = { 
     write-verbose "serviceChanged = $($script:serviceChanged)"; 
     return -not $script:serviceChanged; 
    } 
    SetScript = { 
     # restart the service 
     write-verbose "restarting service"; 
    } 
} 

或者只是把它们全部放到一个资源中。如果您希望将其重复用于多个服务,则可以将其移动到一个完整的ServiceConfiguration定制资源中。

Script ConfigureService { 
    GetScript = { return $null; } 
    TestScript = { 
     # compare remote and local file contents and return 
     # $true if they match, or $false if they're different 
     $source = "D:\temp\dsctest\source.txt"; 
     $target = "D:\temp\dsctest\target.txt"; 
     $isMatch = [System.IO.File]::ReadAllText($target) -eq [System.IO.File]::ReadAllText($source); 
     write-verbose "isMatch = $isMatch"; 
     return $isMatch; 
    } 
    SetScript = { 
     # overwrite the local file 
     $source = "D:\temp\dsctest\source.txt"; 
     $target = "D:\temp\dsctest\target.txt"; 
     $content = [System.IO.File]::ReadAllText($source); 
     write-verbose "overwriting config"; 
     [System.IO.File]::WriteAllText($target, $content); 
     # restart the service 
     write-verbose "restarting service"; 
    } 
} 
+0

同意;没有本地的方式来有条件地执行基于另一资源的资源。 – briantist 2014-09-29 22:15:39