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

Лучшее решение, которое я придумал до сих пор, - это обернуть каждый узел в "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"
            }
        }
    }
}

но это похоже на взлом и заполняет мои блоки конфигурации большим количеством хлама. Есть ли более чистый способ избежать этой ошибки, когда нет узлов, соответствующих фильтру?

(Для контекста я создаю несколько сред разработки, тестирования и uat, где мы только развертываем частичные наборы ролей сервера в каждой среде, поэтому я не хочу менять логику выражения фильтра Node или удалять узлы из Блок конфигурации, потому что они необходимы в производстве, и я хочу использовать одни и те же сценарии везде).


person mclayton    schedule 03.07.2014    source источник


Ответы (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"
            }
        }
    }

}
person mclayton    schedule 06.07.2014

Как насчет добавления -ErrorAction SilentlyContinue и -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

person Trevor Sullivan    schedule 03.07.2014
comment
К сожалению, похоже, что ошибка DSC имеет приоритет над SilentlyContinue. Если я заменю узел $ComputerName { на узел $AllNodes.Where{ $_.Role -eq db }.NodeName { в вашем примере он по-прежнему выдает ошибку «имя конечного узла пусто», а не записывает его в переменную ошибки :-(. - person mclayton; 04.07.2014