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
}
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
Post a Comment