A Windows- and OS X-compatible Python script that fetches, from Apple's or your software update server, the Boot Camp ESD ("Electronic Software Distribution") for a specific model of Mac. It unpacks the multiple layers of archives within the flat package and if the script is run on Windows with the --install
option, it also runs the 64-bit MSI installer.
On Windows, the archives are unpacked using 7-Zip, and the 7-Zip MSI is downloaded and installed, and removed later if Brigadier installed it. This tool used to use dmg2img to perform the extraction of files from Apple's WindowsSupport.dmg
file, but more recent versions of 7-Zip have included more completely support for DMGs, so dmg2img seems to be no longer needed.
This was written for two reasons:
It was originally designed to be run as post-imaging step for Boot Camp deployments to Macs, but as it requires network connectivity, a network driver must be already available on the system. (See Caveats below)
Brigadier has produced less-than-great results with some combinations of driver packages and hardware models in recent versions of Boot Camp 5, and now with Boot Camp 6. Some people have confirmed issues with Boot Camp 6 and Windows 7 in general, so these may not be entirely Brigadier's fault. Some examination of the Boot Camp setup.exe
indicates to me that this executable performs several tasks and sets up some environment for the eventual execution of BootCamp.msi
, which we're not always able to get with Brigadier's simple invocation of msiexec
to install the MSI directly.
I'm far from knowledgable enough about Windows internals to understand how to be able to perform a fully-automated version of whatever setup.exe actually does (besides eventually run msiexec /i /qr
on the MSI). For example, this PR suggests that better results can be achieved by using different "quiet" options to msiexec
, but a disassembly of setup.exe
shows that it is actually executing /qr
, as does the code in the current master branch. This kind of question is one I don't feel I have enough knowledge to attempt an answer.
There have been strange issues I've experienced a couple of years ago as well. For example, a single driver installer (Intel chipset-related) that pops up a series of WinRAR SFX errors due to it attempting to sequentially execute all of the driver's localization files (which aren't even executable). Simply clicking through these dialogs eventually causes the installation to continue, but until that happens the process is blocked. This error doesn't happen when a user manually runs setup.exe
, but why I do not understand.
While I maintain some hope to be able to resolve these issues, my environment's use case for dual-boot labs is shrinking and so it's difficult to justify the time required to spend further researching these issues. If anyone who is knowledgeable about reversing setup.exe
-like installer wrappers and MSI installers, and Windows systems administration in general, is interested in tackling the currently-somewhat-broken support for silent installs of Boot Camp drivers in this tool, I'd love some help! There are several installer properties in BootCamp.msi
that may be of some help with this issue as well.
Run brigadier with no options to download and unpack the ESD that applies to this model, to the current working directory. On OS X, the ESD is kept in a .dmg format for easy burning to a disc; on Windows, the driver files are extracted.
Run it with the --model
option to specify an alternate model, in the form MacPro3,1
, etc.
Run it with the --install
option to both download and install, deleting the drivers after installation. This obviously works only on Windows. This option was made for doing automated installations of the Boot Camp drivers.
Place a brigadier.plist
file in the same folder as the script to override the .sucatalog URL to point to an internal Software Update Server catalog (details below).
Additional options shown below.
You can find a pre-compiled binary for Windows in the releases area. This can be useful if you don't already have Python installed on Windows. This was built using PyInstaller. More details on building it yourself below.
It can also be run directly from a Git checkout on either OS X or Windows.
Besides a few command-line options:
Usage: brigadier [options]
Options:
-h, --help show this help message and exit
-m MODEL, --model=MODEL
System model identifier to use (otherwise this
machine's model is used).
-i, --install After the installer is downloaded, perform the install
automatically. Can be used on Windows only.
-o OUTPUT_DIR, --output-dir=OUTPUT_DIR
Base path where the installer files will be extracted
into a folder named after the product, ie.
'BootCamp-041-1234'. Uses the current directory if
this option is omitted.
-k, --keep-files Keep the files that were downloaded/extracted. Useful
only with the '--install' option on Windows.
You can also create a brigadier.plist
XML plist file and place it in the same directory as the script. It currently supports one key: CatalogURL
, a string that points to an internal SUS catalog URL that contains BootCampESD packages. See the example in this repo.
It's common to perform the Boot Camp drivers during a post-imaging Sysprep phase, so that it's possible to deploy the same image to different models without taking into account the model and required Boot Camp package. Brigadier seems to behave in the context of a SysPrep FirstLogonCommand.
There is one workaround performed by the script when running in this scenario, where the current working would normally be \windows\system32
. In my tests on a 64-bit system, the MSI would halt trying to locate its installer components, due to the way Windows forks its System32
folder into SysWoW64
for 32-bit applications. When the script detects this working directory without a --output-dir
option overriding it, it will set the output directory to the root of the system, ie. %SystemRoot%\
.
By default, when --install
is used, it will clean up its extracted files after installation, unless the --keep-files
option is given, so unless you want to keep the files around you shouldn't need to clean up after it.
If you'd rather run it as a standard Python script, you'll need Python for Windows (this was tested with the latest 2.7 release) in order to execute the script.
If you'd rather build it yourself, you can use the included build script. It requires Python and the matching version of pywin32. It handles downloading PyInstaller for you. Simply run it with no arguments, and it will build a zip file in the current working directory:
c:\python27\python build_windows_exe.py
On OS X, we have the native hdiutil and pkgutil commands to do the work of unpacking the driver files. On Windows, we:
WindowsSupport.dmg
file within the pkgC:\Windows\INF
on a sysprepped image. This folder is the default search location for device drivers, and it should automatically detect and install drivers located here for all unknown hardware. You can also modify the DevicePath
registry key to add a custom location, but using the existing INF
folder means no other changes besides a file copy are required to update an existing image's drivers, so this can be done without actually restoring the image and booting it just to install a driver. Offline driver servicing using Windows and DISM is easy for WIM images, but most admins are likely not deploying WIM images to Macs, but rather using tools that wrap ntfsprogs.brigadier.plist
will support overriding these URLs with your own copies stored on a private webserver.FirstTimeRun
registry key at HKEY_CURRENT_USER\Software\Apple Inc.\Apple Keyboard Support
to disable the first-launch Boot Camp help popup, and there's currently no option to disable this behaviour.