2014-04-28 6 views
23

मुझे एक इन-हाउस एप्लिकेशन को कॉन्फ़िगर करने के लिए काम कर रहे पावरशेल वांछित राज्य कॉन्फ़िगरेशन स्क्रिप्ट प्राप्त करने का प्रयास करने में बहुत परेशानी हो रही है। समस्या की जड़ यह है कि मैं अपने कॉन्फ़िगरेशन डेटा को स्क्रिप्ट संसाधन में पास नहीं कर सकता (कम से कम जिस तरह से मैं इसे करने की कोशिश कर रहा हूं)।पावरशेल डीएससी - स्क्रिप्ट संसाधनों में कॉन्फ़िगरेशन पैरामीटर कैसे पास करें?

मेरे स्क्रिप्ट एक फ़ाइल में हमारे घर में आवेदन के लिए एक 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" 
     } 
    ) 
} 

और मैं साथ डीएससी को लागू करने कर रहा हूँ निम्नलिखित:

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

जब मैं लागू यह कॉन्फ़िगरेशन यह खुशी से फ़ोल्डर बनाता है, लेकिन कॉन्फ़िगरेशन फ़ाइल के साथ कुछ भी करने में विफल रहता है। नीचे दिए गए आउटपुट को देखते हुए, यह स्पष्ट है कि ऐसा इसलिए है क्योंकि $ Node चर कॉन्फ़िगरेशनफ़ाइल/टेस्टस्क्रिप्ट के दायरे में शून्य है, लेकिन मुझे नहीं पता कि उस ब्लॉक के भीतर से इसका संदर्भ कैसे दिया जाए।

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. 

मैं इस विशिष्ट समस्या के लिए ऑनलाइन खोज एक पूरे दिन बंद जला दिया गया है, लेकिन सभी चर, मापदंडों और विन्यास डेटा सभी उपयोग फ़ाइल और रजिस्ट्री संसाधन या अन्य गैर-स्क्रिप्ट संसाधनों का उदाहरण है, जो मैंने पहले से ही मेरी स्क्रिप्ट में "कॉन्फ़िगरेशनफोल्डर" ब्लॉक में काम कर रहा है। जिस चीज़ पर मैं फंस गया हूं वह है कि मेरे "कॉन्फ़िगरेशनफ़ाइल" जैसे स्क्रिप्ट संसाधन के भीतर कॉन्फ़िगरेशन डेटा का संदर्भ कैसे लें।

मैंने एक पूर्ण खाली खींचा है ताकि किसी भी मदद की सराहना की जा सके। यदि सब कुछ विफल हो जाता है तो मुझे प्रति सर्वर एक अलग "कॉन्फ़िगरेशन" स्क्रिप्ट बनाना और मूल्यों को हार्ड-कोड बनाना पड़ सकता है, जिसे मैं वास्तव में नहीं करना चाहता हूं।

चीयर्स,

माइक

उत्तर

6

ConfigurationData केवल समय MOF फ़ाइलों संकलित किए जाते हैं पर मौजूद है, नहीं रनटाइम पर जब डीएससी इंजन अपनी स्क्रिप्ट लागू होता है। स्क्रिप्ट संसाधन के सेटस्क्रिप्ट, गेटस्क्रिप्ट और टेस्टस्क्रिप्ट विशेषताओं वास्तव में स्ट्रिंग ब्लॉक नहीं हैं, स्क्रिप्ट ब्लॉक हैं।

उन स्क्रिप्ट तारों को उत्पन्न करना संभव है (आपके कॉन्फ़िगरेशनडेटा से पहले से आवश्यक डेटा के साथ सभी आवश्यक डेटा के साथ), लेकिन आपको escapes, subexpressions और उद्धरण चिह्नों का सही उपयोग करने के लिए सावधान रहना होगा।

मैं http://social.technet.microsoft.com/Forums/en-US/2eb97d67-f1fb-4857-8840-de9c4cb9cae0/dsc-configuration-data-for-script-resources?forum=winserverpowershell

10

डेविड के जवाब के आधार पर पर मूल TechNet धागे पर इस पर एक संक्षिप्त उदाहरण पोस्ट, मैं एक उपयोगिता समारोह जो एक स्ट्रिंग के लिए अपनी स्क्रिप्ट ब्लॉक धर्मान्तरित लिखा है और उसके बाद एक बहुत भोली खोज करता है और निम्नानुसार कॉन्फ़िगरेशन डेटा के संदर्भों का विस्तार करने के लिए प्रतिस्थापित करें।

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

आप उद्धरण के प्रति जागरूक होना चाहिए और आपके विन्यास डेटा में निकल जाता है क्योंकि प्रारूप-DscScriptBlock केवल शाब्दिक प्रतिस्थापन करता है, लेकिन यह मेरी प्रयोजनों के लिए काफी अच्छा था।

6

इस समस्या को हल करने का एक बहुत ही शानदार तरीका नियमित {0} प्लेसहोल्डर्स के साथ काम करना है। -f ऑपरेटर को लागू करके प्लेसहोल्डर्स को उनके वास्तविक मानों से बदला जा सकता है।

इस विधि के साथ एकमात्र नकारात्मक पक्ष यह है कि आप प्लेसहोल्डर्स के अलावा किसी भी चीज़ के लिए घुंघराले ब्रेसिज़ {} का उपयोग नहीं कर सकते हैं (यानी हैशटेबल या फॉर-लूप कहें), क्योंकि -f ऑपरेटर को ब्रेसिज़ को पूर्णांक रखने की आवश्यकता होती है।

आपका कोड तो इस तरह दिखता है:

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

इसके अलावा, पता लगाने के लिए अगर आप बस एक पाठ संपादक के साथ फ़ाइल .mof उत्पन्न देखने से सही है यह कर रहे हैं एक अच्छा तरीका है; यदि आप जेनरेट किए गए टेस्टस्क्रिप्ट/गेटस्क्रिप्ट/सेटस्क्रिप्ट सदस्यों को देखते हैं, तो आप देखेंगे कि कोड खंड वास्तव में एक स्ट्रिंग है। $ प्लेसहोल्डर मानों को पहले से ही बदल दिया जाना चाहिए था।

+3

वास्तव में उपयोग करते हैं, आप घुंघराले ब्रेसिज़ उपयोग कर सकते हैं, तो आप सिर्फ उन्हें दोगुना करने के लिए (ताकि '{' हो जाता है की जरूरत है '{{' और '}' '}}}')। – BartekB

27

इसे बदलें: $Node.ConfigFolder से $using:Node.ConfigFolder

आप एक चर $Foo कहा जाता है और आप चाहते हैं यह एक स्क्रिप्ट डीएससी संसाधन को पास करने की है, तो $using:Foo

+2

लेकिन ** बिंदु ** इसे $() में रखना है: '$ ($ का उपयोग: नोड.कॉन्फिफ़फोल्डर)' –

+4

यह _should_ आपके लिए इस समस्या को हल करने के लिए सही उत्तर '$ उपयोग' प्रदान किया गया है, नहीं तारों को स्वयं उत्पन्न करने की आवश्यकता है ... उदाहरण के लिए https://msdn.microsoft.com/en-us/powershell/dsc/scriptResource देखें। –

संबंधित मुद्दे