ConfigMgr SCCM Easy to Document Task Sequence Documentation

All Credits to Authors – This post was contributed by Aly Shivji, a consultant with Microsoft Services – U.S. East Region. Credit to Michael Murgolo for initial idea and effort.

Task Sequence Documentation Automatically

https://docs.microsoft.com/en-us/archive/blogs/deploymentguys/documenting-your-task-sequences-automagically

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<xsl:stylesheet xmlns:xsl="https://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<HTML>
<HEAD>
<STYLE TYPE="text/css">
TD.group { background-color:teal;color:white } TD.step { background-color:beige }
</STYLE>
</HEAD>
<BODY>
<TABLE border="0" cellpadding="2" cellspacing="0" style="font: 9px arial;border-width:0px;border-spacing:0px;border-style:none" width="100%">
<!--  Header row for Task Sequence  -->
<TR>
<TD style="background-color:black;color:white;">
<B>Group</B>
</TD>
<TD style="background-color:black;color:white;">
<B>Description</B>
</TD>
<TD style="background-color:black;color:white;"/>
<TD style="background-color:black;color:white;">
<B>Conditions</B>
</TD>
<TD style="background-color:black;color:white;"/>
<xsl:for-each select="descendant::group">
<TD style="background-color:black;color:white;"/>
</xsl:for-each>
</TR>
<!--  Parse Each Group  -->
<xsl:for-each select="SmsTaskSequencePackage/SequenceData/sequence//group | sequence//group">
<TR>
<!--
 Indent for parent groups, i.e. add cells for the number of group ancestors 
-->
<xsl:for-each select="ancestor::group">
<TD/>
</xsl:for-each>
<!--  Add the group name and description  -->
<TD Class="group">
<xsl:value-of select="@name"/>
</TD>
<TD Class="group">
<xsl:value-of select="@description"/>
</TD>
<TD Class="group">
<!--  Output the conditions for the group  -->
<xsl:if test="@continueOnError='true'"> continue on error </xsl:if>
<!--  Conditions with preceding operators  -->
<xsl:if test="./condition//operator">
<xsl:for-each select="./condition//operator">
(
<xsl:value-of select="@type"/>
<BR/>
<xsl:value-of select=".//expression//variable[@name='Query']"/>
<xsl:value-of select=".//expression//variable[@name='Variable']"/>
<xsl:value-of select=".//expression//variable[@name='Operator']"/>
<xsl:value-of select=".//expression//variable[@name='Value']"/>
)
</xsl:for-each>
</xsl:if>
<!--  Conditions with no preceding operators  -->
<xsl:if test="not(./condition//operator)">
<xsl:for-each select="./condition//expression">
<xsl:value-of select=".//variable[@name='Query']"/>
<xsl:value-of select=".//variable[@name='Variable']"/>
<BR/>
<xsl:value-of select=".//variable[@name='Operator']"/>
<BR/>
<xsl:value-of select=".//variable[@name='Value']"/>
<BR/>
</xsl:for-each>
</xsl:if>
</TD>
<!--
 Trailing cells for child groups, i.e. add cells for the number of group decendants 
-->
<TD Class="group"/>
<TD Class="group"/>
<TD Class="group"/>
<xsl:for-each select="descendant::group">
<TD Class="group"/>
</xsl:for-each>
</TR>
<!--  Parse Each Task(Step) Display Header  -->
<TR>
<!--
 Indent for parent groups, i.e. add cells for the number of group ancestors 
-->
<xsl:for-each select="ancestor::group">
<TD/>
</xsl:for-each>
<!--  Display header only if a child step exists  -->
<xsl:if test="child::step">
<TD>
<B>Conditions</B>
</TD>
<TD>
<B>Task</B>
</TD>
<TD>
<B>Description</B>
</TD>
<TD>
<B>Package</B>
</TD>
<TD>
<B>Action</B>
</TD>
<TD>
<B>Variables</B>
</TD>
</xsl:if>
</TR>
<!--  Parse Each Task(Step) that is not disabled  -->
<xsl:for-each select="step[not(@disable='true')]">
<TR>
<!--
 Indent for parent groups of parent, i.e. add cells for the number of group ancestors of the parent group 
-->
<xsl:for-each select="parent::group/ancestor::group">
<TD/>
</xsl:for-each>
<!--  Conditions for steps  -->
<TD Class="step">
<xsl:if test="@continueOnError='true'"> continue on error </xsl:if>
<!--  Conditions with  preceding operators  -->
<xsl:if test="./condition//operator">
<xsl:for-each select="./condition//operator">
(
<xsl:value-of select="@type"/>
<BR/>
<xsl:value-of select=".//expression//variable[@name='Query']"/>
<xsl:value-of select=".//expression//variable[@name='Variable']"/>
<xsl:value-of select=".//expression//variable[@name='Operator']"/>
<xsl:value-of select=".//expression//variable[@name='Value']"/>
)
</xsl:for-each>
</xsl:if>
<!--  Conditions with no preceding operators  -->
<xsl:if test="not(./condition//operator)">
<xsl:for-each select="./condition//expression">
<xsl:value-of select=".//variable[@name='Query']"/>
<xsl:value-of select=".//variable[@name='Variable']"/>
<BR/>
<xsl:value-of select=".//variable[@name='Operator']"/>
<BR/>
<xsl:value-of select=".//variable[@name='Value']"/>
<BR/>
</xsl:for-each>
</xsl:if>
</TD>
<!--  Output Name and Description of Step  -->
<TD Class="step">
<xsl:value-of select="@name"/>
</TD>
<TD Class="step">
<xsl:value-of select="@description"/>
</TD>
<!--
 Output the PackageID, DriverPackageID or CustomSettingPackageID or OSPackageIDs for the step 
-->
<TD Class="step">
<xsl:for-each select=".//variable[@name='PackageID' or @name='OSDApplyDriverDriverPackageID' or @name='ConfigFilePackage' or @name='ImagePackageID']">
<xsl:value-of select="."/>
<BR/>
</xsl:for-each>
</TD>
<!--  Output the step action  -->
<TD Class="step">
<xsl:value-of select="action"/>
</TD>
<TD Class="step">
<!--
 Output non-commandline variables (commandline should be in previous action field) 
-->
<xsl:for-each select="defaultVarList/variable[not(@name='CommandLine')]">
<xsl:value-of select="./@name"/>
:
<xsl:value-of select="."/>
<BR/>
</xsl:for-each>
</TD>
</TR>
</xsl:for-each>
<!--  Step  -->
</xsl:for-each>
<!--  Group  -->
</TABLE>
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>

Anoop is Microsoft MVP! He is a Solution Architect in enterprise client management with more than 20 years of experience (calculation done in 2021) in IT. He is a blogger, Speaker, and Local User Group HTMD Community leader. His main focus is on Device Management technologies like SCCM 2012, Current Branch, and Intune. E writes about ConfigMgr, Windows 11, Windows 10, Azure AD, Microsoft Intune, Windows 365, AVD, etc…

1 thought on “ConfigMgr SCCM Easy to Document Task Sequence Documentation”

  1. I can see how this would work great with MDT. How does one get the proper XML files to use when using SCCM CB? if I export to a zip file, I’m not sure which xml to modify, or even if it will work. The blog referenced is for an older version of CM where exporting the XML was more obvious. 🙂

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.