Summary: Microsoft Scripting Guy, Ed Wilson, talks about using the DSC Diagnostics module for troubleshooting Windows PowerShell DSC.

Microsoft Scripting Guy, Ed Wilson, is here. This morning the Scripting Wife and I are on the train to Vienna. We had an absolutely awesome time in Prague. We would have loved to spend our entire time in Prague, but then we would miss out on more cool stuff in other places—such as Vienna. The last time I was in Vienna, I was teaching a Windows PowerShell class at the Microsoft Office, and it has been several years since we have been back to the city where culture meets business.

As a former music major, and opera lover, I am certainly psyched about returning. There are several awesome operas playing this week, and at least one ballet. Teresa is excited about seeing the Lipizzaner horses. At any rate, we leave behind an awesome couple of friends in Prague—we had lots of fun with Windows PowerShell MVP, David Moravec, and his lovely wife Andrea.  

As the high-speed train speeds along the tracks leaving Prague, I have my Zune playing one of my favorite violinists, Vanessa-Mae. Now she is playing a tune called Red Hot, a sort of classical mixture bridge mix, which is just about perfect for working with Windows PowerShell Desired State Configuration (DSC).

     Note  Today is the eighth day in a series of blog posts about Desired State Configuration.

Download the DSC Diagnostics module

The first thing to do is download the xDSCResouceDesigner Module from the Script Center Repository. The module released with the Wave 2 DSC Resource Kit, and it is a free download.

Note  To perform remote diagnostics, the DSC Diagnostics module needs to be installed on the remote machine. Simply copy the unzipped module to the Program files/Windows PowerShell/Modules location.

After I have the module installed, I can use the Get-Command cmdlet to find what cmdlets are exposed by the module. This technique is shown here:

PS C:\> Get-Command -Module xDscDiagnostics

CommandType     Name                                               ModuleName                    

-----------     ----                                               ----------                    

Function        Get-xDscOperation                                  xDscDiagnostics               

Function        Trace-xDscOperation                                xDscDiagnostics  

So, if I want to look at the last two DSC operations, I use the Get-xDscOperation cmdlet and specify 2 for the value of the –newest parameter. This is shown here:

PS C:\> Get-xDscOperation -Newest 2 

ComputerName   SequenceId TimeCreated           Result   JobID                                

All                                                                                              

Eve                                                                                               

nts

------------   ---------- -----------           ------   -----                                 ---

C1             1          3/6/2014 5:34:13 PM   Success  6ab949ca-66be-4167-853c-eeccc87c717d  {@{

C1             2          3/6/2014 5:22:10 PM   Success  953aec3c-80f0-48ee-ba76-2ff7c155a060  {@{

By looking at the time stamps, I can see that the most recent operation would be –Newest 1. I can also pipe the output to the Format-List cmdlet and look at more detail. This is shown here:

PS C:\> Get-xDscOperation -Newest 1 | fl *

SequenceId        : 1

TimeCreated       : 3/6/2014 5:34:13 PM

ComputerName      : C1

Result            : Success

JobID             : 6ab949ca-66be-4167-853c-eeccc87c717d

AllEvents         : {@{Message=Running consistency engine.; TimeCreated=3/6/2014 5:34:12 PM;

                    Event=System.Diagnostics.Eventing.Reader.EventLogRecord; Type=OPERATIONAL},

                    @{Message=Configuration is sent from computer NULL by user sid S-1-5-18.;

                    TimeCreated=3/6/2014 5:34:12 PM;

                    Event=System.Diagnostics.Eventing.Reader.EventLogRecord; Type=OPERATIONAL},

                    @{Message=Consistency engine was run successfully.; TimeCreated=3/6/2014

                    5:34:13 PM; Event=System.Diagnostics.Eventing.Reader.EventLogRecord;

                    Type=OPERATIONAL}}

NumberOfEvents    : 3

AnalyticEvents    : {}

DebugEvents       : {}

NonVerboseEvents  : {System.Diagnostics.Eventing.Reader.EventLogRecord,

                    System.Diagnostics.Eventing.Reader.EventLogRecord,

                    System.Diagnostics.Eventing.Reader.EventLogRecord}

VerboseEvents     : {}

OperationalEvents : {System.Diagnostics.Eventing.Reader.EventLogRecord,

                    System.Diagnostics.Eventing.Reader.EventLogRecord,

                    System.Diagnostics.Eventing.Reader.EventLogRecord}

ErrorEvents       : {}

WarningEvents     : 

The nice thing about the Trace-XDscOperation cmdlet is that it will prompt you to enable the trace logs (which are disabled by default). After they are enabled, I can rerun my DSC configuration and reproduce any errors I was having.

Performing these commands remotely requires that I poke holes in the Windows Firewall, or that I simply use the Invoke-Command cmdlet and rely on remoting, which is already obviously enabled (or I would not be using DSC). I need to specify credentials that are valid on the remote machine, so I store the credentials in a variable called $cred. I then use the Invoke-Command cmdlet to run my commands. This technique is shown here:

PS C:\> $cred = Get-Credential nwtraders\administrator

PS C:\> Invoke-Command -ComputerName s1 -ScriptBlock {Get-xDscOperation -Newest 2}

ComputerName   SequenceId TimeCreated           Result   JobID                                

All                                                                              

Eve                                                                                              

nts

------------   ---------- -----------           ------   -----                                 ---

S1             1          3/5/2014 4:59:21 PM   Success  f7764868-4e2a-409a-b10b-d026a57b52c5  {@{

S1             2          3/5/2014 4:51:27 PM   Success  6b737c28-f199-457c-9db7-047381585c87  {@{

Groovy. The last two operations worked. Now, how about the tracing stuff? I simply use the Up arrow to retrieve my previous Invoke-Command command, and I change the stuff inside the script block. (Lazy I know, but hey, I would rather edit than type anew.) So here is the trace:

PS C:\> Invoke-Command -ComputerName s1 -ScriptBlock {Trace-xDscOperation}

ComputerName   EventType    TimeCreated           Message                  PSComputerName        

------------   ---------    -----------           -------                  --------------        

S1             OPERATIONAL  3/5/2014 4:59:21 PM   Configuration is sent... s1                 

I can see part of the message. So I use the Up arrow again, and I pipe the output to the Format-List cmdlet (fl is an alias that simplifies this technique):

PS C:\> Invoke-Command -ComputerName s1 -ScriptBlock {Trace-xDscOperation} | fl *

PSComputerName     : s1

RunspaceId         : 287d2943-8504-4c07-ac8b-db78edd96e38

PSShowComputerName : True

EventType          : OPERATIONAL

TimeCreated        : 3/5/2014 4:59:21 PM

Message            : Configuration is sent from computer C1 by user sid

                     S-1-5-21-1893272736-1364514926-820579994-500.

ComputerName       : S1

JobID              : f7764868-4e2a-409a-b10b-d026a57b52c5

SequenceID         : 1

Event              : System.Diagnostics.Eventing.Reader.EventLogRecord

This time, it tells me the name of the computer and the SID of the user. I can look up the user SID if I need to, but everything looks like it is going swell, so I will look at the scenery for a while as we zip along the countryside.

Join me tomorrow for more cool Windows PowerShell stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy