Virtual machine deployment tool

Hi all,

So, as I wrote the other day I will do a dedicated post for the deployment tool I showed on the webinar last week. I haven’t really found a good name for it yet, so, for now, I will just call it deployment tool.

The deployment tool has one purpose and that is helping you deploy any Windows VM with application role to any datacenter you want. The role can be a Citrix VDA or an FTP server or whatever you would like to deploy, the only thing it should require from you is knowing how to install the software you need silently so that we can do a fully automated deployment. Friday, I showcased the installation of a Citrix VDA with some standard applications that we see used all the time. The great thing about the two installations I showed is that the software deployed is the exact same installation no matter where you deploy them. In my demo, I showed how to install them on Azure and how to deploy them to XenServer on-premises. As you could see both VDA’s was installed without any issues and the application list and Citrix functionality was the same as well. It is this kind of consistency I want to help others gain as well.

Now my deployment tool is simple, but when deploying to Microsoft Azure there are a lot of fields that need to be filled out. If you use the XML file I showed you can save a lot of typing, but I do NOT recommend saving the passwords in the XML, I only did that to speed up the process since it was a demo.

Let’s take a view of the deployment tool. Below is a picture of the XenServer tab in the tool, and as you see it is simple. On the left, we have the connection details like the IP for the Pool Master, username, and password. When all are entered in you click on “Connect to XenServer”. If the connection is successful you will see that in the status bar, and if not, that will be shown as well. On the right side you have the information details for the new virtual machine you are about to deploy, it needs a name, size, role, and path to the Microsoft Deployment Toolkit (MDT) server. When all information is entered you click on “Create virtual machine” and that kicks off the MDT build in the background. Now some of you may be thinking, how is this all linking into MDT, and the short version is that the role you select in the drop down is the ID on the task sequence in MDT. The deployment tool collects the MAC address from the new virtual machine and adds it to the customsettings.ini file in MDT and then all is in place.


The second tab on the deployment tool is for Microsoft Azure. If you look on that screen you will see there are a lot more fields to consider, but if you have ever worked with Azure they should all be familiar, in fact, if they are not, you are not ready to use the deployment tool. Below is a screenshot of the Azure tab, and if we again start from the top left we have a button as the first “field”, this is the “Connect to Azure” button and that is the first thing that needs to be done. When you click the button, you are asked for your credentials to Microsoft Azure, and they, of course, need to be filled in correctly so that you can connect. When you have connected to Azure, you see that a lot of the fields are filled out automatically, but you still need to ensure that each field is correct. The fields are populated and the first item in each is shown, this might not fit what you want to install every time.
Under the connect button we have five fields, Resource group, vNet, Subnet, Storage account, and size. They are all drop down boxes so filling them out is simple. In the middle section, we have the following fields, Server OS, Local Admin username, Password for local admin, Virtual machine name and role. Again, the fields should make sense, and the role again points to the ID of the task sequence in MDT.
The third column is containing the following fields, Domain name, Domain join account, Password for domain join account, Server administrator, Password for server administrator. The domain join account is a service account with only permissions to join computers to the domain, the server administrator account is a domain user that has administrative rights on the new virtual machine so that it can access it remotely and kick off the task sequence from MDT.
On the far-right column, we have the MDT path, and this can be in either the datacenter that you are deploying to or if you have a fast-enough connection you can have it accessible via VPN or ExpressRoute. Important to know is that the installation should work on a slow connection, but you might be bored to death before it completes then 🙂
Lastly, we have the “Create virtual machine” button and yeah you guess it, it deploys the VM with the details you provided in the other fields.


So, this was the explanation blog post showing what I had in the webinar last Friday. I was asked if the tool would be a community tool and that is what I am expecting it to be. I won’t promise anything just yet, but since it is a spare time project I would like it to go back to the community so everyone who wants to can use it. When I get a bit more done on the deployment tool I will do another post going into more details about how to install it and make the connections between the tool and MDT.

When writing this post I got the idea that instead of having all the fields on one tab, would it makes sense to do a wizard instead so it doesn’t seem too overwhelming?

If you have any questions or feedback on this project feel free to reach out.


6 thoughts on “Virtual machine deployment tool”

  1. Hi martin. Is it possible with your tool to define also vm settings in different resource locations? I prefer that only the vm is in a “compute” rl, the nic and public ip’s is than in the network rl. Also the disk is than in storage rl. So i split my vm in different rl,s. It is for me so much easier. I have begin with this after i have a ms azure guru in our company. He prefer that design from deploying vm,s. On your Demo i see you have one Ressource location where everything is in. I have many customers where i want in future automate this deploying in azure. Hopefully we get also AFxx from Eric there in the Azure Stack. Regards Franco

    1. Hi Franco,

      That is an interesting approach to Azure I think, never heard about doing it that way, but I can see how it makes sense for some. The tool does not support that now, and I will need to look into how you are doing it in Azure now. From what I have seen you select one resource group when deploying the VM so I am not sure about how you are doing it. But since you are doing it we can definitely make it happen in the tool as well. If you want to do it this way, would it make sense to do the wizard as I wrote on the post?


    2. Hi Franco,
      Do you have a guide somewhere that you use to create the machines today? If I use the Azure new vm wizard I don’t get these options.


  2. hi martin, sorry for the GREAT delay here, for first, i look your Webinar from CUGC, was great, so better question is. how i get this tool? can i make here a beta User for you? and for sure, here are my poshes for creating vm´s in separate Resource locations.

    ## Built a VM with from a Windows Server BYOL image
    # Variables
    $RGCompute = “RG1_Compute”
    $RGNetworking = “RG1_Network”
    $RGStorage = “RG1_Storage”
    $StorAccNameOS = “rg1storageputinyourname” #put your storageaccount standard or premium here
    $StorBootDiagnostic = “rg1storageputinherediagstoragediag”
    $VMName = “Name of your VM”
    $Location = “westeurope”
    $VNetName = “Your VNET Name”
    $SubnetName = “Your Subnet VLAN”
    $IPAddressVM = “10.0.x.x”
    $osSKU = “2016-Datacenter”
    $VMSize = “Standard_DS2_v2_Promo” #Standard_DS2_v2_Promo
    $Disk_D_Size = “200”
    #$Disk_E_Size = “20”
    $DomainName = “”
    $Username = “your admin account”
    $Password = “your password here”
    $DomainJoinAdminName = $DomainName + “\your admin account”
    $DomainJoinPassword = “your password here”
    ## ———————————————————————————————————————————————————————————-
    # Create the Public IP Address (PIP)
    # $PIP = New-AzureRmPublicIpAddress -Name “${VMName}-pip” -ResourceGroupName $RGNetworking -Location $Location -AllocationMethod Static
    ## ———————————————————————————————————————————————————————————-
    # Create the NIC
    # Get the VNET to which to connect the NIC
    $VNet = Get-AzureRmVirtualNetwork -Name $VNetName -ResourceGroupName $RGNetworking
    # Get the Subnet ID to which to connect the NIC
    $SubnetID = (Get-AzureRmVirtualNetworkSubnetConfig -Name $SubnetName -VirtualNetwork $VNET).Id
    $NIC = New-AzureRmNetworkInterface -Name “${VMName}-nic1” -ResourceGroupName $RGNetworking -Location $Location -SubnetId $SubnetID -PrivateIpAddress $IPAddressVM # -PublicIpAddressId $PIP.Id #falls es Public IP braucht
    ## ———————————————————————————————————————————————————————————-
    # Specify local administrator account
    $Passwordsec = convertto-securestring $Password -asplaintext -force
    $Creds = New-Object System.Management.Automation.PSCredential($Username, $Passwordsec)
    ## $cred = Get-Credential -Message “Type the name and password of the local administrator account.”
    ## ———————————————————————————————————————————————————————————-
    # Specify the image
    $Images = Get-AzureRmVMImage -Location $Location -PublisherName “MicrosoftWindowsServer” -Offer “WindowsServer” -Skus $osSKU | Sort-Object -Descending -Property PublishedDate
    ## ———————————————————————————————————————————————————————————-
    $VM = New-AzureRmVMConfig -Name $VMName -VMSize $VMSize
    $VM = Add-AzureRmVMNetworkInterface -VM $VM -Id $NIC.Id
    #Specify the OS and Data Disk – here i have a D Drive and a E Drive
    $StorAcct1 = Get-AzureRmStorageAccount -ResourceGroupName $RGStorage –StorageAccountName $StorAccNameOS
    $OSDiskName = $VMName + “-C”
    $OSDataDiskName1 = $VMName + “-D”
    $OSDataDiskName2 = $VMName + “-E”
    $OSDiskUri = $StorAcct1.PrimaryEndpoints.Blob.ToString() + “vhds/” + $OSDiskName + “.vhd”
    $OSDataDiskUri1 = $StorAcct1.PrimaryEndpoints.Blob.ToString() + “vhds/” + $OSDataDiskName1 + “.vhd”
    $OSDataDiskUri2 = $StorAcct1.PrimaryEndpoints.Blob.ToString() + “vhds/” + $OSDataDiskName2 + “.vhd”
    Set-AzureRmVMOperatingSystem -Windows -VM $VM -ProvisionVMAgent -EnableAutoUpdate -Credential $creds -ComputerName $VMName
    Set-AzureRmVMSourceImage -VM $VM -PublisherName $Images[0].PublisherName -Offer $Images[0].Offer -Skus $Images[0].Skus -Version $Images[0].Version
    Set-AzureRmVMOSDisk -VM $VM -Name $OSDiskName -VhdUri $OSDiskUri -Caching ReadWrite -CreateOption fromImage
    Add-AzureRmVMDataDisk -VM $VM -Name $OSDataDiskName1 -Caching ‘ReadOnly’ -DiskSizeInGB $Disk_D_Size -Lun 0 -VhdUri $OSDataDiskUri1 -CreateOption Empty
    #Add-AzureRmVMDataDisk -VM $VM -Name $OSDataDiskName2 -Caching ‘ReadOnly’ -DiskSizeInGB $Disk_E_Size -Lun 1 -VhdUri $OSDataDiskUri2 -CreateOption Empty
    Set-AzureRmVMBootDiagnostics -VM $VM -Enable -ResourceGroupName $RGStorage -StorageAccountName $StorBootDiagnostic
    New-AzureRmVM -ResourceGroupName $RGCompute -Location $location -VM $VM -Verbose
    ## ———————————————————————————————————————————————————————————-
    #DomainJoin the Machine after creating
    Set-AzureRMVMExtension -VMName $VMName –ResourceGroupName $RGCompute -Name “JoinAD” -ExtensionType “JsonADDomainExtension” -Publisher “Microsoft.Compute” -TypeHandlerVersion “1.0” -Location $Location -Settings @{ “Name” = $DomainName; “OUPath” = “”; “User” = $DomainJoinAdminName; “Restart” = “true”; “Options” = 3} -ProtectedSettings @{“Password” = $DomainJoinPassword}

  3. Hi martin. Long time is now gone. How is life? Can you say me if your tool is now public? Or when not, can you describe me how you push mdt task sequences than after creating vm in azure? I am not sure if you push than a powershell for that. Maybe you can send me some powershell code to look into it how you make that? Regards Franco

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.