Tuesday, October 28, 2014

Handling Reboots in a DSC Configuration

When automating a server configuration you’ll eventually run into the scenario where a reboot is required before a component can be installed.  In Desired State Configuration this can be handled with the xPendingReboot PowerShell Module (from the DSC Resource Kit).  Ed Wilson did a nice write-up of this, including some of the pre-reqs here: Use PowerShell DSC to Check Pending Reboot.  

I had to make a couple of changes to his sample before really shooting myself in the foot.  Turns out the first thing DSC does after rebooting is resume the configuration, which in my simplified demo case just told the LCM to go ahead and reboot again.  It took me a while to break that reboot loop (nice one, doofus).

In the sample below I have used Start-Sleep to give you a fighting chance to stop the cycle of reboots Winking smile.  The sample below WILL reboot your server, so don’t do it to your friends or users.

configuration Reboots

{

    # Get this from TechNet Gallery

    Import-DsCResource -ModuleName xPendingReboot

 

    node (hostname)

    {     

        LocalConfigurationManager

        {

            # This is false by default

            RebootNodeIfNeeded = 'true'

        }

       

        Script TestReboot

        {

            GetScript  = { return 'foo'}

            TestScript = { return $false}

            SetScript  = {

                # Insert a delay before the reboot, otherwise the machine will be stuck in a reboot cycle

                Start-Sleep -Seconds (5*60)

 

                # Setting the global:DSCMachineStatus = 1 tells DSC that a reboot is required

                $global:DSCMachineStatus = 1

            }

        }

 

        # Reboot if pending

        xPendingReboot RebootCheck1

        {

            Name = "RebootCheck1"

        }

 

    }

}

 

Set-Location c:\temp

 

Reboots

 

Set-DscLocalConfigurationManager -Path .\Reboots -Verbose

 

Start-DscConfiguration -Verbose -wait -Path .\Reboots -Force

 

 

Thursday, October 23, 2014

Desired State Configuration for FIM

Last week I was honoured to present at the FIM User Group, talking about Desired State Configuration for FIM.

The presentation was recorded, and is available thanks to Unify Solutions here:

2014-10-15 Desired State Configuration for FIM

Wednesday, October 22, 2014

Creating a Demo Custom DSC Resource

When creating custom DSC resources sometimes it is handy to isolate an issue into a fresh DSC resource, or simply to experiment quickly without impacting existing progress.

The script below will create a demo DSC resource really quickly, allowing you to put content into the script and test it right away.

I’ve been using this to test something quickly then just throw it away, almost like snippets in PowerShell ISE.

 

### Demo DSC Custom Resource details

$demoModuleName  = 'DemoModule'

$dscResourceName = 'DemoDscCustomResource'

 

### Create the new resource

New-xDscResource -Name $dscResourceName -Path "C:\Program Files\WindowsPowerShell\Modules\$demoModuleName" -Property @(

    New-xDscResourceProperty -Name Prop1  -Type String    -Attribute Key

    New-xDscResourceProperty -Name Prop2  -Type String    -Attribute Write

    New-xDscResourceProperty -Name Ensure -Type String    -Attribute Write -ValidateSet "Present", "Absent"

)

 

### Convert the generated files to UTF8

@(

"C:\Program Files\WindowsPowerShell\Modules\$demoModuleName\DSCResources\$dscResourceName\$dscResourceName.schema.mof"

"C:\Program Files\WindowsPowerShell\Modules\$demoModuleName\DSCResources\$dscResourceName\$dscResourceName.psm1"

) | ForEach-Object {

    $fileContent = Get-Content $_

    Set-Content -Value $fileContent -Path $_ -Encoding UTF8

}

 

### Create an empty PSM1 file for the new module

Set-Content -Value "### Test File" -Path "C:\Program Files\WindowsPowerShell\Modules\$demoModuleName\$demoModuleName.psm1" -Encoding UTF8

 

### Modify the new DSC custom resource module

psedit  "C:\Program Files\WindowsPowerShell\Modules\$demoModuleName\DSCResources\$dscResourceName\$dscResourceName.psm1"

 

### Generate a simple test script

@'

Set-Location $HOME

 

Configuration Test{0}

{{

 

    Import-DscResource -ModuleName {1}

 

    Node (hostname)

    {{

        {0} Test{0}

        {{

            Prop1   = 'foo'

            Prop2   = 'bar'

            Ensure  = 'Present'

        }}

    }}

}}

 

Test{0}

 

Start-DscConfiguration -Wait -Verbose -Debug -Path (Join-Path $Home TestDemoDscCustomResource)

 

'@ -F $dscResourceName, $demoModuleName  |

Out-File -Encoding utf8 -FilePath "C:\Program Files\WindowsPowerShell\Modules\$demoModuleName\Test-$dscResourceName.ps1"

 

### Open the new test script

psedit  "C:\Program Files\WindowsPowerShell\Modules\$demoModuleName\Test-$dscResourceName.ps1"

 

Wednesday, October 15, 2014

XML Diff in PowerShell

Microsoft released a tool over a decade ago that is proving quite useful in my current work with loads of XML.

The tool can be loaded in PowerShell using Add-Type then used quite simply.  Below are some very simple examples.  There are more sophisticated ways to use the tool but for now I’m just showing how to do simple comparisons resulting in TRUE or FALSE.

This is proving very useful for diffing FIM Synchronization configuration files, which have megabytes of interesting detail in XML.

 

### Get it here: http://msdn.microsoft.com/en-us/library/aa302294.aspx

Add-Type -Path xmldiffpatch.dll

 

### Create the XmlDiff object

$xmlDiff = New-Object Microsoft.XmlDiffPatch.XmlDiff

 

### Simple compare: expect TRUE

$xmlDiff.Compare([xml]'<foo/>', [xml]'<foo/>')

 

### Same content, different format: expect TRUE

$xmlDiff.Compare([xml]'<foo/>', [xml]'<foo></foo>')

 

### Simple compare: expect FALSE

$xmlDiff.Compare([xml]'<foo/>', [xml]'<bar/>')

 

### Ordering is ignored on attributes: expect TRUE

$xmlDiff.Compare([xml]"<foo a='1' b='2' c='3'/>", [xml]"<foo c='3' b='2' a='1'/>")

 

### Ording is NOT ignored on children: expect TRUE

$xmlDiff.Compare([xml]"<foo><a/><b/><c/></foo>", [xml]"<foo><c/><b/><a/></foo>")

 

### Oh just ignore the children order: expect FALSE

$xmlDiff = New-Object Microsoft.XmlDiffPatch.XmlDiff([Microsoft.XmlDiffPatch.XmlDiffOptions]::IgnoreChildOrder)

$xmlDiff.Compare([xml]"<foo><a/><b/><c/></foo>", [xml]"<foo><c/><b/><a/></foo>")

 

 

Seattle Script Club Wednesday, October 29th

The Seattle Script Club is a great way to get people up and running with PowerShell, and a great place to meet other PowerShell enthusiasts. Club meetings are helpful for newbies, experts, and everything in between. They're a wonderful way to learn new things about PowerShell and improve your scripting skills. Oh, and there's free pizza too (courtesy of Edgile, Inc).

We hope to see many familiar faces at Script Club, and meet new scripters in the Seattle area.

The Seattle Script Club is coordinated by James Brundage from Start-Automating, Craig Martin from Edgile, and Andy Schneider from Avanade.

Location

Conference Room 18/1525

Microsoft Building 18

If you do not have building access, contact Craig (craigmartineh on Twitter).

Agenda

4-6PM - Open Scripting Time

6-7PM - Feature Presentation - Cmdlet Design by James Brundage

7-?PM – Open Hangout Time

Open Scripting Time (4-5PM, Conf Room 18/1525)

Bring in your troublesome scripts and get help fixing them. Debug your problems with PowerShell experts. Work on whatever you’d like. Open Scripting Time will occur on Microsoft campus, and will rotate monthly to a Microsoft building close to a group in need. Since Open Scripting Time will be on Microsoft campus, badge access or guest access will be required.

PowerShell Presentation (6-7PM, Conf Room 18/1525)

Each month, we’ll be doing a 1-hour presentation on a topic of interest to Seattle area scripters. This club presentation is on PowerShell Cmdlet design. Each presentation will be followed by extensive Q&A and interesting show and tell by other members of the group.

Hangout (7-?PM, Some Place Nearby TBD)

After your brains have been thoroughly stuffed with PowerShell knowledge, clear your head and chat with your fellow scripters. Each month we’ll be hanging out after Script Club and enjoying the company of our fellow scripters. The first round for new attendees to Script Club is on Start-Automating.