3

当零个计算机节点与过滤条件匹配时,我遇到了一个问题,将过滤器应用于 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

到目前为止,我提出的最佳解决方案是将每个节点包装在一个“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"
            }
        }
    }
}

但这感觉有点像 hack,并且用很多杂物填充我的配置块。当有零个节点与过滤器匹配时,是否有更简洁的方法来避免此错误?

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

4

2 回答 2

2

最后,我决定在具有过滤器的节点周围添加检查。当有很多不同的过滤器时,它有点笨拙且非常重复,但至少它使解决方法接近问题所在,如果你眯着眼睛看与原始代码并没有太大不同。

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

}
于 2014-07-06T12:18:33.457 回答
0

-ErrorAction SilentlyContinueand添加-ErrorVariable DscErrors到您的通话中Start-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 截图

于 2014-07-03T14:21:59.193 回答