Quantcast
Channel: TechNet Technology News
Viewing all articles
Browse latest Browse all 13502

Automation–Automating Hybrid Clouds with Windows Azure and PowerShell (Part 2): Public Cloud Environment Provisioning PowerShell Examples

$
0
0

Hello Again!

Time for Part 2 of the Automating Hybrid Clouds with Windows Azure and PowerShell blog series (find Part 1: Intro & TOC here).  And yes, this post actually has PowerShell Examples! But first, the list of what examples will be provided…


Public Cloud Environment Provisioning PowerShell Examples

As covered in the intro post of the blog series, the following is the list of high level concept commands that will be covered in this post:

High Level Concept Commands

  1. Establish Windows Azure Subscription Connection
  2. Create Windows Azure Affinity Group
  3. Create Windows Azure Cloud Service
  4. Create Windows Azure Storage Account
  5. Create Windows Azure Storage Container
  6. Upload “On-Prem” VHD to Windows Azure Storage Container
  7. Copy Windows Azure Blob
  8. Create Windows Azure VM Image
  9. Create Windows Azure VM

Pre-Requisites

Here is the short list of pre-requisites for this example solution:

  1. Windows Server
  2. A VHD file that meets the requirements to be uploaded to Windows Azure
  3. Windows Azure PowerShell Module
    Direct
    Download Link: http://go.microsoft.com/?linkid=9811175&clcid=0x409

Establish Windows Azure Subscription Connection

Automation often requires “trust”, especially between two endpoints in any given process/scenario solution. This example is no exception. The connection between the “On-Prem” Windows Server and Windows Azure need to share a “trust”. For Windows Azure (and for this example), one of the most common ways to accomplish this is through “the certificate method” (outlined in this Windows Azure tutorial: How to install and configure Windows Azure PowerShell).

Basically, it leverages the following:

  • The Get-AzurePublishSettingsFile cmdlet opens a web page on the Windows Azure Management Portal, from which you can download the subscription information. The information is contained in a .publishsettings file.
  • The Import-AzurePublishSettingsFile imports the .publishsettings file for use by the module. This file includes a management certificate that has security credentials.

Example Script (with some instructional comments)

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019

#0.0. Perform Prerequisite Setup Steps

#0.1. Download latest Windows Azure PowerShell Module: http://go.microsoft.com/?linkid=9811175&clcid=0x409

#0.2. Execute: Get-AzurePublishSettingsFile; Save .publishsettings file locally


    Get-AzurePublishSettingsFile

#0.3. Execute: Import-AzurePublishSettingsFile; reference local .publishsettings file

    $AzurePublishSettingsFile = "C:\Your_Local_Path\Your Windows Azure Subscription Name-MM-DD-YYYY-credentials.publishsettings"
    Import-AzurePublishSettingsFile -PublishSettingsFile $AzurePublishSettingsFile

#0.4. Execute: Set-AzureSubscription and Select-AzureSubscription (and then, to verify Execute: Get-AzureSubscription)

    $AzureSubscriptionName = "Windows Azure MSDN - Visual Studio Ultimate"
    Set-AzureSubscription -SubscriptionName $AzureSubscriptionName
    Select-AzureSubscription -SubscriptionName $AzureSubscriptionName
    Get-AzureSubscription

Note     I recommend running these commands individually (not all at once) by the groups above.

Execution Results

As part of this process, you will notice a new Management Certificate in the Windows Azure Portal:

image

If everything was successful, the Get-AzureSubscription results should look similar to this:

image


Connection Established – Moving On…

Now that we have established a good connection to Windows Azure, we can take care of the rest of the automated steps to build out the environment.

Reminder     Obviously, there are other methods and concepts to be automated for Windows Azure - these are just the ones I chose for the examples in this blog series.

Setting up the Environment with a “Project Name”

There is one variable that impacts the entire script and resulting environment. This needs to be set first, and will be used throughout:

  • $ProjectName: This is the over-arching variable that will be used (in part or whole) throughout the example. Many other variables are set based on this value.
001
$ProjectName = "BCBDemo"

Note     If you run this example all the way through as a test, you will see how pervasive this variable’s value actually is. Even if you just look through the “Execution Results” from each step it is apparent. This is for example purposes only. I wanted to simplify the scripts and number of variable inputs.


Create Windows Azure Affinity Group

First step for these examples is to create a Windows Azure Affinity Group within Windows Azure for the environment being built. There is one variable that you will want to consider updating to fit your environmental needs/requirements:

  • $AGLocation: The Location the Affinity Group for this Environment/Project is associated with.
001
002
003
004
005
006
007
008
009
010
011
012

$AGName = $ProjectName
$AGLocation
 = "West US"
$AGLocationDesc = "Affinity group for $ProjectName VMs"
$AGLabel = "$AGLocation $ProjectName"

$AzureAffinityGroup = Get-AzureAffinityGroup -Name $ProjectName -ErrorAction SilentlyContinue

if(!$AzureAffinityGroup) {
    $AzureAffinityGroup = New-AzureAffinityGroup -Location $AGLocation -Name $ProjectName -Description $AGLocationDesc -Label $AGLabel
}

$AzureAffinityGroup

Note     All variable values were chosen for this example only, and can be changed to fit your project needs.

Execution Results

image

image


Create Windows Azure Cloud Service

Next up, is to create a Windows Azure Cloud Service within Windows Azure for the environment being built. There are no new unique variables that require value updates.

001
002
003
004
005
006
007
008
009
010

$CloudServiceDesc = "Service for $ProjectName VMs"
$CloudServiceLabel = "$ProjectName VMs"

$AzureService = Get-AzureService -ServiceName $ProjectName -ErrorAction SilentlyContinue

if(!$AzureService) {
    $AzureService = New-AzureService -AffinityGroup $AGName -ServiceName $ProjectName -Description $CloudServiceDesc -Label $CloudServiceLabel
}

Return $AzureService

Note     This portion of the script depends on the previous two.

Execution Results

image

image


Create Windows Azure Storage Account

Next, is to create a Windows Azure Storage Account within Windows Azure for the environment being built. There are no new unique variables that require value updates.

001
002
003
004
005
006
007
008
009
010
011

$StorageAccountName = $ProjectName.ToLower()
$StorageAccountDesc = "Storage account for $ProjectName VMs"
$StorageAccountLabel = "$ProjectName Storage"

$AzureStorageAccount = Get-AzureStorageAccount -StorageAccountName $StorageAccountName -ErrorAction SilentlyContinue

if(!$AzureStorageAccount) {
    $AzureStorageAccount = New-AzureStorageAccount -AffinityGroup $AGName -StorageAccountName $StorageAccountName -Description $StorageAccountDesc -Label $StorageAccountLabel
}

$AzureStorageAccount

Note     This portion of the script depends on the previous three.

Execution Results

image

image


Create Windows Azure Storage Container(s)

Next, is to create Two Windows Azure Storage Containers within Windows Azure for the environment being built. There are no new unique variables that require value updates.

Reason for Two Storage Containers

  • Storage Container #1:Generic VHD Storage Container– “On-Prem” VHD will be uploaded to this container
  • Storage Container #2:Project Specific Storage Container– Uploaded VHD will be copied here (this is the VHD that will be leveraged for the rest of the example)

Note     Creation of two Storage Containers in this example was to ensure I always had a “known good” copy of the uploaded VHD/Blob.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027

#Ensure Storage Account is fully created - Sleep for 60 seconds
Start-Sleep -Seconds 60

#Update the Azure Subscription Connection with the Storage Account
#This makes it easier to connect to the storage account, without requiring the creation and usage of Storage Context


$AzureStorageAccountName = $ProjectName.ToLower()
Set-AzureSubscription -SubscriptionName $AzureSubscriptionName -CurrentStorageAccount $AzureStorageAccountName

#Create Generic VHD Storage Container; VHD will be uploaded here
$GenericStorageContainerName = "vhds"

#Create Project Storage Container; VHD will be copied here
$ProjectStorageContainerName = $ProjectName.ToLower()

$StorageContainerNames = @($GenericStorageContainerName,$ProjectStorageContainerName)

foreach ($StorageContainerName in $StorageContainerNames) {

    $AzureStorageContainer = Get-AzureStorageContainer -Name $StorageContainerName -ErrorAction SilentlyContinue

    if(!$AzureStorageContainer) {
        $AzureStorageContainer = New-AzureStorageContainer -Name $StorageContainerName
    }

    $AzureStorageContainer
}

Note     This portion of the script depends on the previous four.

Execution Results

image

image


Upload “On-Prem” VHD to Windows Azure Storage Container

Next, is to upload the “On-Prem” VHD to the Generic Windows Azure Storage Container within Windows Azure for the environment being built. This portion of PowerShell does require some customization, as it references the previously mentioned, “…VHD file that meets the requirements to be uploaded to Windows Azure”:

  • $SourceDiskName: The Name of the VHD (without .vhd extension) to be uploaded to the Generic Windows Azure Storage Container.
  • $SourceDiskPath: The Path of the VHD (without trailing "\") to be uploaded to the Generic Windows Azure Storage Container.
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022

#Set Source VHD Info
$SourceDiskName = "toWindowsAzure"
$SourceDiskFileExt = "vhd"
$SourceDiskPath = "D:\Drop\Azure\toAzure"
$SourceVHDName = "{0}.{1}" -f $SourceDiskName,
$SourceDiskFileExt
$SourceVHDPath
 = "{0}\{1}" -f $SourceDiskPath,$SourceVHDName

#Set Destination Blob Info
$DesitnationVHDName = "{0}.{1}" -f $ProjectName,
$SourceDiskFileExt
$DestinationVHDPath
 = "https://{0}.blob.core.windows.net/{1}" -f $AzureStorageAccountName,
$GenericStorageContainerName
$DestinationBlobURI
 = "{0}/{1}" -f $DestinationVHDPath,
$DesitnationVHDName
$OverWrite
 = $false

#Upload Local VHD to the Generic VHD Windows Azure Storage Container; this will take a while
$AzureBlob = Get-AzureStorageBlob -Container $GenericStorageContainerName -Blob $DesitnationVHDName -ErrorAction SilentlyContinue
   
if(!$AzureBlob -or $OverWrite) {

    $AzureBlob = Add-AzureVhd -LocalFilePath $SourceVHDPath -Destination $DestinationBlobURI -OverWrite:$OverWrite
}

$AzureBlob

Note     This portion of the script depends on the previous five.

The following is an image (not that it is really needed, but for proof), of the file and path of the VHD I am uploading in this example:

image

Execution Results

Because this step takes a while, when you run the example PowerShell above, you have the opportunity to see the ongoing status within the PowerShell console. Here is a screenshot of the process, mid-execution:

image

Note     Over a fast connection, a file of this size (7.5GB) takes about 10 minutes to upload (as seen in the results below).

image

image


Copy Windows Azure Blob

Next, is to copy the uploaded VHD (now a Windows Azure Blob) from the Generic Container (vhds) to the Project Specific Container within Windows Azure for the environment being built. There are no new unique variables that require value updates.

Note     Usage of two Storage Containers in this example was to ensure I always had a “known good” copy of the uploaded VHD/Blob.

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019

#Set Source Blob Info for Copy

$SourceBlobName = 
$DesitnationVHDName
$SourceContainer
 = $GenericStorageContainerName

#Set Destination Blob Info for Copy

$DestinationContainer = 
$ProjectStorageContainerName
$DestinationBlobName
 = "{0}_copy.{1}" -f $ProjectName,
$SourceDiskFileExt

$CopiedAzureBlob
 = Get-AzureStorageBlob -Container $DestinationContainer -Blob $DestinationBlobName -ErrorAction SilentlyContinue

#Copy Uploaded Blob from Generic to Project
if(!$CopiedAzureBlob) {

    $CopiedAzureBlob = Start-AzureStorageBlobCopy -DestContainer $DestinationContainer -SrcBlob $SourceBlobName -SrcContainer $SourceContainer -DestBlob $DestinationBlobName
}
   
Return $CopiedAzureBlob

Note     This portion of the script depends on the previous six.

Execution Results

image

image


Create Windows Azure VM Image

Next, is to create an Azure VM Image from copied blob within Windows Azure for the environment being built. There are no new unique variables that require value updates as $VMImageOS likely will remain “Windows” for the VHDs uploaded.

001
002
003
004
005
006
007
008
009
010
011
012
013
014

$VMImageName = $ProjectName
$VMImageBlobContainer
 = 
$DestinationContainer
$VMImageBlobName
 = 
$DestinationBlobName
$VMImageOS
 = "Windows"

$AzureVMImage = Get-AzureVMImage -ImageName $VMImageName -ErrorAction SilentlyContinue
   
if(!$AzureVMImage) {

    $AzureBlobMediaLocation = (Get-AzureStorageBlob -Container $VMImageBlobContainer -Blob $VMImageBlobName).ICloudBlob.Uri.AbsoluteUri
    $AzureVMImage = Add-AzureVMImage -ImageName $VMImageName -MediaLocation $AzureBlobMediaLocation -OS $VMImageOS
}
   
Return $AzureVMImage

Note     This portion of the script depends on the previous seven.

Execution Results

image

image


Create Windows Azure VM

Next, (what we all have been waiting for!) is to create a Windows Azure VM from the Windows Azure VM Image within Windows Azure for the environment being built. This portion of PowerShell does require some customization:

  • $VMName: The Name of the VM being created – the example I show here is a simple numbering suffix. It is not a mask of any kind, but something that generates a sequencing integer could be created. If you are uploading a large number of VM to create Windows Azure VMs, you would likely be referencing VM Name (and most other things) from an external data source. Either way, it is up to you, this is just example naming.
  • $AdminUsername: The Name of the Admin User for initial login to the Windows Azure VM. This cannot be "Administrator".
  • $Password: The Password for the Admin User for initial login to the Windows Azure VM.
  • $Windows: The OS of Windows Azure VM. Again, this will likely remain “Windows” for the VHDs uploaded.
  • $VMInstanceSize: The VM Instance Size for the Windows Azure VM (options available, reference the following: Virtual Machine and Cloud Service Sizes for Windows Azure).
  • $WaitForBoot: The option to wait for the Windows Azure VM to finish "Provisioning" before releasing control back to the PowerShell console.
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018

$VMName = "{0}-001" -f $ProjectName.ToLower()
$ServiceName = 
$ProjectName
$AdminUsername
 = "AdminUser"
$VMImageName = $AzureVMImage.ImageName
$Password = "Pass@word1"
$Windows = 
$true
$VMInstanceSize
 = "ExtraSmall"
$WaitForBoot = 
$true

$AzureVM
 = Get-AzureVM -Name $VMName -ServiceName $ServiceName -ErrorAction SilentlyContinue
   
if(!$AzureVM -and $Windows) {

    $AzureVM = New-AzureQuickVM -AdminUsername $AdminUsername -ImageName $VMImageName -Password $Password `
        -ServiceName $ServiceName -Windows:$Windows -InstanceSize $VMInstanceSize -Name $VMName -WaitForBoot:$WaitForBoot
}
   
Return $AzureVM

Note     This portion of the script depends on the previous eight. Also, the method used to create the Windows Azure VM in this example was New-AzureQuickVM, there are other methods – Please see some examples below (after the "Putting it all together" section).

Execution Results

Because this step takes a while, you have the opportunity to see the ongoing status within the Windows Azure Portal. Here is a screenshot of the Windows Azure VM creation, mid-execution:

image

Note     "Provisioning" durations vary.

image

image


Connecting to the Windows Azure VM

Once provisioned, it is simple to connect directly to the Windows Azure VM to test its contents.

Step 1: Select the Windows Azure VM, Click Connect

image

Step 2: When prompted, Open the RDP file that is presented

image

Step 3: When prompted, Enter the credentials you provided within the Create Windows Azure VM PowerShell Script

image

Step 4: Wait for the RDP Session to complete and connect you to the Windows Azure VM

image

Step 5: Use/Explore the Windows Azure VM

image

Note     Obviously nothing was done to customize the network for this VM. Windows Azure Virtual Network was out of scope for this example. For more information, please refer to the following: Windows Azure Virtual Network Overview.


A Dashboard View of the created Windows Azure VM

image

image


Putting it all together

I realize this is more than “like 5 lines of PowerShell”. But in reality, if you had the Windows Azure environment already created, that number isn’t that far off. Either way, here are all the above PowerShell script portions, rolled up into one script example:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

#0.0. Perform Prerequisite Setup Steps

#0.1. Download latest Windows Azure PowerShell Module: http://go.microsoft.com/?linkid=9811175&clcid=0x409

#0.2. Execute: Get-AzurePublishSettingsFile; Save .publishsettings file locally


    Get-AzurePublishSettingsFile 

#0.3. Execute: Import-AzurePublishSettingsFile; reference local .publishsettings file

    $AzurePublishSettingsFile = "C:\Your_Local_Path\Your Windows Azure Subscription Name-MM-DD-YYYY-credentials.publishsettings" 
    Import-AzurePublishSettingsFile -PublishSettingsFile $AzurePublishSettingsFile 

#0.4. Execute: Set-AzureSubscription and Select-AzureSubscription (and then, to verify Execute: Get-AzureSubscription)

    $AzureSubscriptionName = "Windows Azure MSDN - Visual Studio Ultimate" 
    Set-AzureSubscription -SubscriptionName $AzureSubscriptionName 
    Select-AzureSubscription -SubscriptionName $AzureSubscriptionName 
    Get-AzureSubscription

#1.0 Setting up the Environment with a “Project Name”
$ProjectName = "BCBDemo"

#2.0 Create Windows Azure Affinity Group
$AGName = $ProjectName 
$AGLocation = "West US" 
$AGLocationDesc = "Affinity group for $ProjectName VMs" 
$AGLabel = "$AGLocation $ProjectName" 

$AzureAffinityGroup = Get-AzureAffinityGroup -Name $ProjectName -ErrorAction SilentlyContinue 

if(!$AzureAffinityGroup) { 
    $AzureAffinityGroup = New-AzureAffinityGroup -Location $AGLocation -Name $ProjectName -Description $AGLocationDesc -Label $AGLabel 
} 

$AzureAffinityGroup 

#3.0 Create Windows Azure Cloud Service
$CloudServiceDesc = "Service for $ProjectName VMs" 
$CloudServiceLabel = "$ProjectName VMs" 

$AzureService = Get-AzureService -ServiceName $ProjectName -ErrorAction SilentlyContinue 

if(!$AzureService) { 
    $AzureService = New-AzureService -AffinityGroup $AGName -ServiceName $ProjectName -Description $CloudServiceDesc -Label $CloudServiceLabel 
} 

Return $AzureService 

#4.0 Create Windows Azure Storage Account
$StorageAccountName = $ProjectName.ToLower() 
$StorageAccountDesc = "Storage account for $ProjectName VMs" 
$StorageAccountLabel = "$ProjectName Storage" 

$AzureStorageAccount = Get-AzureStorageAccount -StorageAccountName $StorageAccountName -ErrorAction SilentlyContinue 

if(!$AzureStorageAccount) { 
    $AzureStorageAccount = New-AzureStorageAccount -AffinityGroup $AGName -StorageAccountName $StorageAccountName -Description $StorageAccountDesc -Label $StorageAccountLabel 
} 

$AzureStorageAccount

#5.0 Create Windows Azure Storage Container(s)
#Ensure Storage Account is fully created - Sleep for 60 seconds

Start-Sleep -Seconds 60 

#Update the Azure Subscription Connection with the Storage Account
#This makes it easier to connect to the storage account, without requiring the creation and usage of Storage Context


$AzureStorageAccountName = $ProjectName.ToLower() 
Set-AzureSubscription -SubscriptionName $AzureSubscriptionName -CurrentStorageAccount $AzureStorageAccountName 

#Create Generic VHD Storage Container; VHD will be uploaded here
$GenericStorageContainerName = "vhds" 

#Create Project Storage Container; VHD will be copied here
$ProjectStorageContainerName = $ProjectName.ToLower() 

$StorageContainerNames = @($GenericStorageContainerName,$ProjectStorageContainerName) 

foreach ($StorageContainerName in $StorageContainerNames) { 

    $AzureStorageContainer = Get-AzureStorageContainer -Name $StorageContainerName -ErrorAction SilentlyContinue 

    if(!$AzureStorageContainer) { 
        $AzureStorageContainer = New-AzureStorageContainer -Name $StorageContainerName 
    } 

    $AzureStorageContainer 
} 

#6.0 Upload “On-Prem” VHD to Windows Azure Storage Container
#Set Source VHD Info

$SourceDiskName = "toWindowsAzure" 
$SourceDiskFileExt = "vhd" 
$SourceDiskPath = "D:\Drop\Azure\toAzure" 
$SourceVHDName = "{0}.{1}" -f $SourceDiskName,$SourceDiskFileExt 
$SourceVHDPath = "{0}\{1}" -f $SourceDiskPath,$SourceVHDName 

#Set Destination Blob Info
$DesitnationVHDName = "{0}.{1}" -f $ProjectName,$SourceDiskFileExt 
$DestinationVHDPath = "https://{0}.blob.core.windows.net/{1}" -f $AzureStorageAccountName,$GenericStorageContainerName 
$DestinationBlobURI = "{0}/{1}" -f $DestinationVHDPath,$DesitnationVHDName 
$OverWrite = $false 

#Upload Local VHD to the Generic VHD Windows Azure Storage Container; this will take a while
$AzureBlob = Get-AzureStorageBlob -Container $GenericStorageContainerName -Blob $DesitnationVHDName -ErrorAction SilentlyContinue 
    
if(!$AzureBlob -or $OverWrite) { 

    $AzureBlob = Add-AzureVhd -LocalFilePath $SourceVHDPath -Destination $DestinationBlobURI -OverWrite:$OverWrite 
} 

$AzureBlob

#7.0 Copy Windows Azure Blob
#Set Source Blob Info for Copy


$SourceBlobName = $DesitnationVHDName 
$SourceContainer = $GenericStorageContainerName 

#Set Destination Blob Info for Copy

$DestinationContainer = $ProjectStorageContainerName 
$DestinationBlobName = "{0}_copy.{1}" -f $ProjectName,$SourceDiskFileExt 

$CopiedAzureBlob = Get-AzureStorageBlob -Container $DestinationContainer -Blob $DestinationBlobName -ErrorAction SilentlyContinue 

#Copy Uploaded Blob from Generic to Project
if(!$CopiedAzureBlob) { 

    $CopiedAzureBlob = Start-AzureStorageBlobCopy -DestContainer $DestinationContainer -SrcBlob $SourceBlobName -SrcContainer $SourceContainer -DestBlob $DestinationBlobName 
} 
    
Return $CopiedAzureBlob

#8.0 Create Windows Azure VM Image
$VMImageName = $ProjectName 
$VMImageBlobContainer = $DestinationContainer 
$VMImageBlobName = $DestinationBlobName 
$VMImageOS = "Windows" 

$AzureVMImage = Get-AzureVMImage -ImageName $VMImageName -ErrorAction SilentlyContinue 
    
if(!$AzureVMImage) { 

    $AzureBlobMediaLocation = (Get-AzureStorageBlob -Container $VMImageBlobContainer -Blob $VMImageBlobName).ICloudBlob.Uri.AbsoluteUri 
    $AzureVMImage = Add-AzureVMImage -ImageName $VMImageName -MediaLocation $AzureBlobMediaLocation -OS $VMImageOS 
} 
    
Return $AzureVMImage

#9.0 Create Windows Azure VM
$VMName = "{0}-001" -f $ProjectName.ToLower() 
$ServiceName = $ProjectName 
$AdminUsername = "AdminUser" 
$VMImageName = $AzureVMImage.ImageName 
$Password = "Pass@word1" 
$Windows = $true 
$VMInstanceSize = "ExtraSmall" 
$WaitForBoot = $true 

$AzureVM = Get-AzureVM -Name $VMName -ServiceName $ServiceName -ErrorAction SilentlyContinue 
    
if(!$AzureVM -and $Windows) { 

    $AzureVM = New-AzureQuickVM -AdminUsername $AdminUsername -ImageName $VMImageName -Password $Password `
        -ServiceName $ServiceName -Windows:$Windows -InstanceSize $VMInstanceSize -Name $VMName -WaitForBoot:$WaitForBoot 
} 
    
Return $AzureVM

Alternate Windows Azure VM Create Examples

Note     As stated above, the method used to create the Windows Azure VM in this example was New-AzureQuickVM, there are other methods – Please see the following for a couple of those alternate methods.

001
002
003
004
005
006
007
008
009
010

#Alternate Windows Azure VM Create: Example #1
New-AzureVMConfig -DiskName $DiskName -InstanceSize $VMInstanceSize -Name $VMName | `
    Add-AzureProvisioningConfig -AdminUsername $AdminUsername -Windows -Password $Password -ResetPasswordOnFirstLogon | `
    New-AzureVM –ServiceName $ServiceName

#Alternate Windows Azure VM Create: Example #2
$VMConfig = New-AzureVMConfig -Name $VMName -InstanceSize $VMInstanceSize -ImageName $VMImageName | `
    Add-AzureProvisioningConfig -Windows -Password $Password -AdminUsername $AdminUsername

New-AzureVM -ServiceName $ServiceName -VMs $VMConfigWaitForBoot

Other Learnings

During the "Conversion" process from Orchestrator Runbooks to Windows PowerShell, I ran up against a few things that I had to figure out. Here are a two of those learnings (outside what you have seen above), for just in case:

Storage Context

Before I learned about Setting the Azure Subscription with a "Current Storage Account", I tried my hand at creating and leveraging a Storage Context. Once you have created a Storage Context, you can reference it and pass it as a variable to commands requiring some level of specificity when it comes to Windows Azure Storage. While I did not use Storage Context in the examples above, I figured I would give you some example PowerShell, if you decide that is the route you want to take:

001
002
003
004
005

#Get Azure Storage Key and Create New Azure Storage Context
if(!$AzureStorageContext) {
    $AzureStorageKey = Get-AzureStorageKey -StorageAccountName $StorageAccountName
    $AzureStorageContext = New-AzureStorageContext -StorageAccountKey $AzureStorageKey.Primary -StorageAccountName $StorageAccountName
}

References


Digging Deeper: Bad Request (400)

I ran into quite a few exceptions during the build out of this example solution. Needless to say, when the PowerShell screen turns red, frustration rises just a little bit (if not more than a little bit). The following command helped me dig deeper on some of the more vague errors being returned by the command failure exceptions:

001
002
003

#Read Full Error Stream from Failed [Windows Azure] Command
$ErrorStream = New-Object System.IO.StreamReader($Error[0].Exception.InnerException.Response.GetResponseStream()) 
$ErrorStream.ReadToEnd()

Note     While it will not work in all cases, and while it is very generic, I found that if this is run right after a "Bad Request (400)", the "InnerText" of the Exception helped tremendously with what was actually going on. I found this originally referenced here.

Exception Handling Improved?

To get some proof of this working, I attempted to recreate the scenario where I needed to use the above commands. In my attempt to reproduce the "Bad Request (400)", I was met with actually useful and accurate errors:

image

That’s it! If I have any more learnings, I will add them to the upcoming blog posts.


What’s next?

So, what’s next? On to increasing complexity – Part 3 of this blog series takes what we have in this post, and transports it to a new world – Windows PowerShell Workflow!


Automating Hybrid Clouds with Windows Azure and PowerShell - Blog Series - Table of Contents

I broke this “Automating Windows Azure” topic up into four posts – primarily to make it easier to reference externally (based on varied interest levels).

Note     While every bit of my examples will be encapsulated within the various blog series posts, once I have published all the posts, I will be adding a TechNet Contribution, tagging it with “Building Clouds”, and placing a link to it in this section for each of the blog series parts. Be sure to check back here for the download link, once Part 4 has been published.


Thanks for checking out this blog series! For more information, tips/tricks, and example solutions for Automation within System Center, Windows Azure Pack, Windows Azure, etc., be sure to check out the other blog posts from Building Clouds in the Automation Track!

enJOY!



Viewing all articles
Browse latest Browse all 13502

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>