A tool for automating the installation of the Microsoft Windows operating system on various device platforms.

Setup Guide
Glazier Configurations
└─New Actions
└─Config Layout
YAML Files
└─YAML Specs
└─Chooser UI
└─YAML Tips
└─Installer Actions
└─Policy Modules
└─Error Handling
└─Config Handlers
Mailing List 💌
File A Bug 🐛

Hosted on GitHub Pages — Theme by orderedlist

Glazier Build YAML Specification

Glazier uses YAML-based configuration files.


TIP: See the examples directory for more complete YAML examples.

Below is an example of what a simple Glazier configuration could look like.

      - ['software/', 'build.yaml']
      - '#some_executable.exe'
      ['somefile.txt', 'C:\somefile.txt']
  - pin:
      'os_code': ['win2019', 'win2022']
      - software
  - pin:
      'os_code': ['win10']
      - some_template

See below for an explanation of the elements above.

Top Level

The top-level is a dictionary of two elements, templates and controls.


TL;DR: Think of templates as function declarations.

“Templates” is a dictionary of named elements. The name is used to reference each template from one or more control elements. Templates are not executed unless referenced by a control element. Their primary purpose is to allow a logical grouping of commands which may be recycled more than once to simplify the overall configuration.

The second template level is the template name. Names can be arbitrary, but ideally should have some relevance to what the template is doing.

Beneath the template name is the common command element structure described below. Pins are not used in templates, as it is assumed they will be called from a pinned control instead.


  install-oregon-trail: # <-- Template name
    Execute: [ # <-- Glazier Action
      ['googet install -noconfirm oregon-trail']
    Reboot: [] # <-- Glazier Action


“Controls” is an ordered list of unnamed elements. The list structure is used to provide a consistent ordering of elements from top to bottom, so commands can be executed in a predictable order. All build yamls execute commands from top to bottom.

The second control level is the common command structure detailed below. A control commonly starts with a pin item, unlike templates, but a pin is not required. Unpinned controls will match all.

Command Elements

Each block of the controls list or the templates dictionary can contain any combination of the following, except for pins, which are exclusive to control elements.

The order in which individual elements within a single command group are processed is determined by the build code and may be subject to change. If you need to control the order of operations, split the commands between multiple command groups, as the groups are always processed sequentially.


Actions are dynamic command elements. Unlike the static commands listed on this page, actions are not hardcoded into the config handler. When a configuration file references a command that is not one of the known static commands, the config handler will attempt to look up the class name in the actions module. If it finds it, the class is loaded and run with the arguments from the configuration file entry.

Actions are the preferred method for adding new functionality to the autobuild tool. Unlike hard-coded commands, actions are almost fully self-contained and capable of self-validating.

See the Actions README for a list of available actions.


Exclusive to control elements, the pin attaches the current block to a specific set of build info tags. The tags are inclusive, and must *all *match for the command block to be executed by the build. The format is a dictionary, where the key is the variable name from buildinfo and the value is a list of acceptable values. If the key-value in buildinfo matches any of the strings in the list, the pin passes for that key.

Some pins support “loose” matching. In the case of loose matches, the entire pin string is checked against the start of every corresponding buildinfo value. For example: ‘A-B’ matches ‘A-B’ as well as ‘A-B-C-D’, but not ‘A-C’.

  - pin:
     'os_code': ['win10']
     'department': ['demo']

Inverse pinning is also supported. Inverse pins are like regular pins, with the match string beginning with an exclamation point (!). An inverse pin returns False if any buildinfo value matches the inverse string (minus the !). For example: 'os_code': ['!win10'] excludes the pin from os_code=win10 hosts.

While direct match pins are exclusive, skipping any values not named in the set, inverse match pins are inclusive, accepting any values not named directly. If the pin is not negated by a matching inverse pin, the outcome is a successful match. For example: 'os_code': ['!win10', '!win8'] is False for os_code=win10 and False for os_code=win8, but True for os_code=win2022.

Direct pins are only considered if no inverse pins are present. This is to compensate for direct matches being exclusive in nature. It would not make sense to supply [!A, !B, C], because [C] would have the same result.

Pins are generally treated as case insensitive.


The policy tag specifies an imaging policy. Imaging policies are used to verify that the state of the host being installed meets a given set of expectations.

Each policy tag element is a single string consisting of the name of the imaging policy class to be enforced. The class name must match exactly, as classes are dynamically referenced.

  - policy:
    - 'DeviceModel'

See also the Policies README


The template tag tells build to process a list of one or more named templates. Templates are processed recursively, so templates can call other templates as well.

  - workstation


The include tag tells build to process an additional YAML file. The structure is a list of two-part entries, a directory name relative to the current build directory, and a build file name. Includes are useful for breaking up large build files into smaller logical groups.

  - include:
    - ['demo/', 'build.yaml']

Supported Pins

The pins are essentially exported build info variables that help identify the installing host. Not all of build info is exported for the purposes of pinning, although it’s always possible to extend the code to support different pins in the future.