2014-04-28 2 views
23

사내 응용 프로그램을 구성하기 위해 작동하는 PowerShell Desired State Configuration 스크립트를 가져 오는 데 많은 어려움을 겪고 있습니다. 문제의 근본 원인은 내 구성 데이터를 ScriptResource로 전달할 수 없다는 것입니다 (최소한 내가하려는 방식이 아님).PowerShell DSC - 구성 매개 변수를 ScriptResources에 전달하는 방법?

내 스크립트 파일에 일부 설정을 우리의 사내 응용 프로그램에 대한 config 폴더를 만든 다음 쓰기로되어있다 : 참고로

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. 

나는이 특정 문제에 대한 온라인 검색 전체 하루를 타 봤지만 내가했습니다 변수, 매개 변수 및 구성 데이터를 모두 사용하여 파일 및 레지스트리 자원 또는 기타 스크립트 자원의 모든 예제, 내 스크립트의 "ConfigurationFolder"블록에서 이미 작업하고 있습니다. 내가 붙어있는 것은 내 "ConfigurationFile"과 같은 스크립트 리소스 내에서 구성 데이터를 참조하는 방법입니다.

나는 모든 도움을 주시면 감사하겠습니다. 다른 모든 것이 실패 할 경우 서버마다 별도의 "구성"스크립트를 만들고 하드 코드로 값을 설정해야 할 수도 있습니다. 가능한 경우 수행하고 싶지 않습니다.

건배,

마이크

ConfigurationData 만 MOF 파일은 컴파일 시간에 존재

답변

6

아닌 DSC 엔진이 스크립트를 적용 할 때 런타임시. Script 리소스의 SetScript, GetScript 및 TestScript 특성은 실제로 스크립트 블록이 아닌 문자열입니다.

(이미 확장 된 ConfigurationData의 모든 필수 데이터를 사용하여) 이러한 스크립트 문자열을 생성 할 수는 있지만 이스케이프, 하위 표현식 및 따옴표는 올바르게 사용해야합니다.

내가 다윗의 답변에 따라 http://social.technet.microsoft.com/Forums/en-US/2eb97d67-f1fb-4857-8840-de9c4cb9cae0/dsc-configuration-data-for-script-resources?forum=winserverpowershell

10

에서 원래 TechNet의 스레드에서이 이상에 대한 간단한 예를 게시, 나는 문자열로 내 스크립트 블록을 변환하는 유틸리티 함수를 작성하고 매우 순진 검색을 수행 한 다음과 같이 구성 데이터에 대한 참조를 확장하려면 대체하십시오. 당신은 따옴표 염두해야

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); 
      } 

및 형식-DscScriptBlock는 문자 대체를 수행하기 때문에 구성 데이터에서 탈출,하지만 내 목적을 위해 충분했다 :

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는된다.

6

이 문제를 해결하는 매우 우아한 방법은 일반 {0} 자리 표시자를 사용하는 것입니다. -f 연산자를 적용하면 자리 표시자를 실제 값으로 바꿀 수 있습니다.

-f 연산자에 중괄호에 정수가 있어야하기 때문에이 방법의 유일한 단점은 자리 표시 자 이외의 것에 중괄호 {}를 사용할 수 없다는 것입니다 (즉, 해시 테이블 또는 for 루프).

귀하의 코드는 다음과 같습니다 또한

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

, 당신은 단순히 텍스트 편집기로 .mof 파일 생성 보면 맞다 그 일을하고 있는지 확인하는 좋은 방법; 생성 된 TestScript/GetScript/SetScript 멤버를 보면 코드 조각이 실제로 문자열이라는 것을 알 수 있습니다. $ 자리 표시 자 값이 이미 여기에 대체되었습니다.

+3

사용, 스크립트 DSC 리소스에 전달하려는 경우

, 당신은 중괄호를 사용할 수 있습니다, 당신은 너무'{ '가된다 (을 두 배로 필요 '{{'와'}'는'}}'이됩니다. – BartekB

27

변경 : $Node.ConfigFolder to $using:Node.ConfigFolder. 당신이 변수가 $Foo라고하고 그 다음 실제로 $using:Foo

+2

** ** 요점은 ** $()와 같이 쓰는 것입니다 :'$ ($ using : Node.ConfigFolder)' –

+4

이것은 올바른 답이 될 것입니다.이 문제를 해결하기 위해'$ using'이 제공됩니다. 직접 문자열을 생성해야합니다. 예를 보려면 https://msdn.microsoft.com/en-us/powershell/dsc/scriptResource를 참조하십시오. –

관련 문제