Azure Update Management (Log Analytics Agents & Automation Accounts)

Published Dec 19 2021 11:00 PM 5,752 Views


Many of our customers would like to start patching servers as soon as possible using a single Update Management Solution deployed on a single Log Analytics Workspace. To achieve this goal you need to deploy the Azure Monitor Agent (newer version) or the Microsoft Monitoring Agent (current version) on machines that could be domain joined or even on a workgroup. To add even more complexity, the use of PowerShell could be restricted.  

The above requirements can be broken up into 2 scenarios:



[Scenario 1] – Virtual Machine on Azure that is already connected to the domain. It might or might not have the agent. It might or might not have the proxy settings filled in.

[Scenario 2] – Virtual Machine on Azure that is not connected to the domain. It might or might not have the agent or proxy settings filled in.

We will now explore 3 Options for deploying the agents and 3 Query Methods to confirm if the installation was actually successful.


The 3 Options for deploying the Agent


Option 1 – Azure Policy


For both Scenario 1 and Scenario 2 this can be used. We would choose the Enable Azure Monitor for VMs Policy Initiative.



It can be assigned to any Management Group or Subscription



Simply choose your Log Analytics Workspace that is connected to the Automation Account Containing Update Management



I normally also create a Remediation Managed Identity



Set a default Non-Compliance message



And create



If we immediately go to the Deploy-VM-Monitoring we can view the compliance



By clicking on Non-Compliant Resources I can see the machines



But this policy might not have the Failed/Succeeded metric for the actual extension. For that we can use 3 query methods: Azure Resource Graph Explorer, Azure CLI Bash, Azure Cloud Shell PowerShell.


Option 2 – PowerShell


For Scenario 1 and Scenario 2 Our official method to deploy the Log Analytics Extension with PowerShell in Azure can be seen below.



$PublicSettings = @{"workspaceId" = "myWorkspaceId"}
$ProtectedSettings = @{"workspaceKey" = "myWorkspaceKey"}
Set-AzVMExtension -ExtensionName "MicrosoftMonitoringAgent" `
   -ResourceGroupName "myResourceGroup" `
    -VMName "myVM" `
    -Publisher "Microsoft.EnterpriseCloud.Monitoring" `
    -ExtensionType "MicrosoftMonitoringAgent" `
    -TypeHandlerVersion 1.0 `
    -Settings $PublicSettings `
    -ProtectedSettings $ProtectedSettings `
    -Location WestUS



Or if you are using the Azure Monitor Agent



Set-AzVMExtension -ExtensionName "AMAWindows" `
    -ExtensionType AzureMonitorWindowsAgent `
    -Publisher " Microsoft.Azure.Monitor" `
    -ResourceGroupName "myResourceGroup" `
    -VMName "myVM" `
    -TypeHandlerVersion 1.0 `
    -Location WestUS



If the Extension already Exists, you mentioned there needs to some proxy settings filled in.

One way to configure Proxy settings quickly on multiple machines would be to use the Custom Script Extension. PowerShell 7 brings the functionality “-Parallel” which will run multiple instances of the same script.

To manually run the Customer Script Extension Proxy Setting on a Server and set the correct Workspace we can use the below script



#This section adds a new Workspace
$workspaceId = "<WS ID>"
$workspaceKey = "<WS KEy>"

$mma = New-Object -ComObject 'AgentConfigManager.MgmtSvcCfg'
$mma.AddCloudWorkspace($workspaceId, $workspaceKey)

#This section is where the Proxy can be configured
$proxyMethod = $mma | Get-Member -Name 'SetProxyUrl'
if (!$proxyMethod)
    Write-Output 'Health Service proxy API not present, will not update settings.'
#Clears Proxy settings in MMA
Write-Output "Clearing proxy settings."

#Adds new proxy settings
Write-Output "Setting proxy to $ProxyDomainName"





If we wanted to Automate this for multiple machines, we could do something like mentioned in below article.

How to run scripts against multiple Azure VMs by using Run Command - Thomas Maurer


Option 3 – Desired State Configuration


Desired State Configuration is another great way of ensuring the MMA is present on machines and configured correctly. This also makes execution easier because you can use a specified approved account or Hybrid runbook worker to execute the DSC in case of strict security rules where only certain accounts can run PowerShell scripts.


  1. Download the MMA Agent



  1. Extract the contents because we want the MSI



  1. Open Notepad and save the below as “Get-MSIFileInformation.ps1” in your Downloads folder.


try {
    $WindowsInstaller = New-Object -ComObject WindowsInstaller.Installer
    $MSIDatabase = $WindowsInstaller.GetType().InvokeMember("OpenDatabase","InvokeMethod",$Null,$WindowsInstaller,@($Path.FullName,0))
    $Query = "SELECT Value FROM Property WHERE Property = '$($Property)'"
    $View = $MSIDatabase.GetType().InvokeMember("OpenView","InvokeMethod",$null,$MSIDatabase,($Query))
    $View.GetType().InvokeMember("Execute", "InvokeMethod", $null, $View, $null)
    $Record = $View.GetType().InvokeMember("Fetch","InvokeMethod",$null,$View,$null)
    $Value = $Record.GetType().InvokeMember("StringData","GetProperty",$null,$Record,1)
    return $Value
catch {
    Write-Output $_.Exception.Message



  1. Open PowerShell and cd to Downloads, and run the Newly saved MSI Script

.\Get-MSIFileInformation.ps1 -Path C:\Users\<youruser>\Downloads\MMASetup-A
MD64\MOMAgent.msi -Property ProductCode




  1. Create Automation Variables for

OPSINSIGHTS_WS_ID  (This is your Workspace you need the server to connect to),

OPSINSIGHTS_WS_KEY (This is the key for the workspace),

OPINSIGHTS_PROXY_URL (This is the proxy URL in format




  1. Import the Module into the Automation Account





  1. Save the below script as MMAgent.ps1 and Modify the ProductID that was found in Step 4. Also update the ProductID as found in Step 4.


Configuration MMAgent
    $OIPackageLocalPath = "C:\Deploy\MMASetup-AMD64.exe"
    $OPSINSIGHTS_WS_ID = Get-AutomationVariable -Name "OPSINSIGHTS_WS_ID"
    $OPSINSIGHTS_WS_KEY = Get-AutomationVariable -Name "OPSINSIGHTS_WS_KEY"
    $OPINSIGHTS_PROXY_URL = Get-AutomationVariable -Name " OPINSIGHTS_PROXY_URL"

    Import-DscResource -ModuleName xPSDesiredStateConfiguration
    Import-DscResource -ModuleName PSDesiredStateConfiguration

    Node OMSnode {
        Service OIService
            Name = "HealthService"
            State = "Running"
            DependsOn = "[Package]OI"
        xRemoteFile OIPackage {
            Uri = ""
            DestinationPath = $OIPackageLocalPath
        Package OI {
            Ensure = "Present"
            Path  = $OIPackageLocalPath
            Name = "Microsoft Monitoring Agent"
            ProductId = "88EE688B-31C6-4B90-90DF-FBB345223F94"
            DependsOn = "[xRemoteFile]OIPackage"



  1. Import the MMAgent.ps1 script into the Automation Account State Configuration under Configurations. After the import click on MMAgent and click Compile.






  1. Assign a computer or node and within a few minutes the Agent will get pushed to the machine.








The 3 Methods to Query Agent Installation


1.      Azure Resource Graph Explorer [Query All Servers]*



// LogAnalyticsandHealthyAgentv5
// All Running, All Health and All Monitoring Extensions
// Click the "Run query" command above to execute the query and see results.
// Linux and Windows Agents
// Click the "Run query" command above to execute the query and see results.
// This query will show machines that are currently running.
// This query will show the extensions that relates to MicrosoftMonitoringAgent','AzureMonitorWindowsAgent'and 'OMSAgentForLinux'

| where type == 'microsoft.compute/virtualmachines'
| where properties.extended.instanceView.powerState.displayStatus=="VM running" and properties.osProfile.windowsConfiguration.provisionVMAgent=="true" or properties.extended.instanceView.powerState.displayStatus=="VM running" and properties.osProfile.linuxConfiguration.provisionVMAgent=="true"
| extend
    JoinID = toupper(id),
    OSName = tostring(name),
    OSType = tostring(properties.storageProfile.osDisk.osType),
    RSG = tostring(resourceGroup),
    SUB = tostring(subscriptionId),
    LOC = tostring(location)
| join kind=leftouter(
| where type == 'microsoft.compute/virtualmachines/extensions' and name == 'MicrosoftMonitoringAgent' or name == 'AzureMonitorWindowsAgent' or name == 'OMSAgentForLinux'
// | where properties.provisioningState == 'Succeeded'
  VMId = toupper(substring(id, 0, indexof(id, '/extensions'))),
  props = tostring(properties.settings),
  prvstatus = tostring(properties)
)on $left.JoinID == $right.VMId
| summarize Extensions = make_list(props) by id, OSName, OSType, RSG, SUB, LOC, prvstatus



Example of execution. This will show me all machines that are running and their provisionState of the Extension that related to Log Analytics.


The subscription where the policies have not applied yet.



Another subscription to showcase the Provisioning Status



*Although Resource Graph is the easiest way to get information about all machines at once it takes longer to update than the Bash or PowerShell. This means if you are querying your machines and you see one has failed and you repair the failure Resource Graph will take time to update. Therefore if you want realtime information please refer to Azure CLI or Cloud Shell, the limitation being only looking at one server.


2.      Azure CLI Bash [Deep Dive 1 Server Real Time]

If I find that I need to deep dive into one specific server to see if the Extension Provisioning succeeded or failed I can use Cloud Shell Bash in the Azure Portal.

The command is:



az vm extension show -g <resource group> --vm-name <vmname> --name MicrosoftMonitoringAgent





3.      Azure Cloud Shell PowerShell [Deep Dive 1 Server]

The Bash is great at showing a one pager but if I wanted to dive into even more detail about why an extension failed I can use Cloud Shell PowerShell

The command is:



Get-AzVM -ResourceGroupName <resource group> -Name <server> -Status



I can look at the Extensions Portion and I will have the error code and message



And the ExtensionHandlers will give me some more information



These are only methods to assist you in querying your VM Extensions. We need them to be healthy to connect to the Automation Account.


Thank you for reading and I hope this has been beneficial to you in your patching journey.


Some more helpful Links


PowerShell/Get-MSIFileInformation.ps1 at master · NickolajA/PowerShell (

Install Log Analytics agent on Windows computers - Azure Monitor | Microsoft Docs

Install the Azure Monitor agent - Azure Monitor | Microsoft Docs

Log Analytics virtual machine extension for Windows - Azure Virtual Machines | Microsoft Docs



The sample scripts are not supported under any Microsoft standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility of such damages.


Version history
Last update:
‎Dec 21 2021 07:24 AM
Updated by:
We support Ukraine and condemn war. Push Russian government to act against war. Be brave, vocal and show your support to Ukraine. Follow the latest news HERE