PowerShellDSC and Azure: more notes

This is starting to feel a little more robust in my mind… I created a pair of VMs on Azure, on the same subnet, with 1 implicitly a push server, and 1 a “client” server, or “pushee”. Each have public IPs… although thinking about it could I just have opened the RDP ports without that? Don’t know, don’t think so. But regardless they talk DSC to each other through their respective private ports. In fact I couldn’t actually get them to talk DSC/PowerShell/WsMan to each other through their public ports/DNS names. Authentication is done through runtime credentials… which are the same on both servers, FWIW. I don’t have a domain (uksouth.cloudapp.azure.com not really a domain… and if it was that would worry me from a security point of view.

The test here was to create a folder from one to the other, being the very simplest proof that had value… and it worked.

Advice: after each failed run, delete the created Dsc configuration folder. Avoids confusion.



Azure ARM: naïve single VM deployment

The aim is to get a real simple VM deployment working using a json template, and in doing that to sacrifice any guidelines on authoring best practice, so we can focus on getting familiar with the nuts and bolts of ARM deployment.

Download the template and PowerShell helper from here.

Assume you need Windows 10 Anniversary edition PowerShell versions for these client/deployment actions.

Open a PowerShell admin prompt in the download location, and run [.\deploy.ps1].

You will be prompted for your Azure login, a resource group and location (e.g. “uksouth”), and an admin password for the VM.

If all goes fine, then you will be able to rdp to the VM, and be able to start up SSMS.

Finally, a couple of pictures I took to focus the mind when trying to reduce the template to the bare minimum to get a working VM:

The next day… in fact I have started to remove the literals as I get more familiar. Again, I refer you the MS Azure docs above.

Azure RMVM: January 2017

I will try not to make a habit of this, but zero context as I am done. Gist is here.

PowerShell DSC: Creating IIS things on an Azure VM

I started out with an Azure VM (WS 2012 R2, SQLServer 2016). My aim was to deploy a web application so that the index.html was visible to the external world.

Additions I did not yet manage to achieve in DSC were a) adding endpoints for http and https in ARM, b) setting up self-signed certificates on the host VM. The http part right now is a Must.. the https might be considered optional but sensible.

Right now, this is the exciting output as an external user:

That already highlights one new thing: The UK now has its own Azure data centres… previously I noticed I would often get my browser language in Dutch.

Before I show you the whole of the DSC config, some key points were:

  • the use of the CimSession parameter to Start-DscConfiguration
  • as in a previous post, the need to delete pending configurations… assuming you are sure you don’t want them
  • There seems to be no “Let it be so” option for an existing virtual directory… so might have to replace that with some imperative code.


Code here.

Azure RM: get an Image from an ImageFamily and use it

$family = "SQL Server 2014 SP1 Enterprise on Windows Server 2012 R2"
$image=Get-AzureVMImage | where { $_.ImageFamily -eq $family } | sort PublishedDate -Descending | select -ExpandProperty ImageName -First 1


Returns for example:


And now say I want to a VM that is running SQL Server 2016. This is the (or at least a) question to ask (after some initial selects to test the water):

$image2016 = Get-AzureVMImage | where { $_.ImageFamily -eq “SQL Server 2016 RTM Enterprise on Windows Server 2012 R2”}

And that returns me:


Below is the history give or take I used to get there (btw, only just discovered that e.g. [ Set-Clipboard] does not truncate output whereas [clip]does. For example:

Get-History | select -Unique | Set-Clipboard

azure login
cd "E:\gitrepos\AllThingsAzure\AzureCLI"
$global:password = "whatsthis"
$family = "SQL Server 2014 SP1 Enterprise on Windows Server 2012 R2"
$image=Get-AzureVMImage | where { $_.ImageFamily -eq $family } | sort PublishedDate -Descending | select -ExpandProperty ImageName -First 1
Get-AzureVMImage | where $ $_.label -Like "*2016*"
Get-AzureVMImage | where { $_.label -Like "*2016*"}
Get-AzureVMImage | where { $_.label -Like "*sql*2016*"}
$image2016 = Get-AzureVMImage | where { $_.label -Like "*sql*2016*"}
$image2016 = Get-AzureVMImage | where { $_.label -Like "*sql*2016*"} | select {$_.Label}
function prompt{}
$image2016 = Get-AzureVMImage | where { $_.label -Like "*sql*2016*"} | select {$_.Label, $_.ImageName}
$image2016 | Format-Table
$image2016 | Format-List
$image2016 = Get-AzureVMImage | where { $_.label -Like "*sql*2016*Enterprise*R2"} | select {$_.Label, $_.ImageName}
$image2016 = Get-AzureVMImage | where { $_.label -Like "*sql*2016*Enterprise*R2"}
$image2016 = Get-AzureVMImage | where { $_.ImageFamily -Like "SQL Server 2016 RTM Enterprise on Windows Server 2012 R2"}
$image2016 = Get-AzureVMImage | where { $_.ImageFamily -eq "SQL Server 2016 RTM Enterprise on Windows Server 2012 R2"}
Get-History | clip
Get-Help clip
alias clip
Get-History | Set-Clipboard
$x = Get-History
$x = (Get-History | Set-Clipboard)
$x = Get-Clipboard
alias get-clipboard
alias get-clipboard gclip
New-Alias -Name gclip -Value Get-Clipboard
gclip | unique
$x = gclip | unique 
$x | Set-Clipboard
Get-History | select -Unique | Set-Clipboard

Azure and PowerShell: getting the status of the VM

If you run this, then you get a bunch of information… but not the key points about provisioning status:


$vmStatus = Get-AzureRmVM | Where-Object { $_.Name -eq "myvm1"} 
Write-Host $vmStatus.DataDiskNames 
Write-Host $vmStatus.DiagnosticsProfile 
Write-Host $vmStatus.HardwareProfile 
Write-Host $vmStatus.HardwareProfile.VmSize 
Write-Host $vmStatus.StatusCode 
Write-Host $vmStatus.ResourceGroupName 
Write-Host $vmStatus.Location 
Write-Host $vmStatus.HardwareProfile.VmSize 
Write-Host $vmStatus.StorageProfile.ImageReference.Sku 
Write-Host $vmStatus.StorageProfile.OsDisk.OsType 
Write-Host $vmStatus.StorageProfile.OsDisk.Name 
Write-Host $vmStatus.StorageProfile.OsDisk.Vhd.Uri

So the same command, but now specifying the resource name and vm name as arguments, gives this:

$vmStatus = Get-AzureRmVM -ResourceGroupName $rgName -Name $vmName -Status


And from there, we can drill in. For example:


That was a VM that is deallocated. This is how a running VM looks:




Azure: VM deallocation in PowerShell

… and implicit in that is Resource Manager, not Classic.

So interesting: if you execute this cmdlet against a running VM, then it becomes deallocated (as opposed to just Stopped):


That is, the default action is Deallocated.

If you now run the following, while keeping an eye on the Portal status, you see this:

That is, you can from a Deallocated state to a Stopped state. The key difference is the  [-StayProvisioned] switch.

This is useful for various PowerShell actions against Azure RM.

This is useful for the various sizes of VMs.