We're planning to automate the creation of VMs for our build infrastructure so that we can:
- Scale the build resources based on demand, e.g. by adding more build agents when required and removing them when not required
- Recreate all or part of the build environment if / when machines die
- Duplicate the build environment when we need a test set up
One of the steps in this process is automating the creation of the VM base images (in our case using Hyper-V). For that we have a script that:
- Creates new VHDX from ISO with the Convert-WindowsImage script. We're currently using Windows 2012R2 but will be looking to get started with 2016 as soon as it is available.
- Adds an unattend script to the new VHDX with all the base configuration we need
- Updates the VHDX with the latest windows patches using the Apply-WindowsUpdate script
- Creates a new Hyper-V VM based on the VHDX and starts it
- Waits for the VM to boot and wait for the WinRM service to be ready to accept remote connections
- Waits for windows to complete the initial configuration and the configuration of the new patches
- Applies any further patches
- Reboots to complete the configuration of the latest patches
- Waits for windows to complete configuring the patches
- Pushes a sysprep script to machine and invokes that script. This runs sysprep and then turns the machine off
- Deletes the VM but keeps the VHDX
- Removes sysprep and unattend files from the VHDX and then compacts the VHDX
- Moves VHDX to template location and mark as read-only
The problem we're experiencing is in steps 6 and 9. Ideally we wait for all the configuration to be complete before we reboot / shut down the machine but there does not seem to be a way to detect that windows has finished the configuration stage.
When going through the UI it is very clear when either step is done because the log-in UI doesn't show up until the process is ready. However when using WinRM to remotely connect to the machine this is less clear because WinRM provides access to the machine before it is done with the configuration work.
So the question is what is the most fool proof way to detect over a remote connection that Windows has finished configuring updates etc. so that we can reboot / shut down the machine without causing issues later on.
------ EDIT -----
In the end we're using a modified version of Katherine's answer in that our script also waits for
ngen to complete. Given that
ngen doesn't complete until well after the OS has finished initializing that works, and as a bonus the final VHDX will have all of the .NET framework ngen-ed which means we don't have to deal with that when we create new VMs of the template disk. Both script that we use to create the VHDX template and the scripts to create the local test environment are on github in case anybody is interested.