Windows Azure AD authentication support for PowerShell

Last week Microsoft announced several fantastic updates to Windows Azure.

One of the updates I’m really excited about is the new Windows Azure Active Directory authentication support in PowerShell.  Previously to allow the Windows Azure PowerShell cmdlets to authenticate with Windows Azure, you’re only choice was via a management certificate.  There were two options to get that certificate:

  1. Download a .publishsettings file and import the file (Get-AzurePublishSettingsFile and Import-AzurePublishSettingsFile)
  2. Create a cert yourself and configure it in PowerShell (see my previous post)

While not a bad way to go, they came with the overhead of deal with management certs.

Configuring Windows Azure Active Directory authentication in PowerShell

1) Get-AzureAccount – To start with, let’s run the Get-AzureAccount cmdlet to see what accounts are already configured.  Since this is my first time, there shouldn’t be any listed.

get_azureaccount

2) Add-AzureAccount – this will open a browser dialog prompting me to authenticate with the Microsoft Account (formerly Live ID) that I want to use for managing my Windows Azure subscriptions.  For me, this one Microsoft Account is a co-admin on multiple subscriptions, and just happens to be a user in multiple Windows Azure AD tenants.

add_azureaccount_login_1

add_azureaccount_login_2

3)  That’s pretty much it.  If I try to list all my subscriptions, I’ll can easily do that with Get-AzureSubscription.  Notice how there is a “ActiveDirectoryUserId” field.

add_azureaccount

get_azuresubscription

What did this actually do?

If I browse to my user profile directory (C:\Users\<username>\AppData\Roaming\Windows Azure Powershell), I can view the WindowsAzureProfile.xml file.  This is the file that was updated as a result of the Add-AzureAccount cmdlet.  It is basically what gets dumped when executing the Get-AzureSubscription cmdlet.

As noted here, the Windows Azure AD credentials available to PowerShell are good only for 12 hours.

See the most recent Windows Azure PowerShell change log at https://raw.github.com/WindowsAzure/azure-sdk-tools/master/ChangeLog.txt.

Advertisements

Setting a Web/Worker Role Name

I was recently reminded by my friend Nuno that you can actually set the name of the machine used in a Windows Azure Cloud Service (Web or Worker Role).  Normally I really don’t care about the name of the machine.  I’m fine with RD-whatever.

not_set_role_vm_name

If I did care, there is a way to set that machine name.  There is a “vmName” attribute in the Role element of the role’s .cscfg file.

<?xml version="1.0" encoding="utf-8"?>
<ServiceConfiguration serviceName="CloudServiceName" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration" osFamily="3" osVersion="*" schemaVersion="2013-10.2.2">
  <Role name="WebRole1" vmName="CollierWeb">
    <Instances count="1" />
    <ConfigurationSettings/>
  </Role>
</ServiceConfiguration>

Doing so will result in the machine name being set to whatever is in the “vmName” attribute, appended with the instance number (0, 1, 2, etc.)

set_role_vm_name
Keep in mind that the “vmName” attribute value must be less than 10 characters.

Note that the role name will still be whatever is set in the .cscfg, appended with the instance number.

role_name

For more on the schema of the .cscfg file, please see MSDN.

Billable Size of Windows Azure Blobs

I recently came across a PowerShell script that I think will be very handy for many Windows Azure users. The script calculates the billable size of Windows Azure blobs in a container, or the entire storage account. You can get the script at http://gallery.technet.microsoft.com/Get-Billable-Size-of-32175802.

Let’s walk through using this script:

0. Prerequisites

  • Windows Azure subscription. If you have MSDN, you can activate your Windows Azure benefits at http://bit.ly/140uAMt
  • Windows Azure storage account
  • Windows Azure PowerShell cmdlets (download and configure)

msdn-azure-banner-728x90

1. Select Your Windows Azure Subscription

Select-AzureSubscription -SubscriptionName "MySubscription"

2. Update PowerShell Execution Policy
You should only need to do this if your PowerShell execution policy prohibits running unsigned scripts. More on execution policy.

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

3. Calculate Blob Size for an Entire Storage Account

.\CalculateBlobCost.ps1 -StorageAccountName mystorageaccountname

VERBOSE: Loading module from path ‘C:\Program Files (x86)\Microsoft SDKs\Windows
Azure\PowerShell\Azure\.\Microsoft.WindowsAzure.Management.SqlDatabase.dll’.
VERBOSE: Loading module from path ‘C:\Program Files (x86)\Microsoft SDKs\Windows
Azure\PowerShell\Azure\.\Microsoft.WindowsAzure.Management.ServiceManagement.dll’.
VERBOSE: Loading module from path ‘C:\Program Files (x86)\Microsoft SDKs\Windows
Azure\PowerShell\Azure\.\Microsoft.WindowsAzure.Management.Storage.dll’.
VERBOSE: Loading module from path ‘C:\Program Files (x86)\Microsoft SDKs\Windows
Azure\PowerShell\Azure\.\Microsoft.WindowsAzure.Management.dll’.
VERBOSE: 12:16:39 PM – Begin Operation: Get-AzureStorageAccount
VERBOSE: 12:16:42 PM – Completed Operation: Get-AzureStorageAccount
VERBOSE: 12:16:42 PM – Begin Operation: Get-AzureStorageKey
VERBOSE: 12:16:45 PM – Completed Operation: Get-AzureStorageKey
VERBOSE: Container ‘deployments’ with 4 blobs has a size of 15.01MB.
VERBOSE: Container ‘guestbook’ with 4 blobs has a size of 0.00MB.
VERBOSE: Container ‘mydeployments’ with 1 blobs has a size of 12.55MB.
VERBOSE: Container ‘test123’ with 1 blobs has a size of 0.00MB.
VERBOSE: Container ‘vsdeploy’ with 0 blobs has a size of 0.00MB.
VERBOSE: Container ‘wad-control-container’ with 19 blobs has a size of 0.00MB.
VERBOSE: Container ‘wad-iis-logfiles’ with 15 blobs has a size of 0.01MB.
Total size calculated for 7 containers is 0.03GB.

4. Calculate Blob Size for a Specific Container within a Storage Account

.\CalculateBlobCost.ps1 -StorageAccountName mystorageaccountname `
-ContainerName deployments

VERBOSE: Loading module from path ‘C:\Program Files (x86)\Microsoft SDKs\Windows
Azure\PowerShell\Azure\.\Microsoft.WindowsAzure.Management.SqlDatabase.dll’.
VERBOSE: Loading module from path ‘C:\Program Files (x86)\Microsoft SDKs\Windows
Azure\PowerShell\Azure\.\Microsoft.WindowsAzure.Management.ServiceManagement.dll’.
VERBOSE: Loading module from path ‘C:\Program Files (x86)\Microsoft SDKs\Windows
Azure\PowerShell\Azure\.\Microsoft.WindowsAzure.Management.Storage.dll’.
VERBOSE: Loading module from path ‘C:\Program Files (x86)\Microsoft SDKs\Windows
Azure\PowerShell\Azure\.\Microsoft.WindowsAzure.Management.dll’.
VERBOSE: 12:12:48 PM – Begin Operation: Get-AzureStorageAccount
VERBOSE: 12:12:52 PM – Completed Operation: Get-AzureStorageAccount
VERBOSE: 12:12:52 PM – Begin Operation: Get-AzureStorageKey
VERBOSE: 12:12:54 PM – Completed Operation: Get-AzureStorageKey
VERBOSE: Container ‘deployments’ with 4 blobs has a size of 15.01MB.
Total size calculated for 1 containers is 0.01GB.

5. Calculate the Cost

The Windows Azure pricing calculator page should open immediately after the script executes. From there you can adjust the slider to the desired storage size, and view the standard price. The current price is $0.095 per GB for geo-redundant storage.  So this one storage account is costing me only $0.0027 per month. I can handle that.

azure storage cost

The Case of the Latest Windows Azure VM Image

When creating new Windows Azure VMs, an Operating System (OS) image needs to be specified.  Microsoft maintains a repository of images that are available to be used when creating a new VM.  These images could be regular Windows Server 2012 or Windows Server 2008 images, server images with software like SQL Server or BizTalk server installed, or even various Linux distributions.

To get a list of all available images, execute the Get-AzureVMImage cmdlet.  This will return a list of all possible images and details for each.

get-azurevmimage

Sometimes there may be multiple versions of a particular type of image.  For example, Microsoft will maintain a few versions of Window Server images – these very by patch level.

Notice the properties available (Location, Label, OS, ImageFamily, etc.) for each image.  These can be very helpful in narrowing the list of images.

Find the Image Type

In order to find a particular type of image, the ImageFamily property can be used.


Get-AzureVMImage `
| where { $_.ImageFamily -eq “Windows Server 2012 Datacenter” }

This returns details of only the Windows Server 2012 Datacenter images.

get-azurevmimage - imagefamily

Find the Latest Image

In order to find the most recent version of a particular type of image, the PublishDate property can be used to enhance the query.


$images = Get-AzureVMImage `
| where { $_.ImageFamily -eq “Windows Server 2012 Datacenter” } `
| Sort-Object -Descending -Property PublishedDate

$latestImage = $images[0]
$latestImage

Using the above snippet, only the most recent version of the “Windows Server 2012 Datacenter” image will be returned.

Images Aren’t Always Available

Take another look at the properties returned by Get-AzureVMImage.  Notice there is a Location property.  This specifies in which Windows Azure data centers the particular image is available.  All images may not be available in all data centers.  I’ve only seen this happen a few times, and it seemed to be related to a new OS image rolling out to the various data centers.  If trying to create a new VM with an image that is not supported in the target data center, the Windows Azure service management interface will return a 400 error related to a location constraint:

New-AzureVM : “An exception occurred when calling the ServiceManagement API. HTTP Status Code: 400. Service
Management Error Code: BadRequest. Message: The location constraint is not valid. Operation Tracking ID:
0ba6c633f3xxxxxxxxxxxxxxxxxxxxxx.”

To remedy this, slightly modify the script to include logic to select images that are only available in the desired data center location.


$images = Get-AzureVMImage `
| where { $_.ImageFamily -eq "Windows Server 2012 Datacenter" } `
	| where { $_.Location.Split(";") -contains "West US"} `
	| Sort-Object -Descending -Property PublishedDate

Using the above snippet, only the most recent version of the “Windows Server 2012 Datacenter” image that is supported in the “West US” datacenter will be returned.

Create the Virtual Machine

Now that the desired VM OS image has been found, the New-AzureVMConfig and New-AzureVM cmdlets can be used to create the new Virtual Machine.


# Get the latest version of the Windows Server 2012 Datacenter image.
$images = Get-AzureVMImage `
| where { $_.ImageFamily -eq $imageFamily } `
	| where { $_.Location.Split(";") -contains $location} `
	| Sort-Object -Descending -Property PublishedDate
$myVM = New-AzureVMConfig -Name “myvm01” -InstanceSize “Small” -ImageName $images[0].ImageName -DiskLabel "OS" `
| Add-AzureProvisioningConfig -Windows -Password $password -AdminUsername $username -DisableAutomaticUpdates

New-AzureVM -ServiceName “myvmservice” -VMs $myVM -Location “West US” -WaitForBoot

What’s New with Windows Azure? Lots!! (July 2013)

Earlier this month I had the pleasure to present for the first time at the Pittsburgh .NET User Group.  The timing worked out great as Microsoft’s spring/summer conferences were wrapping up – TechEd North America, TechEd Europe, BUILD, and Worldwide Partner Conference (WPC). There were a lot of exciting new Windows Azure features announced during this conferences.

My presentation was titled “What’s New with Windows Azure? Lots!!”. This was mostly a recap presentation – covering as many of the new Windows Azure updates as I could cram into about 90 minutes.

Speaking at the Pittsburgh .NET User Group was a lot of fun!  They have an excellent group and I hope to come back again.

BUILD 2013 Recap

This week I was fortunate to attend Microsoft’s BUILD event in San Francisco, CA.  BUILD is a semi-regular conference where Microsoft shares a few details on the future versions of Windows.  BUILD has essentially replaced PDC.

This was the first BUILD (or PDC) event I could attend in person.  I had a great time!  It was exciting to be around so many other passionate technologists all eager to see the future of Windows!

BUILD this year seemed to focus on Windows 8 and Windows Azure.  The keynote on day 1 was pretty much all Windows 8, and the day 2 keynote was pretty much all Windows Azure.  There was no keynote on day 3 – just lots of sessions to learn more about developing or designing apps for Windows 8 and Windows Azure.  There was very little related to Windows Phone 8 – that was kind of surprising to me.  Perhaps Microsoft has other events to focus more on their mobile strategy with Windows Phone 8.

WP_20130626_002 WP_20130626_001 WP_20130626_005

Day 1

Wednesday, June 26th was the first day of BUILD.  It started off with a keynote headlined by Steve Ballmer and complemented by several other Microsoft executives.  This keynote session was all about sharing the refinements Microsoft is making to the upcoming Windows 8.1 release.  Microsoft certainly seems to be trying to address most of the major complaints people had with Windows 8 (yes, the Start button is making a comeback).  In my opinion, there was nothing exceptionally new or exciting coming in Windows 8.1.  Most of the features shown during the BUILD keynote were already previously announced.  There were a few things, like native 3D printing support, that were pretty cool though.  Windows 8.1 certainly looks like a welcome update to Windows 8.  I’m going to be sure to install the Preview and give it a spin!

BUILD/PDC has been known for the attendee goodies.  This year did not disappoint.  Attendees were first treated to an Acer Iconia W3 – a 8″ tablet running a full version of Windows 8.  Later during the keynote, Microsoft’s Julie Larson-Green returned to the stage to announce all attendees would also receive a Surface Pro with a Type Cover!  I have a Surface RT already, but am certainly looking forward to playing with the Pro.

WP_20130626_003

Day 2

Day 2 kicked off with a keynote that focused on the new capabilities in Windows Azure.  As a Windows Azure geek, this was what I was really interested in!  Satya Nadella opened the keynote by sharing some of the details on the growth of the Windows Azure platform.  As someone that has been working with Windows Azure since PDC 2008, it’s exciting to see how fast the platform has changed and grown!

I think there were five big announcements on the Windows Azure front:

  1. General Availability of Windows Azure Web Sites and Windows Azure Mobile Services: Web Sites and Mobile Services are probably two of my favorite Windows Azure services.  It’s great to see the work the team has done!
  2. Auto-scaling for Cloud Services, Virtual Machines, and Web Sites: this is a feature people have been asking for since day 1.  Now, Windows Azure finally  can “check the box” on auto-scaling.  Right now auto-scaling is limited to scaling based on CPU and storage account queue depth.  I’m hoping that more metrics will be supported in the future.
  3. Service alerting for compute services (Cloud Services, VMs, Web Sites, and Mobile Services):  service administrators can now configure alerts for some of the various metrics collected for their Windows Azure services.  If a service exceeds a threshold (as specified in the rules the administrator creates), an email will be sent to the administrators.
  4. No credit card needed to activate Windows Azure benefits included with MSDN subscriptions: finally!  I can’t count how many times people complained to me about the need to use a credit card to active Windows Azure benefits already available to them as an MSDN subscriber.  Now that is no longer the case – making it much easier for people to take advantage of those benefits.
  5. Windows Azure Active Directory enhancements: there are some pretty nice tooling updates in Visual Studio 2013 Preview that will make working with Windows Azure AD even easier.  Scott Guthrie showed some pretty slick upcoming features related to very easy SaaS integration with Windows Azure AD – for integrating very easily with services like Box.  Very cool – looking forward to playing with this more soon!

For more information on these, and a few other tasty announcements, be sure to visit Scott Guthrie’s blog and the official Windows Azure team blog.

I spent a few hours hanging out at the Windows Azure booth.  There was A LOT of interest in Windows Azure!  I was there to help people get started with the platform, answer questions, and discuss ideas on how to solve a few problems.  Great conversations!!

Microsoft also threw a pretty nice attendee party at Pier 48.  It was a great way to see some more of San Francisco and hang out with the other BUILD attendees.  There was plenty of drinks to go around, and some unique (as in good) food from local food trucks.

WP_20130627_008 WP_20130628_007 WP_20130627_001

Day 3

The final day. There were no major announcements this day.  It was all about attending sessions to learn more.  My favorite session was “Building Big: Lessons Learned from Windows Azure Customers” by Mark Simms and Christian Martinez.  They were very honest about how to best handle scenarios where you’re targeting massive scale – think Halo4 or Skype sized scale.  They shared some great stories and tips!

Going Home

Overall I think BUILD 2013 was a great experience.  Being there in person, instead of watching recordings online, was certainly valuable.  The chance to interact with other BUILD attendees was fantastic as well.  While I had a great time, learned a lot, and had a great time, I’m very much looking forward to going home (as I write this waiting at SFO for my red-eye flight home).

Using Remote PowerShell with Windows Azure VMs

I’ve been doing a little more work with Windows Azure Virtual Machines and PowerShell lately. With the PowerShell cmdlets I can create VMs and Virtual Networks in a quick and repeatable fashion.  After the machines are created, I still need to configure the machines.  This is where Remote PowerShell can help.

Remote PowerShell

With Remote PowerShell, it’s possible to create a remote connection to the VM, and execute PowerShell cmdlets against that VM.  This allows us to remotely configure that VM – carrying out tasks like configuring Window Server roles and modifying other various settings.  See Michael Washam’s blog post for a great primer on Remote PowerShell with Windows Azure VMs.

One of the quirks I’ve noticed lately when working with Remote PowerShell sessions and Windows Azure VMs is that the Remote PowerShell session takes a little while to be “ready” even after the VM is started.  Let’s take the following scenario:

  1. Create a new VM
  2. Using Remote PowerShell, install & configure a new Windows Server role.  Part of the rule’s install process is to reboot the machine.
  3. After the machine reboots, connect again via Remote PowerShell to do some more work.

I’ve had several occasions where trying to connect to the VM after a reboot fails.  I assumed checking for the instance’s status to be “ReadyRole” would be sufficient.  Nope.

# Wait for server to reboot
$VMStatus = Get-AzureVM -ServiceName $serviceName -name $vmName

While ($VMStatus.InstanceStatus -ne "ReadyRole")
{
  write-host "Waiting...Current Status = " $VMStatus.Status
  Start-Sleep -Seconds 15

  $VMStatus = Get-AzureVM -ServiceName $serviceName -name $vmName
}

It’s the cloud – retry

Like most things in the cloud, in order to be successful you have to plan for failure and retry.  So even though the role might report that it is “ReadyRole”, that’s not enough for a Remote PowerShell session to connect reliably.

The steps I’ve taken to try to remedy this situation:

  1. Get the URI for Remote PowerShell on the  Windows Azure VM
  2. In a simple loop, continue to try to connect to the Remote PowerShell session.  If unsuccessful, wait for a few seconds and try again.
for($retry = 0; $retry -le 5; $retry++)
{
  try
  {
    $session = New-PSSession -ComputerName $uri[0].DnsSafeHost -Credential $credentials -Port $uri[0].Port -UseSSL
    if ($session -ne $null)
    {
      break
    }

    Write-Output "Unable to create a PowerShell session . . . sleeping and trying again in 30 seconds."
    Start-Sleep -Seconds 30
  }
  catch
  {
    Write-Output "Unable to create a PowerShell session . . . sleeping and trying again in 30 seconds."
    Start-Sleep -Seconds 30
  }
}

So far this approach seems to be working fairly well.  I’ve actually dropped this logic into a little function that returns the session.  That makes it a little easier to reuse across several different scripts.