Summary: Learn how to use Windows PowerShell to automate troubleshooting of Windows 7 and Windows Server 2008 R2.

Hey, Scripting Guy! Question

  Hey, Scripting Guy! I need to be able to perform troubleshooting tasks on my Windows 7 desktop computer, but I do not want to sit and answer a bunch of questions. I was intrigued by yesterday’s blog post about using the troubleshooting packs and Windows PowerShell, but it seems like it is an interactive process. Can it be automated?

—DR

Hey, Scripting Guy! Answer Hello DR,

Microsoft Scripting Guy, Ed Wilson, here. This week has certainly started out with a bang. I have spent a lot of time working with guest bloggers and getting their blog posts ready for next week’s Guest Blogger Week. I am really psyched because of the quality, diversity, and downright ingenuity of the posts. If that is not enough, I have had several good meetings about the 2011 Scripting Games, and I am practically bursting with excitement over this event. Things are certainly shifting from way cool to hyper-cool, and the overall effect is nearly more than one scripting guy can handle. With so much scripting goodness, it is hard to settle down and focus on one thing (it is sort of like walking into an ice-cream store that offers hundreds of different combinations—it makes it hard to choose).

DR, thanks for bringing me back to reality. The troubleshooting packs in Windows 7 and Windows Server 2008 R2 are cool, and they offer a great way to automate troubleshooting scenarios. As I discussed in yesterday’s article, the first thing to do is see which troubleshooting packs are available on your specific platform. This is a requirement because different roles, features, and software may install their own troubleshooting packs.

NOTE: This is the second in a series of four articles that discuss using Windows PowerShell and the Troubleshooting Module to automate troubleshooting of Windows. In the first article I talked about finding the troubleshooting module, and the troubleshooting packs.  On Wednesday I discuss using the troubleshooting packs to diagnose remote problems, and on Thursday I talk about using PowerShell and Scheduled Tasks to automate troubleshooting.

The troubleshooting packs install by default into the %systemroot%\Diagnostics\System folder; and therefore, the Get-ChildItem cmdlet lists the available packs. By piping the results of the Get-ChildItem (gci is the alias) to the ForEach-Object cmdlet (% is the alias), I can use the Get-TroubleShootingPack cmdlet to revealing specific information about each of the troubleshooting packs. The FullName property from the DirectoryInfo object contains not only the directory name, but also the complete path to the directory.

The Get-TroubleShootingPack cmdlet returns an instance of the DiagPack .NET Framework class. The DiagPack class resides in the Microsoft.Windows.Diagnosis namespace. The Windows Troubleshooting Platform is documented on MSDN, but most of the information that is required to use the cmdlets is easily obtained via the Get-Member, Get-Help, and Get-Command cmdlets. For example, the members of the DiagPack class are obtained via the Get-Member cmdlet (gm is the alias) as shown here.

PS C:\> Get-TroubleshootingPack C:\Windows\diagnostics\system\Audio | gm

TypeName: Microsoft.Windows.Diagnosis.DiagPack

Name MemberType Definition

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

Cancel Method System.Void Cancel()

CopyResults Method System.Void CopyResults(string destinationDirectoryP...

Diagnose Method System.Void Diagnose()

Equals Method bool Equals(Microsoft.Windows.Diagnosis.DiagPack oth...

GetHashCode Method int GetHashCode()

GetType Method type GetType()

Resolve Method System.Void Resolve(Microsoft.Windows.Diagnosis.Diag...

ToString Method string ToString()

Verify Method System.Void Verify()

Description Property System.String Description {get;}

ExtensionPoint Property System.Xml.XmlDocument ExtensionPoint {get;}

FoundRootCauses Property Microsoft.Windows.Diagnosis.DiagRootCause[] FoundRoo...

Id Property System.String Id {get;}

Interactions Property Microsoft.Windows.Diagnosis.DiagInteraction[] Intera...

Interactive Property System.Boolean Interactive {get;}

MinimumVersion Property System.String MinimumVersion {get;}

Name Property System.String Name {get;}

Path Property System.String Path {get;}

PrivacyLink Property System.String PrivacyLink {get;}

Publisher Property System.String Publisher {get;}

RequiresElevation Property System.Boolean RequiresElevation {get;}

RootCauses Property Microsoft.Windows.Diagnosis.DiagRootCause[] RootCaus...

SupportsAmd64 Property System.Boolean SupportsAmd64 {get;}

SupportsClient Property System.Boolean SupportsClient {get;}

SupportsIA64 Property System.Boolean SupportsIA64 {get;}

SupportsServer Property System.Boolean SupportsServer {get;}

SupportsX86 Property System.Boolean SupportsX86 {get;}

Version Property System.String Version {get;}

The properties that I am interested in examining from each of the troubleshooting packs (instances of the DiagPack class) are: the name of the troubleshooting pack, if it requires elevated privileges (run with administrative permissions), and is it interactive (or does it run in the background). Armed with all this information, I pipe the results of the Get-TroubleShootingPack cmdlet to the Format-Table (ft is the alias), and I choose the name RequiresElevation and the Interactive properties. In addition, I tighten the free space between the columns by using the AutoSize switched parameter. The resulting command and the associated output are shown here (keep in mind that this is a single logical command that wraps to multiple lines in my Windows PowerShell console. Depending on the column width setting of your Windows PowerShell console, it might fit on a single line.) I ran this command in a regular Windows PowerShell console, and not one that was elevated.

PS C:\> gci C:\Windows\diagnostics\system | % { Get-TroubleshootingPack $_.fullname}

| ft name, RequiresElevation, Interactive -AutoSize

Name RequiresElevation Interactive

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

Aero True True

Sound True True

Hardware and Devices True True

Devices and Printers True True

HomeGroup True True

Windows Network Diagnostics True True

Program Compatibility True True

Performance True True

Power True True

Printer True True

Search and Indexing True True

Windows Media Player Settings True True

Windows Media Player Library True True

Windows Media Player DVD True True

Windows Update True True

PS C:\>

As I can see in the previous output, all of the troubleshooting packs on my local Windows 7 computer require elevation, and they run in an interactive fashion. Therefore, further work with the troubleshooting packs will require me to start a new instance of the Windows PowerShell console (I am using the Windows PowerShell console, but it is perfectly permissible to use the Windows PowerShell ISE to perform these operations. You need to run the Windows PowerShell ISE as an Administrator if you want to use that tool.)

If I want to see what questions the troubleshooting pack will ask (for interactions), I can select and expand the Interactions property. This is shown here for the Audio Troubleshooting Pack.

PS C:\> Get-TroubleshootingPack C:\Windows\diagnostics\system\Audio | select -ExpandP

roperty interactions

WARNING: 2 columns do not fit into the display and were removed.

Prompt

------

Which of these devices do you want to troubleshoot?

Which of these devices do you want to troubleshoot?

This troubleshooter can't run in a Remote Desktop session

Increase audio device volume

Increase audio device volume

PS C:\>

Interestingly, the output appears a bit strange—each question is repeated, and it says that two columns are missing. I pipe the output from the previous command to the Format-List cmdlet, and I can easily see what was missing from the previous output. The results are shown here.

Image of output information

As can be seen in the previous output, the seemingly duplicate questions are actually the same question asked on different occasions (note the different ID values).

DR, your specific question is how to get around the interaction of the troubleshooter. The answer is to create an answer file. The Get-TroubleShootingPack cmdlet has a AnswerFile parameter that allows one to run through the troubleshooting pack and record the answers in an XML file for later use with the Invoke-TroubleShootingPack cmdlet.

The command to run the Audio Troubleshooting Pack on my computer and to store the answers to the prompts in an XML file in my FSO directory is shown here.

Get-TroubleshootingPack C:\Windows\diagnostics\system\Audio -AnswerFile c:\fso\audio.xml

When this command runs, a dialog box appears that states the answers will be stored in an answer file. After that, the normal questions from the troubleshooting pack appear, and the answers are stored in the specified file. The following screen shot illustrates this process on my computer.

Image of dialog box

The following image shows the XML file that generates from the previous process as a standard formatted file in the XML Notepad. Direct editing of this file is neither encouraged nor supported. The use of the AnswerFile parameter from Get-TroubleShootingPack is the supported method to create these answer files.

Image of XML file

To use the answer file, I supply the path to the AnswerFile parameter of the Invoke-TroubleShootingPack cmdlet as shown here.

Get-TroubleshootingPack C:\Windows\diagnostics\system\Audio |

Invoke-TroubleshootingPack -AnswerFile C:\fso\audio.xml

When this command runs, the output in the following image appears (luckily I have no problems with the audio on my computer). The cool thing is that no prompts appear, and the command runs in an automated fashion.

Image of output information

Because the troubleshooting is now automated, it can run unattended. For example, I could easily create a script that imports the troubleshooting module, and runs the requisite troubleshooter, and logs the results to a file. This could actually be scheduled and run in a proactive fashion.

DR, that is all there is to automating the troubleshooting packs. Troubleshooting Week will continue tomorrow when I will talk about using Windows PowerShell and the Troubleshooting module to diagnose remote problems.

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