Azure Native Remoting Options for your IaaS Resources

Azure Native Remoting Options for your IaaS Resources

So last night (hours before going on vacation) I was watching the last Azure Friday episodes, where they were showing PowerShell being GA in the cloud shell. If you want to take a look at it, here you go:

During the presentation they were showing some of the new features shipped in the release, and they briefly covered these two cmdlets which allows you to run scripts or commands against a VM without the need of logging in interactively:

  • Enable-AzVMPSRemoting
  • Invoke-AzVMCommand

and it made me wonder, how many ways, Azure native ways, do I have to remote into my Windows IaaS machines (I’m talking about Windows Server because that’s my comfort zone, but this is all valid for Linux too). So I’ve tried to do a recollection of all these and summarize them here (click on each of them to go to a more detailed explanation):

Serial Console

As it is indicated by the name, it emulates a diagnostic console. This shouldn’t be used for administrative purposes as it is intended for troubleshooting. For more information on how to configure and consume this feature refer to the following links:

Run Command

Essentially allows you to execute a script and some other pre-defined actions via the agent running on the VM. The functionality is fully described here: https://docs.microsoft.com/en-us/azure/virtual-machines/windows/run-command. There is no need for the server to be exposed to the internet.

PowerShell

Exactly the same thing than the previous point, but using PowerShell. This was a functionallity that existed already in the AzureRM module, and has been ported to the Az module.

  • Invoke-AzureRmVMRunCommand is now Invoke-AzVMRunCommand
  • Get-AzureRmVMRunCommandDocument is now Get-AzVMRunCommandDocument

There are a few things to take into consideration. As you might have seen when consuming this functionality from the portal point of view, there are several predefined options, from running a PowerShell script, to running a simple ‘ipconfig’. All these predefined functions, can be obtained by using the Get-AzVMRunCommandDocument cmdlet. This is particularly important as the Id obtained is a required input of the Invoke-AzureRMVMRunCommand cmdlet.

How to use it?

First thing you need to do is to get yourself an idea on all the available commands by using the Get-AzureRmVMRunCommandDocument or Get-AzVMRunCommandDocument depending on which modules your are running.

If you intend to use the ‘RunPowerShellScript’ for example, you’ll need a script in your file system that carries the actions you want to execute on the target machine. And finally, you run the Invoke-AzureRmVMRunCommand or Invoke-AzVMRunCommand cmdlet (again, depending on what version of the modules are you using).

Out of all the options I reviewed, I’d say this is my favourite one. But something I’d like Microsoft to improve is the fact that, when you are using the command id “RunPowerShellScript”, the script needs to exist in your  file system. It would be nice for them to give you the possibility to define a script block.

Cloud Shell

Ok, let’s cover the feature that inspired this post. As said before, there is a module available in the Cloud Shell called ‘PSCloudShellUtility’. As with this module there are some new cmdlets shipped:

For the sake of what we are covering in this post, our interest falls under the cmdlets ‘Enable-AZMPSRemoting’ and ‘Invoke-AzVMCommand’. These should be executed in this very same order for them to work. As you can see, they are all ‘Function’ type cmdlets, so if we look at the ‘Enable-AzVMPSRemoting’ definition by running:

We will obtain the following:

In summary we can see that it will:

  1. Obtains the Operating System of the specified machine
  2. Obtains the NSGs which apply to the VM
  3. For each NSG (if there is no NSGs applied to the VM, this cmdlet won’t actually do anything)
    1. If there is no inbound rule in the NSG for the type of protocol selected, creates one.
    2. Configure WinRM on the target machine by using the “Run Command” already reviewed feature. The only difference is that instead of using the ‘Invoke-AzVMRunCommand’ it uses the ‘Invoke-AzResourceAction’ which essentially calls the ‘runcommand’ action via the AzureRM API.

So in essence this cmdlet is preparing your VM to accept remote commands over the internet. And finally, if we take a look at the definition of ‘Invoke-AzVMCommand’ by executing:

We obtain the following:

Which is no more than a wrapper for the ‘Invoke-Command’ cmdlet. I’m not a huge fan of this way of remoting into your VM for two main reasons:

  1. Is not very well documented. Or at least I struggled a lot to find documentation about it. I captured some bits and pieces from the Azure Friday episode, and the rest was digging. Certainly Microsoft teams could do a better work at documenting PSCloudShellUtility module and it’s command lets.
  2. It exposes standard ports to the internet. That’s why I prefer the ‘Invoke-AzVMRunCommand’ over this remoting way.

From another point of view, this cmdlets get you up and running in a few seconds. And what they do to your NSGs and VMs is nothing you can’t do manually and include some tweaks in the process to make it more secure.


Hope you find this useful, and if I forgot to mention any other ‘Azure native remoting’ options, don’t hesitate to leave your comment!

Hernán J. Larrea

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.