programing

PowerShell DSC - 구성 매개 변수를 ScriptResources에 전달하는 방법은 무엇입니까?

oldcodes 2023. 8. 12. 10:40
반응형

PowerShell DSC - 구성 매개 변수를 ScriptResources에 전달하는 방법은 무엇입니까?

PowerShell 원하는 상태 구성 스크립트를 사용하여 사내 애플리케이션을 구성하는 데 많은 문제가 있습니다.문제의 근본 원인은 구성 데이터를 ScriptResource에 전달할 수 없다는 것입니다(적어도 내가 시도하는 방식으로는 그렇지 않습니다).

내 스크립트는 사내 응용프로그램에 대한 구성 폴더를 생성한 다음 다음 일부 설정을 파일에 기록해야 합니다.

configuration MyApp {
    param (
        [string[]] $ComputerName = $env:ComputerName
    )
    node $ComputerName {

        File ConfigurationFolder {
            Type = "Directory"
            DestinationPath = $Node.ConfigFolder
            Ensure = "Present"
        }

        Script ConfigurationFile {
            SetScript = {
                write-verbose "running ConfigurationFile.SetScript";
                write-verbose "folder = $($Node.ConfigFolder)";
                write-verbose "filename = $($Node.ConfigFile)";
                [System.IO.File]::WriteAllText($Node.ConfigFile, "enabled=" + $Node.Enabled);
            }
            TestScript = {
                write-verbose "running ConfigurationFile.TestScript";
                write-verbose "folder = $($Node.ConfigFolder)";
                write-verbose "filename = $($Node.ConfigFile)";
                return (Test-Path $Node.ConfigFile);
            }
            GetScript = { @{Configured = (Test-Path $Node.ConfigFile)} }         
            DependsOn = "[File]ConfigurationFolder"
        }

    }
}

참고로, 내 구성 데이터는 다음과 같습니다.

$config = @{
    AllNodes = @(
        @{
            NodeName = "*"
            ConfigFolder = "C:\myapp\config"
            ConfigFile = "C:\myapp\config\config.txt"
        }
        @{
            NodeName = "ServerA"
            Enabled = "true"
        }
        @{
            NodeName = "ServerB"
            Enabled = "false"
        }
    )
}

그리고 다음과 같은 DSC를 적용하고 있습니다.

$mof = MyApp -ConfigurationData $config;
Start-DscConfiguration MyApp –Wait –Verbose;

이 구성을 적용하면 폴더가 생성되지만 구성 파일에 대한 작업은 수행하지 못합니다.아래 출력을 보면, $Node 변수가 ConfigurationFile/TestScript 범위 내에서 null이기 때문인 것은 분명하지만, 해당 블록 내에서 어떻게 참조해야 할지 모르겠습니다.

LCM:  [ Start  Resource ]  [[Script]ConfigurationFile]
LCM:  [ Start  Test     ]  [[Script]ConfigurationFile]
                           [[Script]ConfigurationFile] running ConfigurationFile.TestScript
                           [[Script]ConfigurationFile] node is null = True
                           [[Script]ConfigurationFile] folder =
                           [[Script]ConfigurationFile] filename =
LCM:  [ End    Test     ]  [[Script]ConfigurationFile]  in 0.4850 seconds.

온라인에서 이 특정 문제를 검색하느라 하루 종일 시간을 허비했지만 변수, 매개 변수 및 구성 데이터의 모든 예는 파일 및 레지스트리 리소스 또는 기타 스크립트가 아닌 리소스를 사용합니다. 이 리소스는 이미 스크립트의 "구성 폴더" 블록에서 작업했습니다.내 "구성 파일"과 같은 스크립트 리소스 내에서 구성 데이터를 참조하는 방법이 중요합니다.

제가 빈칸을 작성했으니 도움을 주시면 감사하겠습니다.그렇지 않으면 서버별로 별도의 "구성" 스크립트를 작성하고 값을 하드 코딩해야 할 수도 있습니다. 가능하면 이 작업을 수행하고 싶지 않습니다.

건배.

마이크

변경 내용:$Node.ConfigFolder로.$using:Node.ConfigFolder.

다음과 같은 변수가 있는 경우$Foo스크립트 DSC 리소스로 전달하고 싶은 경우$using:Foo

David의 답변을 바탕으로, 저는 제 스크립트 블록을 문자열로 변환한 다음 매우 단순한 검색을 수행하고 다음과 같이 구성 데이터에 대한 참조를 확장하는 유틸리티 함수를 작성했습니다.

function Format-DscScriptBlock()
{
    param(
        [parameter(Mandatory=$true)]
        [System.Collections.Hashtable] $node,
        [parameter(Mandatory=$true)]
        [System.Management.Automation.ScriptBlock] $scriptBlock
    )
    $result = $scriptBlock.ToString();
    foreach( $key in $node.Keys )
    {
        $result = $result.Replace("`$Node.$key", $node[$key]);
    }
    return $result;
}

그러면 내 SetScript는 다음과 같습니다.

SetScript = Format-DscScriptBlock -Node $Node -ScriptBlock {
                write-verbose "running ConfigurationFile.SetScript";
                write-verbose "folder = $Node.ConfigFolder";
                write-verbose "filename = $Node.ConfigFile)";
                [System.IO.File]::WriteAllText("$Node.ConfigFile", "enabled=" + $Node.Enabled);
            }

Format-DscriptBlock은 문자 대체만 수행하기 때문에 구성 데이터에서 따옴표와 이스케이프를 염두에 두어야 하지만, 이것은 제 목적에 충분했습니다.

이 문제를 해결하는 아주 우아한 방법은 일반적인 사람들과 일하는 것입니다.{0}자리 표시자를 적용하여-f운영자는 자리 표시자를 실제 값으로 바꿀 수 있습니다.

표시자가 테이블 또는 for-loop)에는 대괄호를 사용할 수 입니다. 이서의예유단자이다항표른외목의또시리(-loop의 경우: 는: 해블테이시메)이기 때문입니다.에는 곱슬곱슬한 대괄호 {}을(를) 사용할 수 없다는 것입니다.-f연산자를 사용하려면 대괄호에 정수를 포함해야 합니다.

그러면 코드는 다음과 같습니다.

        SetScript = ({ 
            Set-ItemProperty "IIS:\AppPools\{0}" "managedRuntimeVersion" "v4.0"
            Set-ItemProperty "IIS:\AppPools\{0}" "managedPipelineMode" 1 # 0 = Integrated, 1 = Classic
        } -f @($ApplicationPoolName))

또한 생성된 .mo 파일을 텍스트 편집기로 보기만 하면 됩니다. 생성된 TestScript / GetScript / SetScript 구성원을 보면 코드 조각이 실제로 문자열임을 알 수 있습니다.$placeholder 값은 이미 해당 값으로 대체되어 있어야 합니다.

구성데이터는 MOF 파일이 컴파일될 때만 존재하며 DSC 엔진이 스크립트를 적용하는 런타임에는 존재하지 않습니다.스크립트 리소스의 SetScript, GetScript 및 TestScript 특성은 실제로 스크립트 블록이 아닌 문자열입니다.

구성 데이터의 모든 필수 데이터를 이미 확장한 상태에서 이러한 스크립트 문자열을 생성할 수 있지만 이스케이프, 하위 표현식 및 따옴표를 올바르게 사용하려면 주의해야 합니다.

저는 http://social.technet.microsoft.com/Forums/en-US/2eb97d67-f1fb-4857-8840-de9c4cb9cae0/dsc-configuration-data-for-script-resources?forum=winserverpowershell 의 원래 TechNet 스레드에 이 문제에 대한 간단한 예를 게시했습니다.

언급URL : https://stackoverflow.com/questions/23346901/powershell-dsc-how-to-pass-configuration-parameters-to-scriptresources

반응형