The following Azure Resource Manager mode PowerShell will allow you to create an image of an existing Windows virtual machine in Azure, deploy it at will and join it to a domain if necessary.

Login to PowerShell

[code language=”powershell”]
Get-AzureSubscription
$SubID = "your-subscription-ID"
Login-AzureRMAccount
Select-AzureRmSubscription -SubscriptionId $SubID
[/code]

Create the virtual machine image

Run sysprep on the desired virtual machine in Azure.

[code language=”dos”]%windir%\system32\sysprep[/code]

When prompted for System Cleanup Action choose ‘Enter System Out of The Box Experience (OOBE)‘, Generalize and Shutdown from Shutdown Options.

sysprepgeneral

Deallocate and generalize the virtual machine

[code language=”powershell”]
Stop-AzureRmVM -ResourceGroupName "resourceGroup" -Name "vmName"
Set-AzureRmVm -ResourceGroupName "resourceGroup" `
-Name "vmName" -Generalized
[/code]

Create the virtual machine image

[code language=”powershell”]
Save-AzureRmVMImage -ResourceGroupName YourResourceGroup `
-VMName YourWindowsVM `
-DestinationContainerName YourImagesContainer `
-VHDNamePrefix YourTemplatePrefix -Path Yourlocalfilepath\Filename.json
[/code]

Set the path to the image file you’ve just created the URI to which is available in the storage account where the image file was created under the following path.

[code language=”dos”]\storageAccountName\blobs\system\microsoft.compute\images\images\[/code]

[code language=”powershell”]
$imageURI = "https://storageAccountName.blob.core.windows.net/system/Microsoft.Compute/Images/imagesContainer/templatePrefix-osDisk.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.vhd"
[/code]

Define the required variables

Complete the list of variables below needed to define the deployment.

[code language=”powershell”]
$rgname = "destination-resource-group-name"
$vmsize = "vm-size"
$vmname = "vm-name"
$locName= "vm-location"
$nicName = "network-interface-name"
$vnetName = "virtual-network-name"
$SubName = "subnet-name"
$DomainName = "domain-name"
$DomainJoinAdminName = $DomainName + "\username"
$DomainJoinPassword = "password"
$osDiskName = "OS-disk-name"
$osDiskVhdUri = "URL-to-your-OS-disk-image-file"
[/code]

Deploy the virtual machine.

Complete the deployment using the PowerShell below.

[code language=”powershell”]
$vm = New-AzureRmVMConfig -VMName $vmname -VMSize $vmsize
$vnet=Get-AzureRmVirtualNetwork -Name $vnetName -ResourceGroupName $rgName
$subnet = $Vnet.Subnets | Where-Object { $_.Name -eq $SubName}
$pip=New-AzureRmPublicIpAddress -Name $nicName -ResourceGroupName $rgName -Location $locName -AllocationMethod Dynamic
$nic=New-AzureRmNetworkInterface -Name $nicName -ResourceGroupName $rgName -Location $locName -SubnetId
$subnet.Id -PublicIpAddressId $pip.Id
$vm = Add-AzureRmVMNetworkInterface -VM $vm -Id $nic.Id
$vm = Set-AzureRmVMOSDisk -VM $vm -VhdUri $osDiskVhdUri -name $osDiskName -CreateOption attach -Windows
New-AzureRmVM -ResourceGroupName $rgname -Location $locName -VM $vm[/code]

Join the domain.

Join the virtual machines to the domain using the PowerShell below.

[code language=”powershell”]
Set-AzureRMVMExtension -VMName $VMName –ResourceGroupName $rgname -Name "JoinAD" -ExtensionType "JsonADDomainExtension" -Publisher "Microsoft.Compute" -TypeHandlerVersion "1.0" -Location $locName -Settings @{ "Name" = $DomainName; "OUPath" = ""; "User" = $DomainJoinAdminName; "Restart" = "true"; "Options" = 3} -ProtectedSettings @{ "Password" = $DomainJoinPassword}
[/code]

Category:
Azure Platform, Cloud Infrastructure, PowerShell, Uncategorized

Join the conversation! 4 Comments

  1. Hi,

    great article, but do pip and nic really should have the same name?

    $pip=New-AzureRmPublicIpAddress -Name $nicName…
    $nic=New-AzureRmNetworkInterface -Name $nicName -ResourceGroupName $rgName..

  2. Hello, it looks like your PowerShell code is not displaying the quote mark, so if anyone were to try to run it, it’ll error out. You may want to fix it. 🙂

Comments are closed.