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 (4)

  1. Mrugesh says:

    Hi Nick,

    This is great !

    One quick question.
    Do we require any other checks prior to run this script?
    And
    How 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 😉

    1. Nick Eales says:

      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.

      1. Mrugesh says:

        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 download
        all specified files. Exiting. Error Message: The remote server returned an error: (404) Not Found.”.’
        ErrorCode: VMExtensionProvisioningError
        ErrorMessage: 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) Not
        Found.”.
        StartTime: 10/30/2017 4:54:00 PM
        EndTime: 10/30/2017 4:54:00 PM
        OperationID: XXXXXXXXXXXXXXXXXXXXXXXX
        Status: Failed
        At ..\..\Run_sysprep.ps1:6 char:1
        + Set-AzureRmVMCustomScriptExtension -FileUri $ScriptURI -ResourceGroup …

        1. Nick Eales says:

          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).

Skip to main content