The definitive guide on how to deploy a cloud service to Azure using PowerShell

This is a set of scripts:

deploy-all-async.ps1 > starts the deployment process asynchronously.
compile-all.ps1 > compiles all the projects synchronously
cloud-msbuild-compile.ps1 > compiles each project
cloud-deploy.ps1 > deploys the project to Azure

deploy-all-async.ps1

#To execute, cd to this folder and run:
# .\deploy-all-async.ps1

$ScriptPath = Split-Path $MyInvocation.InvocationName

#START COMPILE ********************************************************************************************************

$path = "$ScriptPath\compile-all.ps1"
Invoke-Expression "$path"

#END COMPILE ********************************************************************************************************


#START DEPLOY ********************************************************************************************************

$projects = @("clouddeploymentname1", "clouddeploymentname2", "clouddeploymentname3", "clouddeploymentname4", "clouddeploymentname5")

$projectFolderPaths = @{
"clouddeploymentname1" = "<path_to_project>\<project_folder>\"
"clouddeploymentname2" = "<path_to_project>\<project_folder>\"
"clouddeploymentname3" = "<path_to_project>\<project_folder>\"
"clouddeploymentname4" = "<path_to_project>\<project_folder>\"
"clouddeploymentname5" = "<path_to_project>\<project_folder>\"
}

$projectFileNames = @{
"clouddeploymentname1" = "<cloud deployment project name>"
"clouddeploymentname2" = "<cloud deployment project name>"
"clouddeploymentname3" = "<cloud deployment project name>"
"clouddeploymentname4" = "<cloud deployment project name>"
"clouddeploymentname5" = "<cloud deployment project name>"
}

Write-Output "Starting Jobs..."

foreach ($project in $projects.GetEnumerator()) {
Write-Host "$(Get-Date)> Going to Process: $project, $($projectFolderPaths.Get_Item($project)), $($projectFileNames.Get_Item($project))"

$ScriptBlock = { 
param($project, $projectFolderPath, $projectFileName)

$args = @()
$args += ("-service", $project)
$args += ("-slot", "Production")
$args += ("-AzureProjectFolderPath", $projectFolderPath)
$args += ("-AzureProjectFileName", $projectFileName)

$path = "<path>\cloud-deploy.ps1"

Write-Host "$(Get-Date)> Going to Execute deployment for: ($project, $projectFolderPath, $projectFileName)"
Invoke-Expression "$path $args"
}

Start-Job $ScriptBlock -Name "$project Deployment" -ArgumentList @($project, $projectFolderPaths.Get_Item($project), $projectFileNames.Get_Item($project))

Write-Host "Sleeping for 2 minutes between each deployment..."
Start-Sleep 120
}

#Wait for it all to complete
While (Get-Job -State "Running")
{
  Start-Sleep 10
}

Write-Output "Completed Jobs, getting output..."

# Getting the information back from the jobs
Get-Job | Receive-Job

#END DEPLOY ********************************************************************************************************

Write-Output "Completed All Jobs"

compile-all.ps1

$ScriptPath = Split-Path $MyInvocation.InvocationName

#START COMPILE ********************************************************************************************************

$path = "$ScriptPath\cloud-msbuild-compile.ps1"

#Needs to be done one by one as projects are shared...

$args = @()
$args += ("-AzureProjectFolderPath", "<path_to_project_folder>\")
$args += ("-AzureProjectFileName", "<project_file_name>")

Invoke-Expression "$path $args"

$args = @()
$args += ("-AzureProjectFolderPath", "<path_to_project_folder>\")
$args += ("-AzureProjectFileName", "<project_file_name>")

Invoke-Expression "$path $args"

$args = @()
$args += ("-AzureProjectFolderPath", "<path_to_project_folder>\")
$args += ("-AzureProjectFileName", "<project_file_name>")

Invoke-Expression "$path $args"

$args = @()
$args += ("-AzureProjectFolderPath", "<path_to_project_folder>\")
$args += ("-AzureProjectFileName", "<project_file_name>")

Invoke-Expression "$path $args"

$args = @()
$args += ("-AzureProjectFolderPath", "<path_to_project_folder>\")
$args += ("-AzureProjectFileName", "<project_file_name>")

Invoke-Expression "$path $args"

#END COMPILE ********************************************************************************************************

cloud-msbuild-compile.ps1

Param([string]$AzureProjectFolderPath,
 [string]$AzureProjectFileName)

Write-Output "$AzureProjectFileName|$(Get-Date)> Going to clear all files from bin\release folder..."

$releasepath = "bin\Release\"
Remove-Item $AzureProjectFolderPath$releasepath -recurse

#Creating a package

$msbuild = "'C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe'"

Write-Output "$AzureProjectFileName|$(Get-Date)> Going to build package IGNORING POST BUILD EVENTS..."

#IGNORES POST BUILD EVENTS!!!

$args = $AzureProjectFolderPath + $AzureProjectFileName + ".ccproj /p:Configuration=Release /p:DebugType=None /p:Platform=AnyCpu /p:OutputPath=" + $AzureProjectFolderPath + $releasepath + " /p:TargetProfile=Cloud /t:publish /verbosity:quiet /p:VisualStudioVersion=14.0 /p:PreBuildEvent= /p:PostBuildEvent="

Invoke-Expression "& $msbuild $args"


Write-Output "$AzureProjectFileName|$(Get-Date)> Build package completed"

cloud-deploy.ps1

Param([string]$service,
      [string]$slot,
 [string]$AzureProjectFolderPath,
 [string]$AzureProjectFileName)

Write-Output "$AzureProjectFileName|$(Get-Date)> Going to deploy..."

#Deploying a package
Function Get-File($filter){
    [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
    $fd = New-Object system.windows.forms.openfiledialog
    $fd.MultiSelect = $false
    $fd.Filter = $filter
    [void]$fd.showdialog()
    return $fd.FileName
}

#Locate the package, publish settings and other variables
Write-Output "$AzureProjectFileName|$(Get-Date)> Locating the package, publish settings and other variables..."

if (!$service) {
$service = "<default>"
}

if (!$slot) {
$slot = "Production"
}

[string]$package = $AzureProjectFolderPath + "bin\Release\app.publish\" + $AzureProjectFileName + ".cspkg"
Write-Output "$AzureProjectFileName|$(Get-Date)> $package= $($package)"

[string]$config = $AzureProjectFolderPath + "bin\Release\app.publish\ServiceConfiguration.Cloud.cscfg"
Write-Output "$AzureProjectFileName|$(Get-Date)> $config= $($config)" 

[string]$publishsettings = "<path to publish settings file>"
[string]$storageaccount = "<name of storage account>"
[string]$subscription = "<name of subscription>"
[string]$containerName = "psdeploy"

#Functions

Function Set-AzureSettings($publishsettings, $subscription, $storageaccount){
    Import-AzurePublishSettingsFile -PublishSettingsFile $publishsettings

    Set-AzureSubscription -SubscriptionName $subscription -CurrentStorageAccount $storageaccount

    Select-AzureSubscription -SubscriptionName $subscription
}

Function Upload-Package($package, $containerName){
    $blob = "$service.package.$(get-date -f yyyy_MM_dd_hh_ss).cspkg"
     
    $containerState = Get-AzureStorageContainer -Name $containerName -ea 0
    if ($containerState -eq $null)
    {
        New-AzureStorageContainer -Name $containerName | out-null
    }
     
    Set-AzureStorageBlobContent -File $package -Container $containerName -Blob $blob -Force| Out-Null
    $blobState = Get-AzureStorageBlob -blob $blob -Container $containerName

    $blobState.ICloudBlob.uri.AbsoluteUri
}

Function Create-Deployment($package_url, $service, $slot, $config){
    $stat = New-AzureDeployment -Slot $slot -Package $package_url -Configuration $config -ServiceName $service
}

Function Upgrade-Deployment($package_url, $service, $slot, $config){
    $setdeployment = Set-AzureDeployment -Upgrade -Slot $slot -Package $package_url -Configuration $config -ServiceName $service -Force
}

Function Check-Deployment($service, $slot){
    $completeDeployment = Get-AzureDeployment -ServiceName $service -Slot $slot
    $completeDeployment.deploymentid
}

#End Functions

try
{
#Importing the Azure cmdlets module
Write-Output "$AzureProjectFileName|$(Get-Date)> Importing the Azure cmdlets module..."

Import-Module "C:\Program Files (x86)\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Azure.psd1"

#Import the publish profile and configure the subscription
Write-Output "$AzureProjectFileName|$(Get-Date)> Importing the publish profile and configuring the subscription..."

Set-AzureSettings -publishsettings $publishsettings -subscription $subscription -storageaccount $storageaccount

#Upload the package to blob storage
Write-Output "$AzureProjectFileName|$(Get-Date)> Uploading the package to blob storage..."

$package_url = Upload-Package -package $package -containerName $containerName

#Check if a deployment exists
Write-Output "$AzureProjectFileName|$(Get-Date)> Checking if a deployment exists..."

$deployment = Get-AzureDeployment -ServiceName $service -Slot $slot -ErrorAction silentlycontinue

#Create a new deployment

if ($deployment.Name -eq $null) 
{
Write-Output "$AzureProjectFileName|$(Get-Date)> Creating a new deployment..."
    Create-Deployment -package_url $package_url -service $service -slot $slot -config $config


#Upgrade an existing deployment

if ($deployment.Name -eq $null) 
{
    #Invalid State

else 
{
Write-Output "$AzureProjectFileName|$(Get-Date)> Upgrade an existing deployment..."
    Upgrade-Deployment -package_url $package_url -service $service -slot $slot -config $config
}

#Check if the deployment has succeeded
Write-Output "$AzureProjectFileName|$(Get-Date)> Checking if the deployment has succeeded..."

$deploymentid = Check-Deployment -service $service -slot $slot

Write-Output "$AzureProjectFileName|$(Get-Date)> Completed"
exit 0
}
catch [System.Exception] 
{
Write-Host $_.Exception.ToString()
    exit 1
}

Comments

Popular posts from this blog

Enable Visual Studio to use more than 2GB of memory

Firefox and Chrome dark mode

Dealing with the morons who built Dell 7710 and RAID