Upcoming Microsoft Azure Training Classes

We have several upcoming training opportunities for Microsoft Azure. If you are interested in Microsoft Azure Websites, an introduction to Microsoft Azure Infrastructure Services or if you need deep dive training that is very hands on focused on Infrastructure services we have you covered.

Microsoft Azure IaaS JumpStart Webinar

Date: 7/29/2014

More Details and Registration

Microsoft Azure IaaS Deep-Dive Remote Classroom (online)

Date: 8/4/2014 – 8/8/2014

More Details and Registration

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.

Windows Azure Training

Introducing Opsgility – my new venture

Over the past few months a good friend of mine Rick Rainey and myself have discussed starting a business together. We both saw a huge need for solid technical training for organizations looking at Windows Azure as their cloud provider of choice. There were three primary reasons that convinced us to start a new business:

  • The first reason is we think Windows Azure is going to be a smashing success for Microsoft. I’ve talked to enough Microsoft customers to see which way the wind is blowing and with my experience on the Windows Azure engineering team I know how hard they work and how fast they can innovate. It is only going to get better!

  • The second reason is Windows Azure is evolving very fast and keeping up with the changes to create always up to date content requires a full time commitment to training. We think this is a very valuable service to customers and also think we are just the people to do it.

  • The third reason is no one else is doing it. If you are an organization that needs deep focused training for your IT Staff or Developers there are not many (if any) options out there. This is a tricky reason.. It could be the reason there is a lack of Windows Azure trainers is because there isn’t a market for it. We do not believe that for a second. We believe that we are on the bleeding edge of a huge opportunity!

It just happens that we both have deep expertise with Windows Azure and PowerShell and have been working closely with and on the platform for years. We both have a passion for training and public speaking so it seems like a no brainer to create our new company, Opsgility.

Opsgility, is a training company focused on Windows Azure and DevOps practices. We provide deep, immersive and hands-on training for Technology Leaders, IT Professionals and Developers. We deliver open enrollment training in areas all over the United States and we will likely start international open enrollment deliveries very soon. Additionally, we will provide onsite private training at your organization in the United States or abroad (tropical locations are a plus!).

If you are interested in Windows Azure or building DevOps into your organization skillsets and would like to learn more about our services please visit our website: Opsgility.com or give us a call: 1-866-833-3878!

Click here to read Opsgility’s CTO and Co-founder Rick Rainey’s Announcement.

P.S. If you are a Windows Azure or PowerShell Expert and would like to help us teach the world about Windows Azure and DevOps shoot us an email: info@opsgility.com

Thanks!
Michael Washam
CEO and Co-Founder Opsgility
michael@opsgility.com

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

Calling the Windows Azure Management API from PowerShell

Most of the time using the Windows Azure PowerShell cmdlets will accomplish whatever task you need to automate. However, there are a few cases where directly calling the API directly is a necessity.

In this post I will walk through using the .NET HttpClient object to authenticate and call the Service Management API along with the real world example of creating a Dynamic Routing gateway (because it is not supported in the WA PowerShell cmdlets).

To authenticate to Windows Azure you need the Subscription ID and a management certificate. If you are using the Windows Azure PowerShell cmdlets you can use the built in subscription management cmdlets to pull this information.

 $sub = Get-AzureSubscription "my subscription" 
 $certificate = $sub.Certificate
 $subscriptionID = $sub.SubscriptionId

For API work my preference is to use the HttpClient class from .NET. So the next step is to create an instance of it and set it up to use the management certificate for authentication.

$handler = New-Object System.Net.Http.WebRequestHandler
 
# Add the management cert to the client certificates collection 
$handler.ClientCertificates.Add($certificate)  
$httpClient = New-Object System.Net.Http.HttpClient($handler)
 
# Set the service management API version 
$httpClient.DefaultRequestHeaders.Add("x-ms-version", "2013-08-01")
 
# WA API only uses XML 
$mediaType = New-Object System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/xml")
$httpClient.DefaultRequestHeaders.Accept.Add($mediaType)

Now that the HttpClient object is setup to use the management certificate you need to generate a request.

The simplest request is a GET request because any parameters are just passed in the query string.

# The URI to the API you want to call 
# List Services API: http://msdn.microsoft.com/en-us/library/windowsazure/ee460781.aspx
$listServicesUri = "https://management.core.windows.net/$subscriptionID/services/hostedservices"
 
# Call the API 
$listServicesTask = $httpClient.GetAsync($listServicesUri)
$listServicesTask.Wait()
if($listServicesTask.Result.IsSuccessStatusCode -eq "True")
{
    # Get the results from the API as XML 
    [xml] $result = $listServicesTask.Result.Content.ReadAsStringAsync().Result
    foreach($svc in $result.HostedServices.HostedService)
    {
        Write-Host $svc.ServiceName " "  $svc.HostedServiceProperties.Location 
    }
}

However, if you need to do something more complex like creating a resource you can do that as well.

For example, the New-AzureVNETGateway cmdlet will create a new gateway for your virtual network but it was written prior to the introduction of Dynamic Routing gateways (and they have not been updated since…).
If you need to create a new virtual network with a dynamically routed gateway in an automated fashion calling the API is your only option.

$vnetName = "YOURVNETNAME"
 
# Create Gateway URI
# http://msdn.microsoft.com/en-us/library/windowsazure/jj154119.aspx 
$createGatewayUri = "https://management.core.windows.net/$subscriptionID/services/networking/$vnetName/gateway"
 
# This is the POST payload that describes the gateway resource 
# Note the lower case g in <gatewayType - the documentation on MSDN is wrong here
$postBody = @"
<?xml version="1.0" encoding="utf-8"?>
<CreateGatewayParameters xmlns="http://schemas.microsoft.com/windowsazure">
  <gatewayType>DynamicRouting</gatewayType>
</CreateGatewayParameters>
"@
 
Write-Host "Creating Gateway for VNET" -ForegroundColor Green
$content = New-Object System.Net.Http.StringContent($postBody, [System.Text.Encoding]::UTF8, "text/xml")        
# Add the POST payload to the call    
$postGatewayTask = $httpClient.PostAsync($createGatewayUri, $content)
$postGatewayTask.Wait()
 
# Check status for success and do cool things

So there you have it.. When the WA PowerShell cmdlets are behind the times you can quickly unblock with some direct API intervention.