In my last post I covered how you can write bash scripts using the azure cli. Right after posting, @dfinke pinged asking rightfully “What about Powershell? Can I do the same things?”. Yes Doug, absolutely! In this post I’ll show you can do the same and more in Powershell using our Azure Powershell cmdlets.
Scripting in Powershell
To understand scripting in Powershell, there’s a few things you need to know.
- Powershell cmdlets write (or should write) objects to the pipeline, not just output text. This is really one of the major differences, you are not writing scripts that have to parse text, deal with regexes etc just to do basic things. Instead you just wire up properties. If you compare to my previous post, you’ll see instantly how this manifests itself and makes life easier.
- Powershell cmdlets are very fine-grained each performing a specific purpose. You can chain together different cmdlets by piping objects from one cmdlet to the next. You can learn more about piping and the pipeline (and should if you don’t know about it) in Powershell here.
- Pipelining is a whole topic on it’s own, but basically as long as objects coming from the pipeline have properties that match property names on the destination cmdlet, it should just work.
- You can create local variables and save objects from previous calls which you can reuse. This is really nice for scripting.
To script with our cmdlets, you will basically call one of the cmdlets and either save the result into a variable that you can pass in, or pipe it directly. In my examples below, you’ll see that in most cases, you just pipe directly.
Below is a list of some common simple scripting scenarios for websites, which includes the cmdlets and a small explanation of what each is doing. This should get you started and you can use a similar approach to work with all of our cmdlets.
Disclaimer, I am not at all a Powershell expert, so there probably are better ways to do what I am showing you.
Stop all running sites
- Retrieves all websites, this returns a collection of Site objects. Each object is a summary object which has a Name property which is the site name.
- Pipes to Stop-AzureWebsite (matching Site.Name to the Stop-AzureWebsite Name parameter) which stops each site.
Start all stopped sites
- Retrieves all websites
- Pipes to Start-AzureWebsite which starts each site.
Delete all sites
- Retrieves all websites
- Pipes to Remove-AzureWebsite which removes each site and passes the force param to force removal without prompting.
Set an app setting to every site
This one may seem a bit strange at first, but read the explanation. You can really see Powershell’s object oriented nature shining through here
- Retrieves all websites
- Pipes to For-EachObject which loops through all the objects.
- The –Process param specifies a script to execute for each object. Within the script $_ refers to the current object.
- The script first calls Get-AzureWebsite to get the full Website object passing the piped in name which is stored in a $site variable. When Get-AzureWebsite is called for a specific Website it retrieves all the details including the settings.
- Next it updates the settings for $site with a “Bar” entry. This is important because we don’t want to lose existing settings we just want to update/append.
- Finally it calls Set-AzureWebsite passing the current site name and the new settings object which contains the old settings and the new Bar setting.
Getting cmdlets to run in the background.
All the previous calls are blocking. Powershell does support the Start-Job cmdlet which allows you spawn things off in the background, so you can modify any of the script to run in the background. This took me a bit of playing, but I finally got the last one working (which is the hardest).
Hold on to your saddles folks! If you thought the last one was a little tough, feast your eyes on this!
- Retrieves all websites
- Pipes to For-EachObject which loops through all the objects.
- The script calls Start-Job to launch a background job
- The –InputObject specifies to pass the site name as a variable to the job script.
- The –ScriptBlock specifies the script which executes within the background job (Matrix anyone?)
- The job script first calls Get-AzureWebsite to retrieve the site info and stores it in the $site variable.
- Next it sets the the settings.
- Finally it calls Set-AzureWebsite passing the current site name and the new settings object which contains the old settings and the new Bar setting.
This one actually deserves a screenshot or two, so here goes. Below you can see running the script which outputs the list of created jobs.
Now you can see that it has created for me a job for each website that was retrieved. The jobs are running in the background. I can use the Get-Job command to monitor the status of any jobs running in my shell.
As you can see above all the jobs completed a few seconds later. There is also a Receive-Job command that you can pass a job to in order to get more details and I believe the Verbose output. In this case Set-AzureWebsite doesn’t return anything, however I can check one of my sites and see that it worked. Notice Bar1…
Merry posh scripting
As in my previous post, this is just the beginning of what you can do once you start mastering scripting in Powershell. Just go ask my friend and Powershell guru Peter Provost. We are doing a lot of deliberate up-front thinking about scripting scenarios with our Powershell cmdlets as there are existing mechanisms since it is so core to being a first class Powershell cmdlet.
Let us know if there are areas you think we need to improve the scripting support, and please share links to any cool Azure powershell scripts you have authored!
Happy Holidays!