Use a Custom Script Extension to Sysprep an Azure VM
Hi All,
I’ve been in a situation where I want to run sysprep on a Azure VM to create an image, hopefully without needing to login / connect directly to the VM. I thought that this was an opportunity to learn about custom script extensions. (for use in other situations as well)
in summary, I created a powershell script file, and saved it to a new file 'sysprep.ps1':
param([switch]$runSysprep=$false)
write-output "Sysprep Script Run, parameter 'runSysprep': $runSysprep"
if($runSysprep){
write-output "starting Sysprep"
Start-Process -FilePath C:\Windows\System32\Sysprep\Sysprep.exe -ArgumentList '/generalize /oobe /shutdown /quiet'
write-output "started Sysprep"
}else{
write-output "skipping Sysprep"
}
I then uploaded this to a storage account, set the security on the container to ‘blob’ (there's nothing sensitive in that script), then ran the following:
$VMName = 'vmName'
$VMRG = 'vmResourceGroup'
$VMLocation = 'AustraliaEast'
$ExtensionName = 'runsysprep'
$Scripturi = 'https://<storageAccountName>.blob.core.windows.net/templates/scripts/sysprep.ps1'
Set-AzureRmVMCustomScriptExtension -FileUri $ScriptURI -ResourceGroupName $VMRG -VMName $VMName -Name $ExtensionName -Location $VMLocation -run './sysprep.ps1' -Argument '-runSysprep'
This gave the output:
RequestId IsSuccessStatusCode StatusCode ReasonPhrase
--------- ------------------- ---------- ------------
True OK OK
To see the output messages from the script that was run:
$status = Get-AzureRmVMDiagnosticsExtension -ResourceGroupName $VMRG -VMName $VMName -Name $ExtensionName -Status
$status.SubStatuses.message
This displayed the output that was expected:
Sysprep Script Run, parameter 'runSysprep': True\nstarting Sysprep\nstarted Sysprep
A short time later, the VM is shutdown (but is still allocated & incurring charges), so i then shutdown the VM:
Stop-AzureRmVM -Name $VMName -ResourceGroupName $VMRG -force
As with everything I post about, please give comments / questions on my approach /methods
Nick
Comments
- Anonymous
October 29, 2017
Hi Nick,This is great !One quick question. Do we require any other checks prior to run this script?AndHow you kept sysprep file to blob? I mean we can make it also auto deploy using "Set-AzureRmVMCustomScriptExtension" isn't it?Thoughts?Thanks!I guess it two ques now ;)- Anonymous
October 29, 2017
The script does assume that the VM is online - but other than that it's up to the admin to be sure that the VM is ready for sysprep.To upload the file to blob storage - to keep this simple, I was just using Azure Storage Explorer - but this could be done in a multitude of ways - including as part of the Set-AzureRmVMCustomScriptExtension command.To set the security on the file to 'blob' - I often use Azure Storage Explorer - but this can also be done through the portal or with PowerShell.- Anonymous
October 31, 2017
Hi Nick - I ran your provided scripts but it didn't get through.I am running this script from my local machine.I kept sysprep.ps1 in container, but it seems not found.I am getting below error:-Set-AzureRmVMCustomScriptExtension : Long running operation failed with status 'Failed'. Additional Info:'VM has reported a failure when processing extension 'runsysprep'. Error message: "Failed to downloadall specified files. Exiting. Error Message: The remote server returned an error: (404) Not Found.".'ErrorCode: VMExtensionProvisioningErrorErrorMessage: VM has reported a failure when processing extension 'runsysprep'. Error message: "Failed to download all specified files. Exiting. Error Message: The remote server returned an error: (404) NotFound.".StartTime: 10/30/2017 4:54:00 PMEndTime: 10/30/2017 4:54:00 PMOperationID: XXXXXXXXXXXXXXXXXXXXXXXXStatus: FailedAt ....\Run_sysprep.ps1:6 char:1+ Set-AzureRmVMCustomScriptExtension -FileUri $ScriptURI -ResourceGroup ...- Anonymous
October 31, 2017
Please to go the script URL using any browser - it should download the file. If it doesn't then the URL is wrong, or the permissions on the blob container with the file hasn't been set to 'blob' or 'container' (either will work).
- Anonymous
- Anonymous
- Anonymous