Saturday, February 21, 2015

Create a VM from a VHD from VMDepot in PowerShell



###################Disclaimer########################################
# The script is provided ASIS. Feel free to modify as per your need #
#####################################################################

clear screen

#global preference
#$ErrorActionPreference = "Stop"

$bgcolor="Gray"
$fgcolor="Cyan"
###############################Set your variables##################################

#collect Id
# you can collect the Id by
#1. go to https://www.vmdepot.com/List/Index,
#2. locate the the desired VHD
#3. select the Deployment Script
#4. Agree to the terms
#5. choose the region
#6. You should see the xplat CLI scripts. Something like
#   "azure vm create DNS_PREFIX -o vmdepot-50272-1-1 -l "West US" USER_NAME [PASSWORD] [--ssh] [other_options]
#    azure vm endpoint create-multiple DNS_PREFIX 80:80,443:443
#7. Collect the ID (value of -o above. In the above example it is "vmdepot-50272-1-1"
$vmdepotVHDID="vmdepot-50272-1-1 -l"
$storageAccountName = "sawestusdp"
$containerName="dpvmdepot"
$maxReturn = 100

$location = 'West US'
$adminname = 'MppUsWest1admin'
$adminpassword = 'MppUsWest1'
$vmName='vmdepotdevrnd'
$vmIPAddress='10.1.0.15'
$vmSSHPublicPort='5003'
$cloudsvcName = 'centosdevrnd'
$vnetname = 'devrnd'   
$subnetname = 'Subnet-1'

###################Display message########################
function Display-Message ($message, $message2) {
    Display-Message_NoLineBreak $message, $message2
    $nl
}
function Display-ErrorMessage ($myError) {
    Write-Host "Error: $myError" -BackgroundColor Red -ForegroundColor $fgcolor

   #Show-ErrorDetails
    $Error.Clear();
    $nl
}
####################End of Display message################

##################Collect User Response################
function Collect-UserResponse ($message) {
    Display-ErrorMessage $message
    Read-Host 'Press <Enter> to continue or Ctrl+C to Abort'
}

##################end of Collecting User Response######


#################Find if blob already exists###############
function Test-Blob ($blobName)
{
    $total = 0
    $token = $null
    do
    {
       $blobs = Get-AzureStorageBlob -Container $containerName -MaxCount $maxReturn  -ContinuationToken $token
       $total += $blobs.Count
       if($blobs.Length -le 0) { break;}
        if ($blobs[$blobs.Count -1].Name -eq $blobName) {
            return $true;
        }
       $token = $blobs[$blobs.Count -1].ContinuationToken;
    }
    while($token -ne $null)
    Display-Message "Total $total blobs in container $containerName"
    return $flase;
}

#################create VM##########################

function Create-VM ($sshport, $vmname, $ubuntuImageName, $adminpassword, $adminname, $subnetname, $vmIPAddress, $cloudsvcName, $vnetname, $location) {
    Display-Message_NoLineBreak "Going to create vm:"
    Display-Message_NoLineBreak "vmname: $vmname"
    Display-Message_NoLineBreak "ubuntuImageName: $ubuntuImageName"
    Display-Message_NoLineBreak "adminpassword: $adminpassword"
    Display-Message_NoLineBreak "adminname: $adminname"
    Display-Message_NoLineBreak "subnetname: $subnetname"
    Display-Message_NoLineBreak "vmIPAddress: $vmIPAddress"
    Display-Message_NoLineBreak "cloudsvcName: $cloudsvcName"
    Display-Message_NoLineBreak "vnetname: $vnetname"
    Display-Message_NoLineBreak "location: $location"
    Display-Message_NoLineBreak "sshport: $sshport"
    Pause

    $vmObject=New-AzureVMConfig -Name "$vmname" -InstanceSize "Small" -ImageName "$ubuntuImageName" |`
                Add-AzureProvisioningConfig -Linux -Password "$adminpassword" -LinuxUser "$adminname" -NoSSHEndPoint|`
                Set-AzureSubnet -SubnetNames "$subnetname" |`
                Set-AzureStaticVNetIP -IPAddress "$vmIPAddress" |`
                Add-AzureEndpoint -LocalPort 22 -Name SSH -Protocol tcp -PublicPort "$sshport" | `
                New-AzureVM –ServiceName "$cloudsvcName" -WaitForBoot -VNetName "$vnetname" -Location "$location"

    return $vmObject
}
   

#add your account
Display-Message "Going to add account..."
#Add-AzureAccount
Display-Message "Added account."

#ensure that you are in service management mode
Display-Message "Going to switch to service management mode..."
Switch-AzureMode -Name AzureServiceManagement


###########Find default subscription##########
$subscriptionName = ""
foreach ($sub in Get-AzureSubscription)
{
    if ($sub.IsDefault -eq "True")
    {
        $subscriptionName = $sub.SubscriptionName
    }
}
Display-Message "Default Subscription:" $subscriptionName
Pause

#set default subscription and the storage account
Display-Message "Going to set the default Subscription"
Set-AzureSubscription -SubscriptionName $subscriptionName -CurrentStorageAccountName $storageAccountName
Display-Message "Default Subscription and Storage Account set"
#print the subscription
Display-Message "Going to print azure subscription."
Get-AzureSubscription
Pause

# Get the storage account key and context
Display-Message "Going to collect Storage context..."
$storageAccountKey = (Get-AzureStorageKey -StorageAccountName $storageAccountName).Primary
Display-Message "Storage Key $storageAccountKey"

#get storage contxt
$storageCtx = New-AzureStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey
Display-Message "Storage context collected: $storageCtx"

$confirmStatus=$null
if (Test-Blob $vmdepotVHDID)
{
    Display-ErrorMessage "$vmdepotVHDID already exists in container $containerName!!!"
    $confirmStatus=Read-Host 'Enter Overwrite(1), Continue Without Overwrite(2)/No(3) followed by <Enter> [default No(2)]'

    if ($confirmStatus -eq $null -or $confirmStatus.Length -eq 0) {
        $confirmStatus="2"
    }
}

#exit program
if ($confirmStatus -eq "3")
{
    Display-Message "Good Bye!!!"
    break;
}

if ($confirmStatus -eq $null -or $confirmStatus -eq "1")
{
    #find the url to the VHD
    Display-Message "Going to collect VHD ID for $vmdepotVHDID..."
    $vmdeptVHDBlobUrl=(Invoke-RestMethod -Uri 'http://vmdepot.msopentech.com/OData.svc/ResolveUid?uid=%27vmdepot-50272-1-1%27').ResolveUid.Element.BlobUrl
    Display-Message "Blob URL of VHD in VMdepot $vmdeptVHDBlobUrl"

    Display-Message "Start copying the VHD..."
    $storageBlobCopy = Start-AzurestorageBlobCopy -SrcUri $vmdeptVHDBlobUrl -DestContainer $containerName -DestBlob "$vmdepotVHDID" -DestContext $storageCtx
    $copyProgress = $storageBlobCopy | Get-AzurestorageBlobCopyState

    While ($copyProgress.Status -eq 'Pending') {
       $copyProgress = ($storageBlobCopy | Get-AzurestorageBlobCopyState)
       Write-Progress -Id 1 -Activity "Copying VHDID $vmdepotVHDID BLOB to Azure Storage Acccount $storageAccountName in container $containerName" -Status ("{0} bytes of {1} completed" -f $copyProgress.BytesCopied, $copyProgress.TotalBytes)
       Start-Sleep -Seconds 5
    }

    "Blob copy completed with status: $($copyProgress.Status)"
    Display-Message "Copied VHD."
}

#cleanse the Image name
$vmDepotImageName = [Regex]::Replace($vmdepotVHDID.ToLower(), '[^(a-z0-9)]', '')
Display-Message "Storage Account Name:" $vmDepotImageName


#Handle Image now.
Display-Message "Going to check if $vmDepotImageName exists..."
$vmDepotImage = Get-AzureVMImage -ImageName $vmDepotImageName
$vmImageObject=$null
$vhdUrl="$($storageCtx.BlobEndPoint)$($containerName)/$vmdepotVHDID"
if ($vmDepotImage -eq $null) {
    Display-Message "Image not found. Going to create an image..."
    $vmDepotImage=Add-AzureVMImage -ImageName "$vmDepotImageName" -MediaLocation $vhdUrl -OS Linux -Verbose
    Display-Message "Image created $vmImageObject"
}


Display-Message "Check if VM $vmName already exists..."
$vmObject=Get-AzureVM -ServiceName $cloudsvcName -Name $vmname
if (($vmObject) -ne $null) {
    Collect-UserResponse "$vmname alread exists!!!"
    $isError = $true
}


if (!$isError) {
    $vmObject=Create-VM $vmSSHPublicPort $vmName $vmDepotImageName $adminpassword $adminname $subnetname $vmIPAddress $cloudsvcName $vnetname $location
}

Display-Message "End of program :)"

No comments:

Post a Comment