Script Block properties in DSC resources

Here’s a little-known feature of Desired State Configuration. First, notice that the Script resource’s properties are all strings, not ScriptBlocks, in its schema:

Get-DscResource Script -Syntax

<#
Script [String] #ResourceName
{
    GetScript = [string]
    SetScript = [string]
    TestScript = [string]
    [Credential = [PSCredential]]
    [DependsOn = [string[]]]
}
#>

However, even though they’re strings in the MOF file, PowerShell will allow you to assign ScriptBlock objects to those properties in your configuration function. Also, if you do this, it will automatically handle $using: scoped variables, serializing them to XML and injecting them into your MOF file. (This is very similar to how PowerShell Remoting works when you use the $using: scope modifier.)

configuration ScriptTest {
    node localhost {
       $MyHashtable = @{
           Key1 = 'This was created'
           Key2 = 'on the machine where the MOF was compiled'
       }
       Script test {
           GetScript = {$using:MyHashtable}
           TestScript = {$true}
           SetScript = { }
       }
    }
}

ScriptTest -OutputPath $env:temp\ScriptTest

<#
localhost.mof snippet, line breaks added by me for readability

 GetScript = "$MyHashtable = [System.Management.Automation.PSSerializer]::Deserialize('<Objs Version=\"1.1.0.1\" xmlns=\"http://schemas.microsoft.com/powershell/2004/04\">
\n  <Obj RefId=\"0\">
\n    <TN RefId=\"0\">
\n      <T>System.Collections.Hashtable</T>
\n      <T>System.Object</T>
\n    </TN>
\n    <DCT>
\n      <En>
\n        <S N=\"Key\">Key1</S>
\n        <S N=\"Value\">This was created</S>
\n      </En>
\n      <En>
\n        <S N=\"Key\">Key2</S>
\n        <S N=\"Value\">on the machine where the MOF was compiled</S>
\n      </En>
\n    </DCT>
\n  </Obj>
\n</Objs>')
\n$MyHashtable";
#>

The cool thing is, this script block serialization feature may exist because of the Script resource, but it’s actually usable by any DSC resource that wants to accept executable code as a parameter. Just define your resource’s property as a String in your schema and *-TargetResource methods, and assign a ScriptBlock object to that property in your configuration script. When DSC compiles the configuration to a MOF, it will take care of the serialization and conversion to string for you. (In your resource’s methods, you’ll need to convert the string back into a ScriptBlock object by using the [scriptblock]::Create() method.)

Advertisements

About Dave Wyatt

Microsoft MVP (PowerShell), IT professional.
This entry was posted in PowerShell and tagged . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s