Category Archives: Virtual Machines

Setting Static IP addresses in a Microsoft Azure Virtual Network with PowerShell

I have finally had a chance to update the Windows Microsoft Azure PowerShell Guide.

The page is about the new functionality of assigning a static IP address to a virtual machine deployed in a Virtual Network.

Setting Static IP Address on Microsoft Azure Virtual Machine

Copy a Windows Azure Virtual Machine Between Subscriptions

While working on some recent training content focused on development and test with Windows Azure Rick Rainey and I thought a great scenario would be to have a script that can copy a single Windows Azure Virtual Machine from a source subscription to a destination subscription. This script will also copy a virtual machine between data center locations. There are tons of scenarios where this can be useful for dev/test so I will not enumerate them all here :)

Using the Script

This script uses the Windows Azure PowerShell cmdlets so they must be installed prior to use. Also, both the source and destination subscription must be configured for PowerShell access prior to use. See the following for information on getting started with the Windows Azure PowerShell Cmdlets.

  # Copy a virtual machine to a different subscription (no VNET)
  .\vmcopy.ps1 -SourceSubscription "source subscription" ` 
             -DestinationSubscription "destination subscription" ` 
             -VirtualMachineName "existingvmname" ` 
             -SourceServiceName "sourcecloudservice" ` 
             -DestinationServiceName "destinationcloudservice" ` 
             -DestinationStorageAccount "destinationstorageaccount" ` 
             -Location "West US" 
 
 
  # Copy a virtual machine to a different subscription and specify an existing virtual network and subnet. 
  .\vmcopy.ps1 -SourceSubscription "source subscription" ` 
               -DestinationSubscription "destination subscription" ` 
               -VirtualMachineName "existingvmname" ` 
               -SourceServiceName "sourcecloudservice" ` 
               -DestinationServiceName "destinationcloudservice" ` 
               -DestinationStorageAccount "destinationstorageaccount" ` 
               -VNETName "DestinationVNET" ` 
               -SubnetName "DestinationSubnet"

The script can be downloaded from within the TechNet Script Center: Virtual Machine Copy Script.

If you find any issues with the script or would just like to make it better we have it posted in GitHub as well: GitHub – Virtual Machine Copy Script and are interested in pull requests for improvements.

Of course, if you would like deeper training on Windows Azure to learn how to write scripts like this yourself we would be happy to help :)

New Windows Azure IaaS Training Courses Available

With the new year upon us we figured it would be a great time to announce new courses! We have recently added two new Windows Azure Infrastructure as a Service based courses that are immediately available for a dedicated onsite or remote class room style delivery.

Each course is two days in length, complete with hands on labs and a thorough introduction to Windows Azure Infrastructure Services (Virtual Machines and Virtual Networks). They are designed as “Jump Start” courses; meaning that they can quickly get students up to speed and proficient with the technology in a very short time period.


Windows Azure Training

Questions about the courses? Give us a call at: 866-833-3878 or email at info@opsgility.com.

Windows Azure – Disk Cleanup with Virtual Machines

In the latest Windows Azure Portal and PowerShell updates Microsoft has added some great functionality to manage disk cleanup with virtual machines.

Prior to these updates managing the cleanup of virtual machine disks was fairly painful. You either had to delete each disk one by one from the portal or use PowerShell code with some complex filtering and polling mechanism to remove them.

Deleting an Individual Virtual Machine and Disks from the Portal

In the portal when you select an individual virtual machine and on the bottom of the screen select Delete you are given two new options.

  • Keep the attached disks (doesn’t delete any disks)
  • Delete the attached disks (deletes all attached disks OS and Data)

delete vm windows azure portal

Deleting an Individual Virtual Machine and Disks from PowerShell

The equivelant functionality for the “Delete the attached disks” option from PowerShell is to append the -DeleteVHD parameter onto a call to Remove-AzureVM.

  Remove-AzureVM -ServiceName $serviceName -Name $vmName -DeleteVHD

Deleting all Virtual Machines and Disks in a Cloud Service from the Portal

If you need to remove all of the virtual machines and underlying disks in a specific cloud service you are covered too.
In the portal simply click CLOUD SERVICES on the left menu and find the cloud service hosting your virtual machines.

In the portal select a cloud service that contains virtual machines and on the bottom of the screen select Delete you are given three options.

  • Delete the cloud service and its deployments (deletes cloud service, all of the virtual machines (in the cloud service) and all disks attached to the virtual machines)
  • Delete all virtual machines (deletes all of the virtual machines (in the cloud service) but retains the disks)
  • Delete all virtual machines and attached disks (deletes all of the virtual machines in the cloud service and all of the disks but does not delete the cloud service)

portal delete cloud service and disks

To accomplish each of the tasks from PowerShell is straightforward.

Delete the cloud service and its deployments – equivalent PowerShell Code

Remove-AzureService -ServiceName $serviceName -DeleteAll

Delete all virtual machines (but not the cloud service or disks)

Remove-AzureDeployment -ServiceName $serviceName -Slot Production

Delete all virtual machines and attached disks (but not the cloud service)

Remove-AzureDeployment -ServiceName $serviceName -Slot Production -DeleteVHD

PowerShell for the rest
Finally, if you need to clean up disks that are no longer attached to virtual machines the PowerShell cmdlets come to the rescue.

Get-AzureDisk | where { $_.AttachedTo -eq $null } | select diskname, medialink

To delete an individual disk.

Remove-AzureDisk "disk name" -DeleteVHD

If you want to delete all of the disks that are not attached (be careful of this one – ensure you know what you are deleting before executing!).

Get-AzureDisk | where { $_.AttachedTo -eq $null } | Remove-AzureDisk -DeleteVHD

Summary
The ease of use of Windows Azure is getting better every day. What used to be a complex task (deleting disks after VM deletion) is now simplified without taking away the power that is available to the command line user. The Windows Azure team(s) are doing an amazingly good job of tackling tasks that were once difficult and making them much more manageable.

Bootstrapping a PowerShell DSC Pull Server and Client

Script Sample

This post describes a set of PowerShell scripts that can automatically provision a PowerShell DSC Pull Server and Client using Windows Azure Virtual Machines.

The scripts can be downloaded from here: Bootstrap PowerShell DSC in Windows Azure.
If you find bugs feel free to fork, fix and submit a pull request.

Before continuing

If you are brand new to Windows PowerShell DSC I recommend a slight detour from this post to watch the TechEd 2013 Introductory Session. Once you watch the TechEd session you should then read this blog post on how to configure a DSC Pull Server: Push and Pull Configuration Modes.

Ok, I feel better. You now should not only know what a DSC pull server is but you will likely appreciate the script more because it takes all of the complexity of putting together a DSC Pull Server and Client and wraps it up in two simple scripts. Not that I am saying you shouldn’t know how to do this on your own but if you need to quickly spin up an environment for a demo, testing or whatever it is nice not to have to reconstruct an environment from scratch each time.

Dependency

The scripts have a dependency on the Windows Azure PowerShell Cmdlets. So read this article to configure them if you haven’t already.

Creating a Pull Server

 
$subscription = "opsgilitytraining"
$serviceName = "mypullsvc"
$vmNamePull = "pullsrv"
$vmSize = "Small" 
$Location = "West US"
 
.\create-pull-srv.ps1 -SubscriptionName $subscription `
   -ServiceName $serviceName -Name $vmNamePull -Size $vmSize `
    -Location $location

What the script does:

  • Provisions a Server 2012 R2 VM in the “mypullsvc” cloud service in the West US data center. The VM name is “pullsrv”.
  • Creates a self-signed SSL certificate that is used to connect to the pull server and for encrypting stored passwords and automatically deploys it to the new virtual machine.
  • Uploads and executes the DSC Pull Server resource provider written by the PowerShell team.
  • Uploads a file that contains a helper function called SetConfiguration. This helper executes your DSC configuration file, generates a deterministic GUID based on the configuration name (so you don’t have to have a table of GUIDs handy) and creates the .mof files + checksums. Basically, all of the nasty work to create a DSC configuration in a pull server environment.
  • Once the server is provisioned login to the Pull Server via RDP.

     
    # if you don't want to leave your PowerShell session
    Get-AzureRemoteDesktopFile -ServiceName $serviceName -Name $vmNamePull -Launch

    Open the example configuration file C:\DSCScript\WebServer.ps1 in PowerShell_ISE and Hit F5. This will create your first bare bones configuration named WebServer on the pull server.

    Creating a Pull Client

    Note: The scripts have been designed to only allow deploying the client into the same cloud service as the pull server

    $vmNameClient = "pullclient"
    $configName = "WebServer"
     
    .\create-pull-client.ps1 -SubscriptionName $subscription `
       -ServiceName $serviceName -Name $vmNameClient -Size $vmSize `
       -CertificatePath .\PSDSCPullServerCert.pfx -PullServer $vmNamePull `
       -ConfigurationName $configName


    What the script does:

    • Provisions a Server 2012 R2 VM in the “mypullsvc” cloud service in the West US data center. The VM name is “pullclient”.
    • Deploys the previously created certificate PSDSCPullServerCert.pfx and also adds this cert to the LocalMachine\Root (trusted root authority) so it can be used with SSL.
    • Configures the client to point to the pull server using the DSC configuration name specified in -Configuration. The pull server has an example WebServer configuration that simply installs IIS that can be specified here.

    Testing the configuration

    Once the server is provisioned login to the Pull Client via RDP.

     
    # if you don't want to leave your PowerShell session
    Get-AzureRemoteDesktopFile -ServiceName $serviceName -Name $vmNameClient -Launch

    After patiently waiting 30+ minutes the configuration should be downloaded to your client VM. To validate this launch PowerShell and run:

     
    Get-DscConfiguration

    If all goes well you should see the following:
    PowerShell DSC

    Forcing DSC Configuration
    As of now there is no DSC cmdlet to force the client to pull a configuration. However, DSC is setup using scheduled tasks so you can force the task to run which will have your client check to see if it is up to date and if not apply the configuration.

     
    Get-ScheduledTask "Consistency" | Start-ScheduledTask

    Summary

    There you have it. Two simple scripts that can quickly get you up and running with PowerShell DSC.
    If you are interested in learning more about PowerShell DSC or Windows Azure in general for yourself or your organization we provide on-site or open enrollment Windows Azure and PowerShell Training.

Updating SQL Server AlwaysOn IP in Windows Azure

When deploying SQL Server AlwaysOn Availability Groups into Windows Azure with the listener enabled the configuration can break if the public IP address of the cloud service the SQL VMs are deployed into changes.

Cloud Service IP

The IP address of the cloud service hosting your SQL VMs can change if you shut down all the SQL Nodes at the same time using the Portal or PowerShell (and not using the -StayProvisioned flag in Stop-AzureVM). If this happens you will no longer be able to connect to the SQL Server through the listener until it is updated with the new IP of the cloud service when the VMs are restarted. This is a very common scenario with Dev/Test and proof of concepts because you may spin up the SQL servers but need to shut them down when not in use.

To make this easier from a DevOps perspective I have written a PowerShell script and published it to the TechNet Script Center that will update the listener IP address to the current IP Address of the cloud service.

Using the Script

The script does use the Windows Azure PowerShell cmdlets for automation so ensure they are setup and configured first.

Install and configure the Windows Azure PowerShell Cmdlets

Next you will need to enable CredSSP authentication since the script automates the other SQL nodes from the primary.

Enable CredSSP on your client machine for delegation before executing the script.

Example:
enable-wsmancredssp -role client -delegatecomputer “*.cloudapp.net”

Note:
This command will fail if your client machine is connected to any networks defined as “Public network” in “Network and Sharing Center.” of if PowerShell remoting has not previously been enabled with Enable-PSRemoting.

Run GPEdit.msc You must also enable delegating of fresh credentials using group policy editor on your client machine. Computer Configuration -> Administrative Templates -> System -> Credentials Delegation and then change the state of “Allow Delegating Fresh Credentials with NTLM-only server authentication” to “Enabled.” Its default state will say, “Not configured.”

Enable CredSSP on the primary SQL Server Node

enable-wsmancredssp -role client -delegatecomputer "*.cloudapp.net"

Install the WinRM certificate for the primary SQL Node

Download the script from the TechNet Script center:

Install WinRM Certificate for Windows Azure VMs

Example that installs the WinRM certificate (this allows secure remote PowerShell to the SQL Server VM)

$subName = "my subscription"
$cloudService = "MySQLAOCloudService"
$vmName = "SQLAO-01"
 
.\InstallWinRMCertAzureVM.ps1 -SubscriptionName $subName -ServiceName $cloudService -Name $vmName

Update the SQL Always On Listener IP

Download the SQL AlwaysOn IP Update script from the TechNet script center:

Update SQL Server Always On Listener IP Address in Windows Azure

Example of using the script to update a SQL AlwaysOn Availability Group.
The UpdateSQLAlwaysOnVIP.ps1 script will get the current IP address of the cloud service. Log in to the first SQL Node (SQLAO-01), update the IP cluster resource IP address and restart the SQL Nodes.

$avgroup = "SQLAG"
$nodes = "SQLAO-01", "SQLAO-02", "SQLAO-03"
.\UpdateSQLAlwaysOnVIP.ps1 -SubscriptionName $subName -ServiceName $cloudService -AvailabilityGroupName $avgroup -Nodes $nodes

SQL Always On References

Try out Server 2012 R2 RTM in Windows Azure

It was announced today that MSDN/TechNet subscribers can now download Server 2012 R2 and Windows 8.1 RTM.. Fantastic news if you have access to MSDN or TechNet :)

As of 9/9/2013 Server 2012 R2 RTM is not available as an image in Windows Azure. You can either wait for them to add it OR if you have access to the RTM bits you can add it yourself.

Step 1: Login to MSDN or TechNet and download the ISO

Step 2: Download the Convert-WindowsImage.ps1 PowerShell script to convert the ISO from MSDN/TechNet into a bootable VHD.

Step 3: Mount the ISO to your machine (double click it in Win8)

Step 4: Run the following to create the VHD:

 .\Convert-WindowsImage.ps1 -SourcePath "E:\sources\install.wim" -Edition ServerStandard -VHDPath D:\Server2012R2.VHD

Step 5: Use the Windows Azure PowerShell Cmdlets to Upload the VHD

Add-AzureVHD -Destination "https://<yourstorage>.blob.core.windows.net/images/Server2012R2.vhd" -LocalFilePath "D:\Server2012R2.VHD" -NumberOfUploaderThreads 5

Step 6: Register as an image.

Add-AzureVMImage -ImageName "Server2012R2" -OS Windows  -MediaLocation "https://<yourstorage>.blob.core.windows.net/images/Server2012R2.vhd"

Now, back in the portal or from PowerShell you can provision a new Server 2012 R2 VM from your very own custom image. My bet is the Windows Azure team will have an RTM Image of Server 2012 R2 in the Image Gallery and avoid the need for these steps but until then you can try out 2012 R2 in the cloud :)

Windows Azure PowerShell June 2013 Update for IaaS and PaaS

The latest release of the Windows Azure PowerShell cmdlets has a huge amount of functionality for both Windows Azure Virtual Machines and significant improvements to Cloud Services.

Virtual Machine Updates

  • Virtual Machine Stop Billing Support
  • Endpoint Access Control List Support
  • Endpoint Support Improvements

 Cloud Service Enhancements

  • Dynamically configure RDP per role or per service
  • Dynamically configure Diagnostics per role or per service

 Virtual Machine Stop Billing

It was announced at TechEd today that in addition to the huge improvement of per-minute billing when you stop a Virtual Machine you will not be charged. This functionality was exposed in PowerShell as well in the Stop-AzureVM cmdlet. One caveat I want to mention is if you stop the last VM in a deployment you will lose your deployment’s virtual IP address. If you want to stop the last VM but not lose your IP a new switch has been added -StayProvisioned. Stop-AzureVM will prompt you with a warning if you try to stop the last VM (with -StayProvisioned you will continue to be billed).

Virtual Machine Endpoint Access Control Support

A significant improvement in the security of virtual machines is the ability to lock down an endpoint so that only a specified set of IP addresses can access it.

To specify ACLs during or after deployment from PowerShell you create a new ACL configuration object using New-AzureAclConfig and then modify it with Set-AzureAclConfig. The created ACL object is then specified to the *-AzureEndpoint cmdlet in the -ACL parameter.

Example – Setting an ACL for SSH

$acl = New-AzureAclConfig
 
Set-AzureAclConfig -AddRule Permit -RemoteSubnet "209.116.0.0/16" -Order 1 `
                            -ACL $acl -Description "Lock down SSH"
 
Get-AzureVM -ServiceName mwlinuxsvc1 -Name mwlinux | 
    Set-AzureEndpoint -Name ssh -Protocol tcp -PublicPort 22 `
                      -LocalPort 22 -ACL $acl | 
    Update-AzureVM

Virtual Machine Other Endpoint Improvements

It is not a well known fact that prior to this release it was not possible to perform an update on a load balanced endpoint set. The underlying API would not actually support it. In this release a new API was added that allowed for the direct modification of a load balanced endpoint set.

To support this in PowerShell a new cmdlet called Set-AzureLoadBalancedEndpoint was added.
This cmdlet supports modifying a load balanced endpoint for operations such as changing health probe settings or port settings. Best of all this cmdlet can be called directly against this service and doesn’t require updating each individual endpoint.

Example of enabling an http health probe on an existing load balanced endpoint.

Set-AzureLoadBalancedEndpoint -ServiceName $svc -ProbeProtocolHTTP `
-LBSetName "lbweb" -ProbePath "/healthcheck" `
-ProbePort 80

Finally, a flag for enabling DirectServerReturn has been enabled on Add/Set Endpoint cmdlets. This flag allows you to enable DirectServerReturn on certain endpoints which in turn allows the server to respond directly to the client instead of funneling the response back through the load balanced.

Cloud Services – Enabling RDP and Diagnostics on Demand

A new concept called “Cloud Service Extensions” was recently added which allows certain code to be executed after a Cloud Service has been deployed. Currently, the only two extensions that have been published to date are RDP and Diagnostics.
The power of the extensions model is you do not have to repackage your application to enable/disable functionality like RDP and Diagnostics it can be done after the fact.

Both cmdlets support a -Role parameter which allows you to selectively enable or disable the extension.

Example of enabling RDP for all roles

$cred = Get-Credential
Set-AzureServiceRemoteDesktopExtension -ServiceName $svc -Credential $cred

Example on removing RDP from all roles

Remove-AzureServiceRemoteDesktopExtension -ServiceName $svc

A few things about the Cloud Service Extension architecture. The above example sets a default RDP configuration. So all roles will have the same user name / password. If you then called the cmdlet on an individual role the role would get its own settings. This is interesting when you remove the role specific settings because the default settings will still apply.
The cmdlets are smart enough to warn you of this behavior on use.

The other cmdlet that has been added is the Set-AzureServiceDiagnosticsExtension. It works exactly the same way but accepts a wadcfg.xml file that can configure diagnostics logging on the role or roles.

One final caveat – the RDP and Diagnostics extensions are not compatible with the legacy RDP and Diagnostics plugins that ship in the SDK. To take advantage of this dynamic behavior you will first need to remove the legacy plugins from your application and redeploy.

My Last Release :(

Sadly, this is the last release that I will have direct involvement in as I accepted a new job outside of Microsoft working with an outstanding Microsoft and Windows Azure Partner – Aditi. However, I will still continue to stay in tune with the Windows Azure PowerShell cmdlets and blog religiously about them (and email bugs and feature requests!).

The WA PowerShell/Runtime team is outstanding and I expect some great things from them going forward from the PowerShell and Service Management API front (hopefully, some powerful new Cloud Service Extensions will make their way out of Redmond as well)!

Windows Azure PowerShell Updates for IaaS GA

With the release of Windows Azure Virtual Machines and Virtual Networks into general availability the Windows Azure PowerShell team has been working feverishly to provide an even more powerful automation experience for deploying virtual machines in the cloud.

Remote PowerShell on Windows Azure – Automating Virtual Machines

One of the key requests we have heard from customers is to go beyond the current capabilities of automated infrastructure provisioning and allow the user to bootstrap a virtual machine as part of a fully automated deployment.

With this release we are announcing that Remote PowerShell will be enabled by default on Windows based virtual machines created with the latest version of the Windows Azure PowerShell Cmdlets.

Enabling Remote PowerShell allows a user to create a virtual machine and on boot immediately launch a script to bootstrap whatever configuration is desired. This could be installing and configuring Windows Roles and Features all the way to downloading and deploying an application or website. Authentication is over SSL for security and you can use your own certificate or we can even generate one for you. In addition to the bootstrapping abilities Remote PowerShell allows you to write powerful scripts for remote management and automation that can be ran at any time after the virtual machine is booted. The same scripts you use to manage your on-premises servers will work with your servers in Windows Azure. Of course, we do provide a switch to disable this functionality on boot if Remote PowerShell is not desired.

Installing Windows Server Features Automatically

In the example below the new -WaitForBoot parameter is used with New-AzureVM. This switch tells the cmdlet to wait for the virtual machine to be in the RoleReady (booted) state before continuing execution. Once the virtual machine is ready the script calls the Get-AzureWinRMUri cmdlet to retrieve the connection string to execute a remote script against the virtual machine. The script block passed to Invoke-Command installs the Web-Server IIS and the related management tools.

A PowerShell scripter could easily extend this script to automatically deploy a custom web application or service with just a few additional lines of code.

Installing Windows Features using Remote PowerShell

 
 
# Using this script installs the generated cert into your local cert store which allows 
# PowerShell to verify it is communicating with the correct endpoint. 
# This REQUIRES PowerShell run Elevated
. "C:\Scripts\WAIaaSPSRemotePS\InstallWinRMCert.ps1" 
 
$user = ""
$pwd = ""
$svcName = ""
$VMName = "webfe1" 
$location = "West US"
 
$credential = Get-Credential 
 
New-AzureVMConfig -Name $VMName -InstanceSize "Small" -ImageName $image |
                Add-AzureProvisioningConfig -Windows -AdminUsername $user -Password $pwd |
                Add-AzureEndpoint -Name "http" -Protocol tcp -LocalPort 80 -PublicPort 80 |
                New-AzureVM -ServiceName $svcName -Location $location -WaitForBoot 
 
# Get the RemotePS/WinRM Uri to connect to
$uri = Get-AzureWinRMUri -ServiceName $svcName -Name $VMName 
 
# Using generated certs – use helper function to download and install generated cert.
InstallWinRMCert $svcName $VMName 
 
# Use native PowerShell Cmdlet to execute a script block on the remote virtual machine
Invoke-Command -ConnectionUri $uri.ToString() -Credential $credential -ScriptBlock {
    $logLabel = $((get-date).ToString("yyyyMMddHHmmss"))
    $logPath = "$env:TEMPinit-webservervm_webserver_install_log_$logLabel.txt"
    Import-Module -Name ServerManager
    Install-WindowsFeature -Name Web-Server -IncludeManagementTools -LogPath $logPath
}

Contents of InstallWinRMCert.ps1

 
 
function InstallWinRMCert($serviceName, $vmname)
{
    $winRMCert = (Get-AzureVM -ServiceName $serviceName -Name $vmname | select -ExpandProperty vm).DefaultWinRMCertificateThumbprint
 
    $AzureX509cert = Get-AzureCertificate -ServiceName $serviceName -Thumbprint $winRMCert -ThumbprintAlgorithm sha1
 
    $certTempFile = [IO.Path]::GetTempFileName()
    $AzureX509cert.Data | Out-File $certTempFile
 
    # Target The Cert That Needs To Be Imported
    $CertToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $certTempFile
 
    $store = New-Object System.Security.Cryptography.X509Certificates.X509Store "Root", "LocalMachine"
    $store.Certificates.Count
    $store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
    $store.Add($CertToImport)
    $store.Close()
 
    Remove-Item $certTempFile
}

Image and Disk Mobility

Windows Azure is an open computing platform and allows for the movement of your virtual machine disks between on-premises and the cloud. There are two optimized cmdlets that enable either you to upload your VHD or download it.

Uploading a VHD

The first example shows how to upload a VHD to Windows Azure. This can be a bootable OS disk or simply a data disk (remove -OS Windows for data disks). After Add-AzureDisk is called you could use the New-AzureVMConfig cmdlet or the management portal to provision a virtual machine that boots off of the uploaded VHD.

 
 
$source = "C:vmstoragemyosdisk.vhd"
$destination = "https://&lt;yourstorage&gt;.blob.core.windows.net/vhds/myosdisk.vhd"
 
Add-AzureVhd -LocalFilePath $source -Destination $destination -NumberOfUploaderThreads 5
Add-AzureDisk -DiskName 'myosdisk' -MediaLocation $destination -Label 'mydatadisk' -OS Windows

Downloading a VHD

Not only can you upload a disk to Windows Azure but it is also easy to download a VHD as well! The example below shows how you can save a VHD to the local file system ready to run on a Hyper-V enabled system. (Note: a virtual machine should not write to the VHD at the same time you are trying to download it).

 
 
$source = "https://&lt;yourstorage&gt;.blob.core.windows.net/vhds/myosdisk.vhd"
$destination = "C:vmstoragemyosdisk.vhd"
Save-AzureVhd -Source $source -LocalFilePath $destination -NumberOfThreads 5

VMDK Conversion and Migration to Windows Azure

If you have VMWare based virtual machines that you would like to migrate you can use the Microsoft Virtual Machine Converter Solution Accelerator to convert the disks to VHDs and then use the Add-AzureVHD cmdlet to upload the VHD and create a virtual machine in Windows Azure from it.

Copying a VHD across Windows Azure Regions

 
 
# Source VHD (West US)
$srcUri = "http://&lt;yourweststorage&gt;.blob.core.windows.net/vhds/myosdisk.vhd"      
 
# Target Storage Account (East US)
$storageAccount = "&lt;youreaststorage&gt;"
$storageKey = "&lt;youreaststoragekey&gt;"
 
$destContext = New-AzureStorageContext  –StorageAccountName $storageAccount `
                                        -StorageAccountKey $storageKey  
 
# Container Name
$containerName = "vhds"
 
New-AzureStorageContainer -Name $containerName -Context $destContext
 
$blob = Start-AzureStorageBlobCopy -srcUri $srcUri `
                                   -DestContainer $containerName `
                                   -DestBlob "testcopy1.vhd" `
                                   -DestContext $destContext   
 
$blob | Get-AzureStorageBlobCopyState

Enhanced Security -AdminUserName is required for Windows (Breaking Change)

In order to protect you from unwanted attacks from connections attempting to use the dictionary on your password, we have made it mandatory to supply a username.
This change affects the New-AzureQuickVM and the Add-AzureProvisioningConfig cmdlets used for VM creation. Each will have a new –AdminUserName parameter that is now required.
Make sure you can remember it but do not use obvious names like Administrator or Admin.

High Memory Virtual Machine Support

The latest version of the WA PowerShell Cmdlets now support the new higher memory SKU sizes of A6 and A7 for larger workloads. For more information about Windows Azure compute sizes see the following: http://www.windowsazure.com/en-us/pricing/details/virtual-machines/.

high-mem-skus

Managing Availability Sets on Deployed VMs

We have also added the ability to specify availability set configuration for groups of virtual machines for highly available configurations. Previously, this could only be set at deployment time or post deployment from the Windows Azure Management Portal. For more information on availability sets see the following article:
http://www.windowsazure.com/en-us/manage/windows/common-tasks/manage-vm-availability/

 
 
Get-AzureVM -ServiceName "mywebsite" | Where {$_.Name -like "*web*"} | 
    Set-AzureAvailabilitySet -AvailabilitySetName "wfe-av-set" |
    Update-AzureVM

Wrapping Up

I hope you are excited about the new features in the Windows Azure PowerShell Cmdlets. If you would like to try this yourself you will need a subscription, to download the WA PowerShell Cmdlets and a short read on getting started.

Thanks!
Michael Washam
Senior Program Manager – Windows Azure