Documenting APIs with Sandcastle using Windows Powershell

Please see my blog about Sandcastle Spetember 2007 release. With this release, we plan on shipping an example Windows powershell script to document APIs using Sandcastle.


Why Windows Powershell

I saw what Scot Hanselman did for Sandcastle with Powershell and got the inspiration for creating a Windows powershell script for Sandcastle. BTW you can view Scott's latest show on DNR TV about Windows powershell at


I have details about this new scripr below. The script that will be shipped is called “scbuild.ps1” and provides the following features:

  • Provides a single command wrapper to build CHM and HxS files regardless of where the source assemblies and comments are located. For example, to build the sample project we ship with Sandcastle use the following command:

                 scbuild –buildchm -buildhxs –framework 2.0 –sources test.dll,comments.xml

  • Allows the build options to be read from a configuration file. Options specified on the command line override options defined in the configuration file.

  • Handles any number of target assemblies and comment files, including globbing.

  • Handles any number of dependencies.

  • Should work with .NET 2.0, 3.0, and 3.5.

  • Supports vs2005, prototype, and Hana presentation styles.

  • Provides hooks to add new presentation styles in the future, including user defined styles, and user defined function overrides.

  • The script is written for PowerShell 1.0.


The build script has the following dependencies:

  • September 2007 release of Sandcastle.
  • The DxRoot environment variable must point to the root of the Sandcastle installation.
  • To make it easier for the user, the PATH environment variable should contain the …/ProductionTools folder, which contains the scbuild.ps1 script.
  • .NET 2.0 for Sandcastle.
  • PowerShell 1.0, with the execution policy set to RemoteSigned or Unrestricted. [Note: In a future release we could Authenticode sign the script to make this unnecessary.]
  • hhc.exe to compile CHM files.
  • Hxcomp.exe to compile HxS files.

Running the Script

To run the script, open a PowerShell window and run scbuild with the “appropriate” options. You’ll want to make sure that DxRoot points to the root folder of the Sandcastle installation and [optionally] that your PATH variable contains the ProductionTools folder. Internally all Sandcastle executables are referenced relative to DxRoot; setting PATH is only necessary to avoid having to type the entire path to scbuild each time.

NOTE: If you’ve just installed PowerShell to run this script, you have to give it permission to execute scripts on your machine. If you don’t, PowerShell will refuse to execute any scripts that haven’t been Authenticode signed. To change the execution policy, open a PowerShell window and type the following command:

       set-executionpolicy RemoteSigned

This allows the shell to execute all local scripts, as well as signed remote scripts. The setting is persistent.

Once that’s done, you can run the script. For a synopsis of the command line options available, see the header of …/ProductionTools/scbuild.ps1. Most of the options should be pretty self explanatory from the synopsis. I’ll expand on a couple of the more advanced features here. 

Using the –Config Option

The –config option allows you to specify the options you would normally type on the command line in a configuration file. You’ll want to use this feature to easily manage build configurations or if the command line is too long for the shell.

The config file is a PowerShell script and the command line options are exposed as variables in “Script:” scope. For example, with the following statements in a file named “testconfig.ps1”:

$BuildChm = $true

$BuildHxs = $true

$Framework = "2.0"
$Sources = "test.dll", "comments.xml"

You can then run the build with this command:

       scbuild –config testconfig.ps1

Using the –Mixin Option

The –Mixin option allows you to override any of the functions defined in scbuild.ps1 and DocModel.ps1, except for Init(), which is called before the mixins are loaded. Like the config file, the mixin file is a PowerShell script. It gets loaded just after scbuild and the doc model have been initialized, but before any of the build commands are executed. You can use this feature to add new functionality or to change build details.

NOTE: This feature is experimental. Future versions of the build script may be quite different, and functions and variables that exist in this version may not be there in future versions. Anybody using this feature should expect breaking changes.

For example, to override the function that copies the CHM file to its final destination you could create a script file named “testmix.ps1”:

function CopyChmToOutputDir {

       WriteInfo "copy chm file to output directory with date"
MakePath $OutputDir

       copy-item –force "$TempDir\Output\$($Name).chm" "$($Name)-$([DateTime]::Now.ToString('yyMMdd'))"


To run the build command with this mixin use:

        scbuild –buildchm -buildhxs –framework 2.0 –mixin testmix.ps1 –sources test.dll,comments.xml

When you run this command, the output file name would now include the current date: test-070910.chm.

New & Changed Files

scbuild.ps1 requires a number of support files, but touches only one previously existing file: …/Prototype/Transforms/utilities_reference.xsl. In that file, we removed the HTML 4.0 doc type declaration, because the output from the transforms is not valid HTML 4.0 and having the doc type causes validation errors later in the tool chain. Eventually, the transforms should be fixed to produce valid XHTML 1.0 transitional and then the doc type declaration should be added back in.

Also, each presentation now has a new BuildAssembler config file named Sandcastle-scbuild.config. The new config differs from the previous Sandcastle config in that it includes a different set of reflection and comment files. It is necessary to make the build script location independent, and to support any number of input files.

The doc model specific scripts include a shared script: …/Presentation/Shared/SharedDocModel.ps1. This script defines functions that are the same for all doc models.

Note that the doc model specific script must be called DocModel.ps1, and no other directory under …/Presentation that does not define a doc model must have a DocModel.ps1 file in it. The presence of this file is used to determine if a particular style specified on the command line is a doc model, or just some other support directory like “Shared.” This allows us to add/delete doc models without touching the build script itself, and to ship different configurations that include only a subset of the doc models. It also allows the user to define a custom doc model.


  • Better error handling when intermediate build steps fail.
  • The script currently rebuilds all of the framework and dependency reflection data each time it is executed. This makes it easy to handle different frameworks and doc models. In a future version we can speed things up by keeping a copy of the data around and only rebuilding it on request.

 Hope you all like this new script. Cheers.