In Part 1 of this series, we saw the basics needed to get an Image built, in Part 2 I want to show you how we can use our existing Intune Software Packages in the built process, a few smaller tricks and how to troubleshoot the whole thing if something goes wrong.
Installing Software
To use our existing Intune software packages, we can simply compress them into a zip archive, similar as we would do to create an intunewin file:


Upload them to our storage account created in Part 1:

And finally create a Shared Access Signature URL for that file and add it to our install script by replacing <INSERTSASURLHERE> in the script with our URL. We want to store the SAS URL on our storage account, so it is protected and not stored in clear text in the Image Template. The access to the script during building is protected by the managed identity, so here we only need the path to the script without the SAS token (Scripts/AzureVMImageBuilder/InstallApp.ps1):

Depending on your Application and wrapping, you may need to modify the Install command as well, since most of our Apps are still wrapped in PowerShell App Deploy Toolkit V3, my sample uses the Deploy-Application.exe as main file to track installation.
If your app installation will start a subprocess that will not terminate after the installation is done, you may use my other Install script that will query the running process rather than using the -wait option from start-process, as it could wait forever to terminate this child process (Scripts/AzureVMImageBuilder/InstallApp2.ps1):

Now we can finally upload that script to our storage account as well, copy the URL:

And just add it to our Image Template:

Tipps and Tricks
OS Disk resize
If you selected a bigger Disk size than the original (marketplace) image and you require that additional size during built time, you can use a simple script to resize the OS partition to max available storage:


Scripts/AzureVMImageBuilder/Resize-OSDisk.ps1
Azure VM Guest Agent
If you want to use the exported vhd image outside of Azure, you may want to disable the automatic Azure VM Guest Agent installation that would happen during the setupcomplete.cmd phase before OOBE as in my experience the setup process will timeout in Hyper-V. Fortunately, we can easily rename the OEM folder containing the install scripts:
Scripts/AzureVMImageBuilder/VMGuestAgent.ps1

Download and extract
For the download I opted in to use the windows integrated curl.exe which works pretty reliable in my experience, but if you want you can also use azcopy for that by again downloading it to the machine and use it in something like that: (Scripts/AzureVMImageBuilder/InstallApp3.ps1)

Similar, depending on your app, size and structure, you may want to use 7-zip instead of the PowerShell integrated Expand-Archive cmdlet to speed things up. We can again simply download and store the 7z cli version to the machine and replace the Expand command with something like this to speed up things:

Troubleshooting
Let’s leave our perfect world, where everything just works and have a look at how we can troubleshoot things when something just doesn’t want to work as we want. First thing to know, all things that are created during built time by the Azure Image Builder are stored in a seperate Resource Group within our subscription. You can find it relatively easy as its name starts with IT and it contains the Image Template name as well:

During built time
During built, we can find everything used to build our image, including the Azure VM, OS Disk, and networking:

The probably most helpful tool for me were the LiveLogs from the Container instance. No longer waiting for the whole process to fail / timeout to get the results, we can just go into our Container and select Logs to see a live output of what the thing is currently doing:

If you want to have a more verbose output during build, you can go into the storage account, to Classic file shares and into the packerOutput Folder, here you can find the packer.log:

Which shows you a more verbose output of the view that we saw in the Logs section of the container with timestamps and things that you would expect from logs, making it easier to find stuff:

One sidenote since we are in the storage account, we cannot change our scripts on our storage account, as they are getting stored in the temp storage account, so changes will only take effect, when we recreate the Image Template itself (more of that in Part 3)

If the Logs captured are not enough to understand what happens, we can create a Disk Snapshot of the OS Disk at any stage of the build:




And with that snapshot we can either create our own Azure VM or just export it to a vhd file:

and mount it to offline search for logs, etc.

Alternatively, you can also change the password of the packer user of that VM and connect directly to it via e.g. Azure Bastion, however this will most likely break the build process, which may or may not be what you want.
After Built
If we look in the Resource Group after the built time, we can see only the storage account is left and everything else got cleaned up:

If we want to see what happened during built time, we now can have a look into the packerlogs blob container and open the customizations.log:

And we again have a similar log as we saw before during the built time:

Conclusion
Now that we know how we can re-use our existing Intune software packages to build our custom images, the whole idea behind creating golden images sounds less terrific to me. In Part 3, I will cover how we can use an Azure Resource Manager Template to more easily make changes to our Azure Image Builder Template by just changing it in a json file instead of recreating the whole thing in the UI every time we want to change anything.

Leave a Reply