Tag Archives: powershell

Azure: Deploy a WebApp with PowerShell

A quick runthrough on using PowerShell to deploy a new WebApp. ASP.NET code for the website has been zipped up (into myapp.zip) and this code snippet will upload it to a new WebApp, hosted in a new App Service Plan and a new Resource Group.

From a local PowerShell session use Connect-AZAccount before running this code to sign-in to Azure. Alternatively this code can be run (with the exception of the upload itself) from the Cloud Shell directly in the Azure Portal.

The code also writes out the URL of the resulting WebApp and the PowerShell necessary to tear down the resources when they are no longer required.

#Set some parameters
$location="UK South"
$resourceGroupName= “rsg-myapp”

#Create Resource Group
"-- Creating Resource Group"
New-AzResourceGroup -Location $location -Name $resourceGroupName -tag $Tags

#Create ServicePlan
"-- Creating Service Plan"
New-AzAppServicePlan -ResourceGroupName $resourceGroupName -Name $appServicePlanName -Location $location -Tier Free

#Create Web App
"-- Creating Web App"
New-AzWebApp -ResourceGroupName $resourceGroupName -Name $webAppName -Location $location -AppServicePlan $appServicePlanName

#Upload the web code
"-- Uploading Web App Code"
Publish-AzWebApp -ResourceGroupName $resourceGroupName -Name $webAppName -ArchivePath $codeZIPPath –Force

#Show user code to destroy this (useful for testing)
#  and the website that has been created.
"-- Tidy Up Code: "
" Remove-AzResourceGroup -Name $resourceGroupName"
"-- Website: "
"-- https://$WebAppName.azurewebsites.net"

"-- Done"

The resulting website can be viewed just by pointing a browser at the given URL. The created resources can be checked in the Azure portal:


vSAN Cluster Shutdown

A few weeks ago I had to shutdown a vSAN Cluster temporarily for a planned site-wide 24 hour power outage that was blacking out a datacentre. With the amount of warning and a multi-datacentre design this wasn’t an issue, but I made use of vSphere tags and some Powershell/PowerCLI to help with the evacuation and repopulation of the affected cluster. Hopefully some of this may be useful to others.

The infrastructure has two vSAN Clusters – Cluster-Alpha and Cluster-Beta. Cluster-Beta was the one being affected by the power outage, and there was sufficient space on Cluster-Alpha to absorb migrated workloads. Whilst they exist in different datacentres both clusters are on the same LAN and under the same vCenter.

I divided the VMs on Cluster-Beta into three categories:

  1. Powered-Off VMs and Templates. These were to stay in place, they would be inaccessible for the outage but I determined this wouldn’t present any issues.
  2. VMs which needed to migrate and stay on. These were tagged with the vSphere tag “July2019Migrate”
  3. VMs which needed to be powered off but not migrated. For example test/dev boxes which were not required for the duration. These were tagged with “July2019NOMigrate”

The tagging was important, not only to make sure I knew what was migrating and what was staying, but also what we needed to move back or power on once the electrical work had completed. PowerCLI was used to check that all powered-on VMs in Cluster-Beta were tagged one way or another.

Get the VMs in CLuster-Beta where the tag “July2019Migrate” is not assigned and the tag “July 2019NOMigrate” is not assigned and the VM is Powered On.

Get-Cluster -Name "Cluster-Beta" |Get-VM | where {
 (Get-TagAssignment -Entity $_).Tag.Name –notcontains "July2019Migrate" –and
 (Get-TagAssignment -Entity $_).Tag.Name –notcontains "July2019NOMigrate" –and
 $_.PowerState –eq “PoweredOn”}

In the week approaching the shutdown the migration was kicked off:

#Create a List of the VMs in the Source Cluster which are tagged to migrate
$MyTag= Get-Tag -Name "July2019Migrate"
$MyVMs=Get-Cluster "Cluster-Beta" | Get-VM | Where-Object {(Get-TagAssignment -Entity $_).Tags -contains $MyTag }
#Do the Migration
$TargetCluster= "Cluster-Alpha" #Target Cluster
$TargetDatastore= "vSANDatastore-Alpha" #Target Datastore on Target Cluster
$MyVMs | Move-VM -Destination (Get-Cluster -Name $TargetCluster) -Datastore (Get-Datastore -Name $TargetDatastore) -DiskStorageFormat Thin -VMotionPriority High

At shutdown time, a quick final check of the remaining powered on VMs was done and then all remaining VMs in Cluster-Beta were shut down. Once there were no running workloads on Beta it was time to shut down the vSAN cluster. This part I didn’t automate as I’m not planning on doing it a lot, and there’s comprehensive documentation in the VMware Docs site. The process is basically one of putting all the hosts into maintenance mode and then once the whole cluster is done, powering them off.

You are in a dark, quiet datacentre. There are many servers, all alike. There may be Grues here.

When power was restored, the process was largely reversed. I powered on the switches providing the network interconnect between the nodes, and then powered on those vSAN hosts and waited for them to come up. Once all the hosts were visible to vCenter, it was just a case of selecting them all and choosing “Exit Maintenance Mode”

2019-07-29 (8)

There was a momentary flash of alerts as nodes come up and wonder where their friends are, but in under a minute the cluster was passing the vSAN Health Check


At this point it was all ready to power on the VMs that had been shutdown and left on the cluster, and vMotion the migrated virtual machines back across. Again, PowerCLI simplified this process:

#Create a List of the VMs in the Source Cluster which are tagged to stay but need powering on.
$MyTag= Get-Tag -Name "July2019NOMigrate"
$MyVMs=Get-Cluster “Cluster-Alpha” | Get-VM | Where-Object {(Get-TagAssignment -Entity $_).Tags -contains $MyTag }
#Power on those VMs
$MyVMs | Start-VM

#Create a List of the VMs in the Source Cluster which are tagged to migrate (back)
$MyTag= Get-Tag -Name "July2019Migrate"
$MyVMs=Get-Cluster “Cluster-Alpha” | Get-VM | Where-Object {(Get-TagAssignment -Entity $_).Tags -contains $MyTag }
#Do the Migration
$TargetCluster= "Cluster-Beta" #New Target Cluster
$TargetDatastore= "vSANDatastore-Beta" #Target Datastore on Target Cluster
$MyVMs | Move-VM -Destination (Get-Cluster -Name $TargetCluster) -Datastore (Get-Datastore -Name $TargetDatastore) -DiskStorageFormat Thin -VMotionPriority High

Then it was just a case of waiting for the data to flow across the network and finally check that everything had migrated successfully and normality had been restored.

we have normality, I repeat we have normality…Anything you still can’t cope with is therefore your own problem. Please relax.

Trillian, via the keyboard of Douglas Adams. The Hitchhiker’s Guide to the Galaxy

Rubrik Build Workshop

Last week (end of May 2019) I was lucky enough to secure a place at the Rubrik Build Workshop in London. This event, which has been touring round the world, is a day of technical learning focussed on API, SDK, and version control.

Roxie at RubrikThe first thing to acknowledge here is even though Rubrik was hosting the event and the presenters  (the awesome pairing of Chris Wahl and Rebecca Fitzhugh) work for the company there was absolutely no sales push. Whilst they used their own APIs and SDKs as examples the majority of the content was very much platform agnostic. Kudos is due here for running this kind of free-of-charge educational event for the tech community without filling it with sales and marketing slides.

The morning started with a session on version control- looking at how git and in particular GitHub – can be used to track and share code. The “RoxieAtRubrik” GitHub account was used in some hands-on demos -we all forked a public project, made changes,  and submitted a pull request. The course material used in the workshops is publicly available via this account- check here: https://github.com/RoxieAtRubrik

There were some insights into how GitHub is used at Rubrik- there’s unit tests for every single function and in the background they have a CI (Continuous Integration) pipeline at work to make sure releases are up to scratch. Quality control can be tricky on community fed projects where developers may not be subject to traditional corporate control and it’s interesting to see how different teams handle this input.

Our dive into version control was followed by a look at how REST APIs work, using the Rubrik APIs as an example. There was plenty of hands-on activity here, with an online lab provided to simulate communicating with a real world device but in a safe environment.

Rubrik Hands on Lab Environment

The schedule of this event was flexible and after a show of hands amongst the 15 delegates we moved on to look at PowerShell, both in general terms for those new to the scripting language but also seeing how the SDK layer of the Rubrik PowerShell module made the API calls we’d looked at previously more user-friendly.

This PowerShell module is open source and available on GitHub- https://github.com/rubrikinc/rubrik-sdk-for-powershell – and as with all these projects contributions are welcome from the community. There was lots of encouragement from the presenters for customers/users to try these SDKs out and feed back any improvements that could be made, either by submitting an feature request or bug report, or by writing some or all of the addition yourself.

The European leg of the Rubrik Build tour has finished, but they’re off to Australia and New Zealand in June if that’s local to you. Check out https://build.rubrik.com/ for details.

PowerShell Maths

A colleague recently popped in a support request after noticing that the Calculator app wasn’t installed on their computer. This prompted an office discussion on how else you can solve sums when sat in front of a computer, and I mentioned you could just use PowerShell.

Open a regular PowerShell window and you can just start typing in basic sums


So addition, subtraction, multiplication, and division work fine- but what else can you do without making it complicated or hard to remember?

PowerShell this comes with the backing of the .NET Maths library, so you can enter [System.Math]:: (or just [Math]:: ) and then tab through possible operations – for example square root (see screenshot), power, trigonometry and so on.


There’s currently 35 methods in this library and you can get a full list of these using the GetMethods property. This example lists them nicely in comma delimited form so you don’t have to scroll this webpage too much 🙂

PS C:\> ([System.Math].GetMethods() |
Select-Object -Unique -Property Name ).Name -join ", "
Abs, Acos, Acosh, Asin, Asinh, Atan, Atan2, Atanh, Cbrt, Ceiling, Cos, Cosh,
Exp, Floor, Log, Log10, Pow, Sin, Sinh, Sqrt, Tan, Tanh, BigMul, DivRem, Clamp,
IEEERemainder, Max, Min, Round, Sign, Truncate, ToString, Equals, GetHashCode,

So, who needs a graphical Calculator app now?

Quick PowerCLI- Getting VM hardware versions

A quick PowerCLI snippet for examining what VM Hardware versions exist in your virtual environment:

Using the “Group-Object” cmdlet we can run up a quick count of all the VMs on each hardware version

Get-VM | Group-Object Version

Count Name                      Group
----- ----                      -----
42    v13                       {VM1,VM2,VM3...}
257   v8                        {VM4,VM5,VM6...}
70    v11                       {VM7,VM8,VM9...}
2     v4                        {VM10,VM11}
5     v10                       {VM12,VM13,VM14...}
2     v9                        {VM15,VM16}
2     v7                        {VM17,VM18}

This can be refined using “Sort-Object” to put the most common hardware version at the top of the list.

Get-VM  | Group-Object Version | Sort-Object Count -Descending
Count Name                      Group
----- ----                      -----
257   v8                        {VM4,VM5,VM6...}
70    v11                       {VM7,VM8,VM9...}
42    v13                       {VM1,VM2,VM3...}
5     v10                       {VM12,VM13,VM14...}
2     v7                        {VM17,VM18}
2     v9                        {VM15,VM16}
2     v4                        {VM10,VM11}

We may only be concerned with VMs that are Powered On, so “Where-Object” can be used to filter the original list.

Get-VM  | Where-Object {$_.PowerState -eq "PoweredOn"} | Group-Object Version | Sort-Object Count -Descending
Count Name                      Group
----- ----                      -----
66    v8                        {VM4,VM5,VM19...}
51    v11                       {VM7,VM8,VM9...}
33    v13                       {VM1,VM21,VM22...}
5     v10                       {VM12,VM13,VM20...}
2     v9                        {VM15,VM16}
1     v4                        {VM10}

This quick snippet can be useful when establishing the range of hardware versions in an environment, or estimating the amount of work involved in updating VM hardware to a modern standard across an estate.