Thought I’d create a new Azure VM using PowerShell than the web UI.
Turns out that has more options but is also a different sort of process. And it has some good features like directly domain joining a new VM. I assumed I could use some cmdlet like New-AzureVM
and give it all the VM details but it doesn’t quite work that way.
Here’s what I did. Note this is my first time so maybe I am doing things inefficiently …
First get a list of available images, specifically the Windows Server 2008 R2 images as that’s what I want to deploy.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# get a list of Images containing Windows Server 2008 R2 PS> Get-AzureVMImage | ?{ $_.ImageName -match "Win2K8R2SP1-Datacenter" } | fl ImageName,Label ImageName : a699494373c04fc0bc8f2bb1389d6106__Win2K8R2SP1-Datacenter-201410.01-en.us-127GB.vhd Label : Windows Server 2008 R2 SP1, October 2014 ImageName : a699494373c04fc0bc8f2bb1389d6106__Win2K8R2SP1-Datacenter-201411.01-en.us-127GB.vhd Label : Windows Server 2008 R2 SP1, November 2014 ImageName : a699494373c04fc0bc8f2bb1389d6106__Win2K8R2SP1-Datacenter-201412.01-en.us-127GB.vhd Label : Windows Server 2008 R2 SP1, December 2014 # the third image is what I want |
You don’t just use New-AzureVM
and create a VM. Rather, you have to first create a configuration object. Like thus:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
PS> $VMConfig = New-AzureVMConfig -Name RAX-SVR01 -InstanceSize Basic_A1 -ImageName "a699494373c04fc0bc8f2bb1389d6106__Win2K8R2SP1-Datacenter-201412.01-en.us-127GB.vhd" # for the curious here's what the object contains PS> $VMConfig AvailabilitySetName : ConfigurationSets : {} DataVirtualHardDisks : {} Label : RAX-SVR01 OSVirtualHardDisk : Microsoft.WindowsAzure.Commands.ServiceManagement.Model.OSVirtualHardDisk RoleName : RAX-SVR01 RoleSize : Basic_A1 RoleType : PersistentVMRole WinRMCertificate : X509Certificates : NoExportPrivateKey : False NoRDPEndpoint : False NoSSHEndpoint : False DefaultWinRmCertificateThumbprint : ProvisionGuestAgent : True ResourceExtensionReferences : DataVirtualHardDisksToBeDeleted : |
Now I can add more configuration bits to it. That’s using a different cmdlet, Add-AzureProvisioningConfig
. This cmdlet’s help page is worth a read.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
PS> $VMConfig | Add-AzureProvisioningConfig -WindowsDomain -Domain "MYDOMAIN" -DomainUserName "DomainUser" -DomainPassword "PasswordInPlaintext" -JoinDomain "MYDOMAIN" -DisableAutomaticUpdates -TimeZone "Arabian Standard Time" -AdminUsername "LocalUser" -Password "PasswordInPlaintext" AvailabilitySetName : ConfigurationSets : {RAX-SVR01, Microsoft.WindowsAzure.Commands.ServiceManagement.Model.NetworkConfigurationSet} DataVirtualHardDisks : {} Label : RAX-SVR01 OSVirtualHardDisk : Microsoft.WindowsAzure.Commands.ServiceManagement.Model.OSVirtualHardDisk RoleName : RAX-SVR01 RoleSize : Basic_A1 RoleType : PersistentVMRole WinRMCertificate : X509Certificates : {} NoExportPrivateKey : False NoRDPEndpoint : False NoSSHEndpoint : False DefaultWinRmCertificateThumbprint : ProvisionGuestAgent : True ResourceExtensionReferences : {BGInfo} DataVirtualHardDisksToBeDeleted : |
In my case I want to provision the VM and also join it to my domain (my domain’s up and running in Azure). So the switches I specify are accordingly. Here’s what they mean:
-AdminUsername
– a username that can locally manage the VM (this is a required parameter)-Password
– password for the above username (this is a required parameter)-TimeZone
– timezone for the VM-DisableAutomaticUpdates
– I’d like to disable automatic updates-WindowsDomain
– specifies that the VM will be domain joined (I am not sure why this is required; I guess specifying this switch will make all the domain related switches manadatory so this way the cmdlet can catch any missing switches) (this is a required parameter; you have to specifyWindows
,Linux,
orWindowsDomain
)-JoinDomain
– the domain to join-DomainUserName
– a username that can join this VM to the above domain-Domain
– the domain to which the above username belongs-DomainPassword
– password for the above username
Good so far? Next I have to define the subnet(s) to which this VM will connect.
1 2 3 4 5 |
PS> $VMConfig | Set-AzureSubnet -SubnetNames "subnet" # the output's just the VMConfig object; no indication of success or failure # to double check whether the subnet was added one can do the following: PS> $VMConfig | Get-AzureSubnet |
Specify a static IP if you’d like.
1 |
PS> $VMConfig | Set-AzureStaticVNetIP -IPAddress "192.168.23.10" -Verbose |
Finally I create the VM. In this case I will be putting it into a new Cloud Service so I have to create that first …
1 2 3 4 5 6 7 8 9 10 11 12 13 |
PS> New-AzureService -ServiceName RAX-SVR01 -Location "Southeast Asia" OperationDescription OperationId OperationStatus -------------------- ----------- --------------- New-AzureService 5b1deef6-3fa1-5226-a776-867edaad6603 Succeeded # create the VM; the VNet needs to be specified, doesn't just pick it up from the subnet name (coz you could have the same subnet name in multiple VNets) PS> $VMConfig | New-AzureVM -ServiceName RAX-SVR01 -VNetName "vnet" OperationDescription OperationId OperationStatus -------------------- ----------- --------------- New-AzureVM 09f6f243-3ab0-58ac-9d90-eb6c135f7ed4 Succeeded |
That’s it. Wrap all this up in a script and deploying new VMs will be easy peasy!