{"id":81222,"date":"2018-10-09T15:34:14","date_gmt":"2018-10-09T15:34:14","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=81222"},"modified":"2021-02-23T19:20:29","modified_gmt":"2021-02-23T19:20:29","slug":"azure-and-windows-powershell-using-vm-extensions","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/azure-and-windows-powershell-using-vm-extensions\/","title":{"rendered":"Azure and Windows PowerShell: Using VM Extensions"},"content":{"rendered":"<p><strong>The series so far:<\/strong><\/p>\n<ol>\n<li><a href=\"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/azure-windows-powershell-basics\/\">Azure and Windows PowerShell: The Basics<\/a><\/li>\n<li><a href=\"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/azure-and-windows-powershell-getting-information\/\">Azure and Windows PowerShell: Getting Information<\/a><\/li>\n<li><a href=\"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/azure-and-windows-powershell-using-vm-extensions\/\">Azure and Windows PowerShell: Using VM Extensions<\/a><\/li>\n<\/ol>\n\n<p>As I mentioned in the previous article, I will not explain how to create Virtual Machines in detail, because Robert Cain published a great series about Azure VMs: <a href=\"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/create-azure-vms-powershell-part-1\/\">Create Azure VMs<\/a>. But after deploying a Virtual Machine in your Azure subscription, you will probably notice that you must configure the VM in order to suit your needs. This step is normal because the Virtual Machine has been deployed based on a template, which is usually generic and without any customization.<\/p>\n<p>Nowadays, deploying a Virtual Machine on premises or in your Azure subscription is very easy and can be done very quickly. Thanks to the DevOps methodology, SysAdmins and developers can work all together in order to automate the deployment process as much as possible. The main goal for the IT department is to be able to deliver the service as quickly as possible because time is money. This is the reason why the provisioning process must be simple, fast, and secure. One essential step you must automate is the configuration of each Virtual Machine. Working with Group Policy Objects is a good idea, but if your Azure Cloud platform is isolated from your on-premises datacenter, then you must consider other options. Azure VMs can be deployed and configured without post-deployment intervention based on a feature which is called \u2018Azure VM Extensions,\u2019 so you can use this feature to save time and to automate the configuration management process.<\/p>\n<h2>What are Azure VM Extensions?<\/h2>\n<p>In the Azure Cloud, a feature called \u2018Azure VM Extensions\u2019 can be used to do configuration management. With Azure VM Extensions, you can configure for example:<\/p>\n<ul>\n<li>Monitoring<\/li>\n<li>Security<\/li>\n<li>Configuration management<\/li>\n<li>Backup<\/li>\n<li>And more\u2026<\/li>\n<\/ul>\n<p>This feature uses Windows and Linux Azure agents that are automatically installed during the provisioning process. This agent is named \u2018Microsoft Azure Virtual Machine Agent,\u2019 and it is the only prerequisite in order to use the Azure VM extensions. If the agent is not installed in the Virtual Machine, you can install it very easily. In this case, you can download the <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=394789\">agent<\/a> and double-click the Windows installer file.<\/p>\n<p>Do not worry, you can manage these extensions outside of the Virtual Machine. You do not need to connect directly to the Virtual Machine to update the Extension. Note that VM Extensions can be bundled with a new VM deployment or run against any existing system.<\/p>\n<p>Many VM extensions are available for use with Azure Virtual Machines. As shown below, you can see the list from the Azure Portal by navigating to the <em>Virtual Machine<\/em> blade, and then by clicking <em>Extensions<\/em><strong>.<\/strong> To see the available extensions, click the <em>Add<\/em> button:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"297\" height=\"847\" class=\"wp-image-81223\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-68.png\" \/><\/p>\n<p>Depending on whether you deploy a Linux VM or a Windows VM, the possible VM Extensions will be different. You can also use Windows PowerShell to list the Azure VM Extensions using the following command. The <code>Get-AzureRmVMExtensionImage<\/code> cmdlet will list the VM Extensions available in the West Europe region. Replace the region where your Azure subscription is located:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; Get-AzureRmVmImagePublisher -Location &lt;Azure_Region&gt; | `\r\n&gt;&gt; Get-AzureRmVMExtensionImageType | `\r\n&gt;&gt; Get-AzureRmVMExtensionImage | Select Type, Version<\/pre>\n<p>\n<img loading=\"lazy\" decoding=\"async\" width=\"680\" height=\"478\" class=\"wp-image-81224\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-69.png\" \/><\/p>\n<p>The output has been truncated due to the large number of Azure VM Extensions. In the West Europe region, there are 810 VM extensions at your disposal.<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; (Get-AzureRmVmImagePublisher -Location &lt;Azure_Region&gt; | `\r\n&gt;&gt; Get-AzureRmVMExtensionImageType | `\r\n&gt;&gt; Get-AzureRmVMExtensionImage | Select Type, Version).count<\/pre>\n<p><strong><img loading=\"lazy\" decoding=\"async\" width=\"680\" height=\"95\" class=\"wp-image-81225\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-70.png\" \/><\/strong><\/p>\n<h3>Why is it important to notice that VM Extensions are not available in each Azure Region?<\/h3>\n<p>Publishers will update their VM Extension and make them available to regions at different times, so keep in mind that it means you could have VMs in different regions on different Extension versions.<\/p>\n<h3>Who authors the VM Extensions?<\/h3>\n<p>The VM Extensions are supported by publishers who are registered with Microsoft. It means that you cannot publish your VM Extensions without being in a relationship with Microsoft.<\/p>\n<h3>Why use the VM Extensions?<\/h3>\n<p>You must use the VM Extensions to simplify the configuration management of Virtual Machines. When you use a VM Extension, you only need to provide mandatory parameters, and that is all. One of the great things is you can install VM Extensions through the Azure Portal, Windows PowerShell, and Azure CLI.<\/p>\n<p>If you do not want to use VM Extensions, then common ways to automate the configuration of the lifecycle of the Virtual Machines are:<\/p>\n<ul>\n<li>Group Policy Object when it is applicable<\/li>\n<li>Login script when it is applicable<\/li>\n<li>Using Remote PowerShell<\/li>\n<li>Preinstalling software or components directly on the disk, so in other words, installing your tools in your gold image<\/li>\n<\/ul>\n<p>If you work with DevOps methodology, trust me, you will have to use Azure VM Extensions.<\/p>\n<h2>Using Azure VM Extensions<\/h2>\n<p>It is time to work with Azure VM Extensions in practice. In this guide, I will work with a Virtual Machine named <em>DC1<\/em>. First, I need to check the VM Agent status using the following command:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Get-AzureRmVM -Name &lt;VM_Name&gt; -ResourceGroupName &lt;RG_Name&gt; | Select -ExpandProperty OSProfile | Select -ExpandProperty Windowsconfiguration | Select ProvisionVMAgent<\/pre>\n<p>The command returns <em>True<\/em> which indicates that the VM Agent is installed and running.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"860\" height=\"178\" class=\"wp-image-81226\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-71.png\" \/><\/p>\n<p>It is also possible to confirm if the agent is installed directly in the Virtual Machine. Log in to the VM and open the Task Manager to check the <em>WindowsAzureGuestAgent.exe<\/em> process. It means that the VM Agent is installed:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"971\" height=\"317\" class=\"wp-image-81227\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-72.png\" \/><\/p>\n<p>Note: if the VM Agent is not installed, you can download it from <a href=\"https:\/\/go.microsoft.com\/fwlink\/?LinkID=394789&amp;clcid=0x409\">here<\/a>.<\/p>\n<h3>VM Extensions using the Azure Portal<\/h3>\n<p>The first way to install a VM Extension is the Azure Portal. Navigate to the Virtual Machines blade, start the Virtual Machine, and click <em>Extension<\/em> to open a new blade. In my case, no extensions have been found, so I must click <em>+ Add<\/em> and browse the list to select the extension I want to install:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"688\" height=\"457\" class=\"wp-image-81228\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-73.png\" \/><\/p>\n<p>When you select a VM Extension, a new blade will appear and prompt for mandatory parameters. Here, I select the Site24x7 agent, which is a third-party monitoring application.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"273\" height=\"70\" class=\"wp-image-81229\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-74.png\" \/><\/p>\n<p>Information is provided telling you what the extension provides and shows you how to create an account and get a key for the service. After testing this extension, do not forget to remove the extension since this is a paid resource.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"574\" height=\"468\" class=\"wp-image-81230\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-75.png\" \/><\/p>\n<p>Once you have the key, click <em>Create<\/em>. You will be asked to supply the key here:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"586\" height=\"174\" class=\"wp-image-81231\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-76.png\" \/><\/p>\n<p>Wait a few minutes until the extension is installed on your VM. You\u2019ll see it in the Start menu:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"927\" height=\"148\" class=\"wp-image-81232\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-77.png\" \/><\/p>\n<p>The VM Extension will also be visible in the list in the Azure Portal:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"883\" height=\"177\" class=\"wp-image-81233\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-78.png\" \/><\/p>\n<p>To uninstall the Extension, simply click on the name in your Azure Portal, and select <em>Uninstall<\/em>. The process is very simple, and it works very well so you can use it without any risk.<\/p>\n<h3>VM Extensions using PowerShell<\/h3>\n<p>Of course, to automate the configuration management of the VM, it is essential to script some tasks to save time and avoid human mistakes. First, it is possible to check if there are VM extensions already installed on a Virtual Machine. Several properties can be retrieved using the <em>Get-AzureRmVM<\/em> cmdlet:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Get-AzureRmVM -Name &lt;VM_Name&gt; -ResourceGroupName &lt;RG_Name&gt; | Format-List *<\/pre>\n<p>In my case, I can confirm that a VM Extension is already installed in the VM:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"860\" height=\"401\" class=\"wp-image-81234\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-79.png\" \/><\/p>\n<p>To install a new VM Extension, there are several PowerShell cmdlets at your disposal that you can list using the following command:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true \">PS &gt; Get-Command Set-AzureRM*Extension*<\/pre>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"733\" height=\"283\" class=\"wp-image-81235\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-80.png\" \/><\/p>\n<p>To understand how to use these cmdlets, I advise the <code>Get-Help<\/code> cmdlet followed by the <code>examples<\/code> parameter. In the example, the <em>BGInfo<\/em> tool can be installed in the VM using the following command after substituting your VM name and resource group:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Set-AzureRmVMBGInfoExtension \u2013VMName &lt;VM_Name&gt; -Name \"BGInfo\" -ResourceGroupName &lt;RG_Name&gt;<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"809\" height=\"143\" class=\"wp-image-81236\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-81.png\" \/><\/p>\n<p>Confirm the new extension installed by listing the properties:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Get-AzureRMVM -Name &lt;VM_Name&gt; -ResourceGroupName &lt;RG_Name&gt;  | fl *<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"809\" height=\"433\" class=\"wp-image-81237\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-82.png\" \/><\/p>\n<p>When logging to the Virtual Machine, BGInfo is up and running.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1078\" height=\"432\" class=\"wp-image-81238\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-83.png\" \/><\/p>\n<p>To troubleshoot any issue or deployment error, I advise you to run the following command, which returns the extension status:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Get-AzureRmVM -ResourceGroupName &lt;RG_Name&gt; -VMName &lt;VM_Name&gt; -Status<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"788\" height=\"308\" class=\"wp-image-81239\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-84.png\" \/><\/p>\n<h3>VM Extensions using Azure CLI<\/h3>\n<p>Another way to work with Azure VM Extensions, is to use Azure CLI as you did with PowerShell. To list the VM Extensions attached to a VM, use the following:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">az vm extension list --resource-group &lt;RG_Name&gt; --vm-name &lt;VM_Name&gt;<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"809\" height=\"548\" class=\"wp-image-81240\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-85.png\" \/><\/p>\n<p>Remove an extension attached to the Virtual Machine with the following command:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">Az vm extension delete \u2013g &lt;RG_Name&gt; --vm-name &lt;VM_Name&gt; -n &lt;VMExtension_Name&gt;<\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"639\" height=\"98\" class=\"wp-image-81241\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-86.png\" \/><\/p>\n<p>Depending on the VM extension you are removing, it can be time-consuming.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"736\" height=\"157\" class=\"wp-image-81242\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-87.png\" \/><\/p>\n<p>To get more information about VM Extensions with Azure CLI, you can read this <a href=\"https:\/\/docs.microsoft.com\/en-us\/cli\/azure\/vm\/extension?view=azure-cli-latest\">article<\/a>.<\/p>\n<h3>Adding VM Extensions during the deployment<\/h3>\n<p>Until now, Azure VM Extensions have been installed after the provisioning process. It is important to know that configuration can be updated after the provisioning process, but it is also important to indicate which configuration will be applied before the provisioning. At the step number 3 of the creation process, click <em>Extension<\/em>s to open a new blade that will list the available VM Extensions:<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" width=\"1253\" height=\"388\" class=\"wp-image-81243\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-88.png\" \/><\/strong><\/p>\n<h3>Custom Scripts<\/h3>\n<p>Using Azure VM Extensions can be very helpful to configure new Virtual Machine, however, sometimes it is not enough to suit your needs, so it is essential to use custom scripts to perform specific tasks. There are few things to take into consideration, such as:<\/p>\n<ul>\n<li>Script Location: The script can be stored on GitHub, Azure Blob Storage, or anywhere the VM can access the repository.<\/li>\n<li>Internet Connectivity: If your script is located on the Internet, then the firewall rules must be opened.<\/li>\n<li>Operating System: if you run a bash script, for example, you must run the script on supported OS\u2019s (e.g. Linux OS)<\/li>\n<li>Timeout: 90 minutes are allowed for the script to run.<\/li>\n<\/ul>\n<p>To finish this article, here is an example of custom script implementation with PowerShell:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Set-AzureRmVMCustomScriptExtension -ResourceGroupName &lt;RG_Name&gt; `\r\n    -VMName &lt;VM_Name&gt; `\r\n    -Location &lt;Location&gt; `\r\n    -FileUri &lt;Script_URL&gt; `\r\n    -Run &lt;Command_to_execute&gt; `\r\n    -Name &lt;Extension_Name&gt;<\/pre>\n<p>For instance, I can run a custom script stored on my Azure Blob storage. The script is very basic and will write the <strong>Get-Process<\/strong> cmdlet results in a text file:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Get-Process | Out-File C:\\proc.txt<\/pre>\n<p>Run the following command to deploy your custom script extension:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS &gt; Set-AzureRmVmCustomScriptExtension -ResourceGroupName &lt;ResourceGroup&gt; `\r\n-VMName &lt;VM_Name&gt; `\r\n-Location &lt;location&gt; `\r\n-FileUri &lt;url&gt; `\r\n-Run &lt;Script&gt; `\r\n-name &lt;FriendlyName&gt;<\/pre>\n<p>To easily manage your Azure Storage Account, I advise you to read the following <a href=\"https:\/\/www.red-gate.com\/simple-talk\/cloud\/cloud-development\/using-azure-storage-explorer\/\">article<\/a> which will help you to easily find the file URL.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"686\" height=\"212\" class=\"wp-image-81244\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-89.png\" \/><\/p>\n<p>Confirm that the script has been executed successfully from the Azure Portal or directly inside the Virtual Machine:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1141\" height=\"584\" class=\"wp-image-81245\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/10\/word-image-90.png\" \/><\/p>\n<h2>Conclusion<\/h2>\n<p>This third article in this series described steps to automate configuration management tasks of the lifecycle of Azure Virtual Machines using the following ways:<\/p>\n<ul>\n<li>Azure Portal<\/li>\n<li>Windows PowerShell<\/li>\n<li>And Azure CLI<\/li>\n<\/ul>\n<p>Configuring Azure VMs with VM Extensions can be done when the VM Guest Agent is installed in the Virtual Machine. If the agent is not installed and you cannot start the VM, then you can install it in an <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/virtual-machines\/windows\/install-vm-agent-offline\">offline mode<\/a>.<\/p>\n<p>VM Extensions are software components that extend the functionality of the Virtual Machine. Note that you can add multiple extensions on the same VM. Azure VM Extensions supported Linux and Windows Virtual Machines. If you are limited with the default VM Extensions, do not forget to use the custom script extension to suit your needs.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the third part of his series, Nicolas Prigent describes how to run post-deployment configuration and automation tasks on Azure Virtual Machines. Nicolas explains how to use Azure VM Extensions using the Azure PowerShell module to save time during the provisioning process.&hellip;<\/p>\n","protected":false},"author":158223,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[137091,53,35],"tags":[95506],"coauthors":[6804],"class_list":["post-81222","post","type-post","status-publish","format-standard","hentry","category-azure","category-featured","category-powershell","tag-automate"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/81222","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/158223"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=81222"}],"version-history":[{"count":5,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/81222\/revisions"}],"predecessor-version":[{"id":81306,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/81222\/revisions\/81306"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=81222"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=81222"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=81222"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=81222"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}