说我有两个这样的街区:
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'
}
}
}
我构建了一个类似这样的测试,但似乎无论File资源的测试输出如何,都会执行Service资源 - 也就是说,如果它实际上对文件做了任何操作。
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.
除了受控的示例之外,我怎样才能仅在文件资源实际执行某些操作时才执行脚本资源?
我的用例是检查远程位置的文件是否已更改,如果是,请将其复制到本地计算机,然后重新启动服务。我显然不希望重新启动服务,如果文件没有改变,但我看不到一个好的幂等方式来做到这一点,因为文件正在使用哈希测试 - 我必须有我的服务重启步骤执行相同的文件哈希检查。
答案 0 :(得分: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";
}
}