PowerShell DSC - 由于节点名称为空,因此跳过节点处理

时间:2014-07-03 13:47:51

标签: powershell dsc

计算机节点符合过滤条件时,我在向DSC配置块中的节点应用过滤器时遇到问题。例如:

configuration MyApp {
    node $AllNodes.Where{ $_.Role -Match "role1|role2" }.NodeName {
        File ApplicationFolder {
            Type = "Directory"
            DestinationPath = $Node.ApplicationFolder
            Ensure = "Present"
        }
    }
}

$configData = @{
    AllNodes = @(
        @{
            NodeName = "*"
        }
        @{
            NodeName = $env:COMPUTERNAME
            Role = "role3"
            ApplicationFolder = "E:\MyApp"
        }
    )
}

$mof = MyApp -ConfigurationData $configData;
Start-DscConfiguration MyApp -ComputerName $env:COMPUTERNAME -Wait -Verbose;

运行此脚本会出现以下错误:

PSDesiredStateConfiguration\node : Node processing is skipped since the node name is empty.
At E:\test\test.ps1:3 char:5
+     node $AllNodes.Where{ $_.Role -Match "role1|role2" }.NodeName {
+     ~~~~
    + CategoryInfo          : InvalidOperation: (:) [Write-Error], InvalidOperationException
    + FullyQualifiedErrorId : NodeNameIsRequired,PSDesiredStateConfiguration\node
Errors occurred while processing configuration 'MyApp'.
At
C:\Windows\system32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\PSDesiredStateConfiguration.psm1:2088 char:5
+     throw $errorRecord
+     ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (MyApp:String) [], InvalidOperationException
    + FullyQualifiedErrorId : FailToProcessConfiguration

到目前为止,我提出的最佳解决方案是将每个Node包装在一个检查空值的“if {}”中 - 例如

configuration MyApp {
    $nodeNames = $AllNodes.Where{ $_.Role -Match "role1|role2" }.NodeName;
    if( $nodeNames -ne $null )
    {
        node $nodeNames {
            File ApplicationFolder {
                Type = "Directory"
                DestinationPath = $Node.ApplicationFolder
                Ensure = "Present"
            }
        }
    }
}

但这感觉就像是一个黑客,并填补我的配置块与很多cruft。当零节点与过滤器匹配时,是否有更简洁的方法来避免此错误?

(对于上下文,我正在构建多个开发,测试和uat环境,我们只将部分服务器角色集部署到每个环境,所以我不想更改Node过滤器表达式的逻辑或删除来自配置块的节点,因为它们在生产中是必需的,我想在任何地方使用相同的脚本。)

2 个答案:

答案 0 :(得分:2)

最后,我决定在有过滤器的节点周围添加一个检查。当有很多不同的过滤器时,它有点kludgy和非常重复,但至少它使解决方法接近问题的位置,如果你眯眼它不会看起来 与原来的不同代码。

configuration MyApp {

    $nodeNames = $AllNodes.Where{ $_.Role -Match "role1|role2" }.NodeName;
    if( $nodeNames -ne $null )
    {
        node $nodeNames {
            File ApplicationFolder {
                Type = "Directory"
                DestinationPath = $Node.ApplicationFolder
                Ensure = "Present"
            }
        }
    }

}

答案 1 :(得分:0)

如何在-ErrorAction SilentlyContinue的电话中添加-ErrorVariable DscErrorsStart-DscConfiguration

configuration foo {
    param ([string[]] $ComputerName)
    node $ComputerName {
        File dsctest.txt {
            DestinationPath = 'c:\test\dsctest.txt';
            Contents = 'dsctest';
        }
    }
}

foo -ComputerName dc01,dc02,dc03,dc04,dc05;

Start-DscConfiguration -Path .\foo -Wait -ErrorAction SilentlyContinue -ErrorVariable DscErrors;

$FailedList = ($DscErrors.OriginInfo.PSComputerName | Sort-Object) -join ', ';
Write-Host -ForegroundColor Red -Object ('The following systems failed to process: {0}' -f $FailedList);

在我的实验室环境中输出的内容如下:

DSC Screenshot