Résoudre les problèmes liés à l’agent Log Analytics pour Windows

Cet article fournit une assistance sur les erreurs que vous pourriez rencontrer avec l’agent Log Analytics pour Windows dans Azure Monitor et suggère des solutions possibles pour les résoudre.

Outil de résolution des problèmes Log Analytics

L’Outil de résolution des problèmes Windows de l’agent Log Analytics est un ensemble de scripts PowerShell conçus pour faciliter la recherche et le diagnostic des problèmes liés à l’agent Log Analytics. Il est inclus automatiquement avec l’agent lors de l’installation. L’exécution de l’outil doit être la première étape du diagnostic d’un problème.

Utiliser l’outil de résolution des problèmes

  1. Ouvrez l’invite PowerShell en tant qu’administrateur sur l’ordinateur sur lequel l’agent Log Analytics est installé.

  2. Accédez au répertoire dans lequel se trouve l’outil :

    cd "C:\Program Files\Microsoft Monitoring Agent\Agent\Troubleshooter"

  3. Exécutez le script principal à l’aide de la commande suivante :

    .\GetAgentInfo.ps1

  4. Sélectionnez un scénario de résolution des problèmes.

  5. Suivez les instructions qui s’affichent dans la console. Notez qu’une intervention manuelle est requise pour arrêter la collecte des journaux dans les étapes des journaux de suivi. En fonction de la reproductibilité du problème, attendez le temps nécessaire et sélectionnez « s » pour arrêter la collecte des journaux et passer à l’étape suivante.

    L’emplacement du fichier de résultats est consigné à la fin et mis en évidence dans la nouvelle fenêtre d’explorateur qui s’ouvre.

Installation

L’Outil de résolution des problèmes est inclus automatiquement lors de l’installation de l’agent Log Analytics, avec la build 10.20.18053.0 et les versions ultérieures.

Scénarios couverts

L’outil de résolution des problèmes vérifie les scénarios suivants :

  • L’agent ne signale pas les données ou des données de pulsation sont manquantes.
  • Échec du déploiement de l’extension d’agent.
  • L’agent plante.
  • L'agent consomme beaucoup de CPU ou de mémoire.
  • Échecs d’installation et de désinstallation.
  • Les journaux personnalisés présentent des problèmes.
  • La passerelle OMS présente des problèmes.
  • Les compteurs de performances présentent des problèmes.
  • Les journaux de l’agent ne peuvent pas être collectés.

Notes

Si vous rencontrez un problème, exécutez l’Outil de résolution des problèmes. Le fait d’avoir les journaux dès le départ permettra à notre équipe de support de résoudre plus rapidement votre problème.

Sources importantes de résolution des problèmes

Pour faciliter la résolution des problèmes liés à l’agent Log Analytics pour Windows, l’agent enregistre les événements dans le journal des événements Windows, en particulier sous Application et services\Operations Manager.

Problèmes de connectivité

Si l’agent communique via un serveur proxy ou un pare-feu, des restrictions peuvent empêcher la communication à partir de l’ordinateur source et du service Azure Monitor. Si la communication est bloquée, à cause d’une configuration incorrecte, l’inscription auprès d’un espace de travail peut échouer quand vous tentez d’installer l’agent ou de configurer l’agent après l’installation pour envoyer les rapports à un autre espace de travail. La communication avec l’agent peut échouer après une inscription réussie. Cette section décrit les méthodes permettant de résoudre des problèmes de ce type avec l’agent Windows.

Vérifiez que le pare-feu et le proxy sont configurés pour autoriser les URL et les ports suivants, indiqués dans le tableau ci-dessous. Vérifiez également que l’inspection HTTP n’est pas activée pour le trafic web. Elle peut empêcher un canal TLS sécurisé entre l'agent et Azure Monitor.

Ressource de l’agent Ports Sens Ignorer l’inspection HTTPS
*.ods.opinsights.azure.com Port 443 Règle de trafic sortant Oui
*.oms.opinsights.azure.com Port 443 Règle de trafic sortant Oui
*.blob.core.windows.net Port 443 Règle de trafic sortant Oui
*.agentsvc.azure-automation.net Port 443 Règle de trafic sortant Oui

Pour obtenir les informations relatives au pare-feu nécessaires pour Azure Government, consultez Azure Government Monitoring + Management. Si vous envisagez d’utiliser le Runbook Worker hybride Azure Automation pour vous connecter et vous inscrire auprès du service Automation afin d’utiliser des runbooks et des solutions de gestion dans votre environnement, il doit avoir accès au numéro de port et aux URL décrites dans la section Configurer votre réseau pour le Runbook Worker hybride.

Plusieurs méthodes vous permettent de vérifier si l’agent communique correctement avec Azure Monitor :

  • Activez l’évaluation d’intégrité de l’agent Azure Log Analytics dans l’espace de travail. Dans le tableau de bord Agent Health, consultez la colonne Nombre d’agents inactifs pour voir rapidement si l’agent est répertorié.

  • Exécutez la requête suivante pour vérifier que l’agent envoie une pulsation à l’espace de travail auquel il doit rendre compte. Remplacez <ComputerName> par le nom réel de la machine.

    Heartbeat 
    | where Computer like "<ComputerName>"
    | summarize arg_max(TimeGenerated, * ) by Computer 
    

    Si l’ordinateur communique avec le service, la requête doit retourner un résultat. Si la requête n’a pas retourné de résultat, vérifiez tout d’abord que l’agent est configuré pour rendre compte à l’espace de travail correct. S’il est configuré correctement, passez à l’étape 3 et inspectez le journal des événements Windows pour déterminer si l’agent consigne le problème qui peut l’empêcher de communiquer avec Azure Monitor.

  • Une autre méthode permettant d’identifier un problème de connectivité consiste à exécuter l’outil TestCloudConnectivity. L’outil est installé par défaut avec l’agent dans le dossier %SystemRoot%\Program Files\Microsoft Monitoring Agent\Agent. À partir d’une invite de commandes avec élévation de privilèges, accédez au dossier et exécutez l’outil. L’outil retourne des résultats et met en surbrillance l’endroit où le test échoue. Par exemple, peut-être était-t-il lié à un port ou à une URL particulière qui était bloquée.

    Screenshot that shows TestCloudConnection tool execution results.

  • Filtrez le journal des événements Operations Manager par Sources d’événementsModules du service de contrôle d’intégrité, HealthService et Connecteur de service, et filtrez par Niveau d’événementAvertissement et Erreur pour vérifier s’il contient des événements écrits, issus du tableau suivant. Si tel est le cas, passez en revue les étapes de résolution incluses pour chaque événement possible.

    ID de l’événement Source Description Résolution
    2133 & 2129 Service de contrôle d’intégrité Échec de la connexion de l’agent au service. Cette erreur peut se produire lorsque l’agent ne peut pas communiquer directement ou via un pare-feu ou un serveur proxy avec le service Azure Monitor. Vérifiez les paramètres de proxy de l’agent ou que le pare-feu ou le proxy réseau autorise le trafic TCP de l’ordinateur au service.
    2138 Modules du service de contrôle d’intégrité Le proxy requiert une authentification. Configurez les paramètres de proxy de l’agent et spécifiez le nom d’utilisateur/mot de passe requis pour s’authentifier auprès du serveur proxy.
    2129 Modules du service de contrôle d’intégrité Échec de la connexion. Échec de la négociation TLS. Vérifiez vos paramètres TCP/IP de carte réseau et les paramètres de proxy de l’agent.
    2127 Modules du service de contrôle d’intégrité Code d'erreur de l'échec d'envoi de données. Si cela se produit uniquement périodiquement pendant la journée, il peut s’agir d’une anomalie aléatoire qui peut être ignorée. Surveillez pour comprendre la fréquence à laquelle cela se produit. Si cela se produit souvent au cours de la journée, vérifiez tout d’abord votre configuration réseau et les paramètres de proxy. Si la description inclut le code d’erreur HTTP 404 et qu’il s’agit de la première fois où l’agent tente d’envoyer des données au service, elle inclura une erreur 500 avec un code d’erreur 404 interne. Le code d'erreur 404 signifie qu’un élément est « introuvable », ce qui indique que la zone de stockage pour le nouvel espace de travail est toujours en cours de provisionnement. Lors de la tentative suivante, les données seront correctement écrites dans l’espace de travail, comme prévu. Une erreur HTTP 403 peut indiquer un problème d’autorisation ou d’informations d’identification. Des informations supplémentaires sont incluses avec l’erreur 403 pour aider à résoudre le problème.
    4000 Connecteur de service Échec de la résolution du nom DNS. La machine n’a pas pu résoudre l’adresse Internet utilisée lors de l’envoi de données au service. Ce problème peut être des paramètres de résolution DNS sur votre machine, des paramètres de proxy incorrects ou un problème DNS temporaire avec votre fournisseur. Si cela se produit régulièrement, cela peut provenir d’un problème temporaire de réseau.
    4001 Connecteur de service La connexion au service a échoué. Cette erreur peut se produire lorsque l’agent ne peut pas communiquer directement ou via un pare-feu ou un serveur proxy avec le service Azure Monitor. Vérifiez les paramètres de proxy de l’agent ou que le pare-feu ou le proxy réseau autorise le trafic TCP de l’ordinateur au service.
    4002 Connecteur de service Le service a retourné le code d’état HTTP 403 en réponse à une requête. Vérifiez l’intégrité du service auprès de l’administrateur de service. La requête sera retentée ultérieurement. Cette erreur est écrite pendant la phase d’inscription initiale de l’agent. Vous verrez une URL similaire à https://<workspaceID>.oms.opinsights.azure.com/AgentService.svc/AgentTopologyRequest. Un code d’erreur 403 signifie « interdit » et peut être causé par un ID ou une clé d’espace de travail mal orthographié. La date et l’heure peuvent également être incorrectes sur l’ordinateur. Si l’heure varie de +/- 15 minutes par rapport à l’heure actuelle, l’intégration échoue. Pour corriger ce problème, mettez à jour la date et/ou l’heure de votre ordinateur Windows.

Problèmes de collecte de données

Une fois que l’agent est installé et rend compte à son ou ses espaces de travail configurés, il peut cesser de recevoir la configuration, de collecter ou de transférer les performances, les journaux ou d’autres données au service selon ce qui est activé et qui cible l’ordinateur. Vous devez déterminer :

  • Est-ce un type de données spécifique ou toutes les données qui ne sont pas disponibles dans l’espace de travail ?
  • Le type de données est-il spécifié par une solution ou spécifié dans le cadre de la configuration de la collecte des données d’espace de travail ?
  • Combien d’ordinateurs sont-ils affectés ? Un seul ou plusieurs ordinateurs rendent-ils compte à l’espace de travail ?
  • Cela fonctionnait-il et a-t-il cessé à un moment précis de la journée ou cela n’a-t-il jamais été collecté ?
  • La requête de recherche dans les journaux que vous utilisez est-elle syntaxiquement correcte ?
  • L’agent a-t-il jamais reçu sa configuration à partir d’Azure Monitor ?

La première étape du dépannage consiste à déterminer si l’ordinateur envoie un événement de pulsation.

Heartbeat 
    | where Computer like "<ComputerName>"
    | summarize arg_max(TimeGenerated, * ) by Computer

Si la requête retourne des résultats, vous devez déterminer si un type de données particulier n’est pas collecté et transféré au service. Ce problème peut être dû à l’agent qui ne reçoit pas la configuration mise à jour du service ou à certains autres symptôme empêchant l’agent de fonctionner normalement. Procédez comme suit pour poursuivre le dépannage.

  1. Ouvrez une invite de commandes avec élévation de privilèges sur l’ordinateur et redémarrez le service de l’agent en entrant net stop healthservice && net start healthservice.

  2. Ouvrez le journal des événements Operations Manager et recherchez les ID d’événements7023, 7024, 7025, 7028 et 1210 à partir de Source d'événementHealthService. Ces événements indiquent que l’agent reçoit correctement la configuration d’Azure Monitor et surveillent activement l’ordinateur. La description de l’événement d’ID 1210 spécifie également sur sa dernière ligne toutes les solutions et les informations qui sont incluses dans l’étendue de la supervision sur l’agent.

    Screenshot that shows an Event ID 1210 description.

  3. Patientez quelques minutes. Si vous ne voyez pas les données attendues dans les résultats de la requête ou la visualisation, selon que vous affichez les données à partir d’une solution ou d’Insight, à partir du journal des événements Operations Manager, recherchez Sources d’événementHealthService et Modules de service de contrôle d’intégrité. Filtrez par Niveau d’événementAvertissement et Erreur pour vérifier s’il contient des événements écrits, issus du tableau suivant.

    ID de l’événement Source Description Résolution
    8000 HealthService Cet événement spécifie si un flux de travail lié aux performances, à un événement ou à un autre type de données collectées est dans l’incapacité de transférer au service pour ingestion à l’espace de travail. L'ID d'événement 2136 de HealthService source est écrit avec cet événement et peut indiquer que l'agent est incapable de communiquer avec le service. Les raisons possibles peuvent être des erreurs de configuration du proxy et des paramètres d’authentification, de panne réseau ou le pare-feu ou le proxy du réseau n'autorise pas le trafic TCP de l'ordinateur vers le service.
    10102 et 10103 Modules du service de contrôle d’intégrité Le workflow n’a pas pu résoudre la source de données. Ce problème peut se produire si l’instance ou le compteur de performances spécifié n’existe pas sur l’ordinateur ou est incorrectement défini dans les paramètres de données de l’espace de travail. S’il s’agit d’un compteur de performances spécifié par l’utilisateur, vérifiez que les informations spécifiées suivent le format correct et existent sur les ordinateurs cibles.
    26002 Modules du service de contrôle d’intégrité Le workflow n’a pas pu résoudre la source de données. Ce problème peut se produire si le journal des événements Windows spécifié n’existe pas sur l’ordinateur. Cette erreur peut être ignorée en toute sécurité si l’ordinateur n’est pas censé avoir inscrit ce journal des événements. Sinon, s’il s’agit d’un journal des événements spécifié par l’utilisateur, vérifiez que les informations spécifiées sont exactes.

Problèmes de certificat épinglé avec des agents de supervision Microsoft plus anciens - Changement cassant

Vue d’ensemble de la modification de l’autorité de certification racine

À compter du 30 juin 2023, Log Analytics back-end n’acceptera plus les connexions de MMA qui font référence à un certificat racine obsolète. Ces MMA sont des versions antérieures à la version d’hiver 2020 (Agent Log Analytics) et antérieures à SCOM 2019 UR3 (SCOM). Toute version, bundle : 10.20.18053/extension : 1.0.18053.0 ou ultérieure, n’aura aucun problème, ainsi que toute version ultérieure à SCOM 2019 UR3. Tout agent antérieur à celui-ci s’interrompt, puis ne fonctionne plus et ne se charge plus dans Log Analytics.

Qu’est-ce que JEA exactement ?

Dans le cadre d’un effort de sécurité continu sur différents services Azure, Azure Log Analytics passera officiellement de la racine de l’autorité de certification Baltimore CyberTrust à la racine de l’autorité de certification DigiCert Global G2. Cette modification aura un impact sur les communications TLS avec Log Analytics si le nouveau certificat racine de l’autorité de certification DigiCert Global G2 est manquant dans le système d’exploitation ou si l’application fait référence à l’ancienne autorité de certification racine Baltimore. Cela signifie que Log Analytics n’acceptera plus les connexions de MMA qui utilisent cette ancienne autorité de certification racine après sa mise hors service.

Produits de solution

Vous avez peut-être reçu la notification de changement cassant, même si vous n’avez pas installé personnellement Microsoft Monitoring Agent. En effet, plusieurs produits Azure tirent profit de Microsoft Monitoring Agent. Si vous utilisez l’un de ces produits, vous serez sans doute affecté, car ils tirent profit de l’agent Windows Log Analytics. Pour les produits avec les liens ci-dessous, des instructions spécifiques vous obligeront sans doute à effectuer une mise à niveau vers le dernier agent.

Identification et remise en état des agents cassants

Pour les déploiements avec un nombre limité d’agents, nous vous recommandons vivement de mettre à niveau votre agent par nœud en suivant ces instructions de gestion.

Pour les déploiements avec plusieurs nœuds, nous avons écrit un script qui détecte les MMO cassants affectés par abonnement, puis les met à niveau vers la dernière version. Vous devez exécuter ces scripts de manière séquentielle, en commençant par UpdateMMA.ps1, puis en poursuivant par UpgradeMMA.ps1. Selon la machine, le script peut prendre un certain temps. PowerShell 7 ou version ultérieure doit s’exécuter pour éviter un dépassement de délai.

UpdateMMA.ps1 Ce script passe par les machines virtuelles de vos abonnements, recherche les MMO existants installés, puis génère un fichier .csv d’agents à mettre à niveau.

UpgradeMMA.ps1 Ce script utilise le fichier .CSV généré dans UpdateMMA.ps1 pour mettre à niveau tous les MMO cassants.

Ces deux scripts peuvent prendre un certain temps.

# UpdateMMA.ps1
# This script is to be run per subscription, the customer has to set the az subscription before running this within the terminal scope.
# This script uses parallel processing, modify the $parallelThrottleLimit parameter to either increase or decrease the number of parallel processes
# PS> .\UpdateMMA.ps1 GetInventory
# The above command will generate a csv file with the details of VM's and VMSS that require MMA upgrade. 
# The customer can modify the csv by adding/removing rows if needed
# Update the MMA by running the script again and passing the csv file as parameter as shown below:
# PS> .\UpdateMMA.ps1 Upgrade
# If you don't want to check the inventory, then run the script wiht an additional -no-inventory-check
# PS> .\UpdateMMA.ps1 GetInventory & .\UpdateMMA.ps1 Upgrade


# This version of the script requires Powershell version >= 7 in order to improve performance via ForEach-Object -Parallel
# https://docs.microsoft.com/powershell/scripting/whats-new/migrating-from-windows-powershell-51-to-powershell-7?view=powershell-7.1
if ($PSVersionTable.PSVersion.Major -lt 7) 
{
    Write-Host "This script requires Powershell version 7 or newer to run. Please see https://docs.microsoft.com/powershell/scripting/whats-new/migrating-from-windows-powershell-51-to-powershell-7?view=powershell-7.1."
    exit 1
}

$parallelThrottleLimit = 16
$mmaFixVersion = [version]"10.20.18053.0"

function GetVmsWithMMAInstalled
{
    param(
        $fileName
    )

    $vmList = az vm list --show-details --query "[?powerState=='VM running'].{ResourceGroup:resourceGroup, VmName:name}" | ConvertFrom-Json
    
    if(!$vmList)
    {
        Write-Host "Cannot get the VM list, this script can only detect the running VM's"
        return
    }

    $vmsCount = $vmList.Length
    
    $vmParallelThrottleLimit = $parallelThrottleLimit
    if ($vmsCount -lt $vmParallelThrottleLimit) 
    {
        $vmParallelThrottleLimit = $vmsCount
    }

    if($vmsCount -eq 1)
    {
        $vmGroups += ,($vmList[0])
    }
    else
    {
        # split the vm's into batches to do parallel processing
        for ($i = 0; $i -lt $vmsCount; $i += $vmParallelThrottleLimit) 
        { 
            $vmGroups += , ($vmList[$i..($i + $vmParallelThrottleLimit - 1)]) 
        }
    }

    Write-Host "Detected $vmsCount Vm's running in this subscription."
    $hash = [hashtable]::Synchronized(@{})
    $hash.One = 1

    $vmGroups | Foreach-Object -ThrottleLimit $parallelThrottleLimit -Parallel {
        $len = $using:vmsCount
        $hash = $using:hash
        $_ | ForEach-Object {
            $percent = 100 * $hash.One++ / $len
            Write-Progress -Activity "Getting VM Inventory" -PercentComplete $percent
            $vmName = $_.VmName
            $resourceGroup = $_.ResourceGroup
            $responseJson = az vm run-command invoke --command-id RunPowerShellScript --name $vmName -g $resourceGroup --scripts '@UpgradeMMA.ps1' --parameters "functionName=GetMMAVersion" --output json | ConvertFrom-Json
            if($responseJson)
            {
                $mmaVersion = $responseJson.Value[0].message
                if ($mmaVersion) 
                {
                    $extensionName = az vm extension list -g $resourceGroup --vm-name $vmName --query "[?name == 'MicrosoftMonitoringAgent'].name" | ConvertFrom-Json
                    if ($extensionName) 
                    {
                        $installType = "Extension"
                    }
                    else 
                    {
                        $installType = "Installer"
                    }
                    $csvObj = New-Object -TypeName PSObject -Property @{
                        'Name'           = $vmName
                        'Resource_Group' = $resourceGroup
                        'Resource_Type'  = "VM"
                        'Install_Type'   = $installType
                        'Version'        = $mmaVersion
                        "Instance_Id"    = ""
                    }
                    $csvObj | Export-Csv $using:fileName -Append -Force
                } 
            } 
        }
    }
}

function GetVmssWithMMAInstalled
{
    param(
        $fileName
    )

    # get the vmss list which are successfully provisioned
    $vmssList = az vmss list --query "[?provisioningState=='Succeeded'].{ResourceGroup:resourceGroup, VmssName:name}" | ConvertFrom-Json   

    $vmssCount = $vmssList.Length
    Write-Host "Detected $vmssCount Vmss running in this subscription."
    $hash = [hashtable]::Synchronized(@{})
    $hash.One = 1

    $vmssList | Foreach-Object -ThrottleLimit $parallelThrottleLimit -Parallel {
        $len = $using:vmssCount
        $hash = $using:hash
        $percent = 100 * $hash.One++ / $len
        Write-Progress -Activity "Getting VMSS Inventory" -PercentComplete $percent
        $vmssName = $_.VmssName
        $resourceGroup = $_.ResourceGroup

        # get running vmss instance ids
        $vmssInstanceIds = az vmss list-instances --resource-group $resourceGroup --name $vmssName --expand instanceView --query "[?instanceView.statuses[1].displayStatus=='VM running'].instanceId" | ConvertFrom-Json
        if ($vmssInstanceIds.Length -gt 0) 
        {
            $isMMAExtensionInstalled = az vmss extension list -g $resourceGroup --vmss-name $vmssName --query "[?name == 'MicrosoftMonitoringAgent'].name" | ConvertFrom-Json
            if ($isMMAExtensionInstalled ) 
            {
                # check an instance in vmss, if it needs an MMA upgrade. Since the extension is installed at VMSS level, checking for bad version in 1 instance should be fine.
                $responseJson = az vmss run-command invoke --command-id RunPowerShellScript --name $vmssName -g $resourceGroup --instance-id $vmssInstanceIds[0] --scripts '@UpgradeMMA.ps1' --parameters "functionName=GetMMAVersion" --output json | ConvertFrom-Json
                $mmaVersion = $responseJson.Value[0].message
                if ($mmaVersion) 
                {
                    $csvObj = New-Object -TypeName PSObject -Property @{
                        'Name'           = $vmssName
                        'Resource_Group' = $resourceGroup
                        'Resource_Type'  = "VMSS"
                        'Install_Type'   = "Extension"
                        'Version'        = $mmaVersion
                        "Instance_Id"    = ""
                    }
                    $csvObj | Export-Csv $using:fileName -Append -Force
                }
            }
            else 
            {
                foreach ($instanceId in $vmssInstanceIds) 
                {
                    $responseJson = az vmss run-command invoke --command-id RunPowerShellScript --name $vmssName -g $resourceGroup --instance-id $instanceId --scripts '@UpgradeMMA.ps1' --parameters "functionName=GetMMAVersion" --output json | ConvertFrom-Json
                    $mmaVersion = $responseJson.Value[0].message
                    if ($mmaVersion) 
                    {
                        $csvObj = New-Object -TypeName PSObject -Property @{
                            'Name'           = $vmssName
                            'Resource_Group' = $resourceGroup
                            'Resource_Type'  = "VMSS"
                            'Install_Type'   = "Installer"
                            'Version'        = $mmaVersion
                            "Instance_Id"    = $instanceId
                        }
                        $csvObj | Export-Csv $using:fileName -Append -Force
                    }
                }
            }
        }      
    }
}

function Upgrade
{
    param(
        $fileName = "MMAInventory.csv"
    )
    Import-Csv $fileName | ForEach-Object -ThrottleLimit $parallelThrottleLimit -Parallel {
        $mmaVersion = [version]$_.Version
        if($mmaVersion -lt $using:mmaFixVersion)
        {
            if ($_.Install_Type -eq "Extension") 
            {
                if ($_.Resource_Type -eq "VMSS") 
                {
                    # if the extension is installed with a custom name, provide the name using the flag: --extension-instance-name <extension name>
                    az vmss extension set --name MicrosoftMonitoringAgent --publisher Microsoft.EnterpriseCloud.Monitoring --force-update --vmss-name $_.Name --resource-group $_.Resource_Group --no-wait --output none
                }
                else 
                {
                    # if the extension is installed with a custom name, provide the name using the flag: --extension-instance-name <extension name>
                    az vm extension set --name MicrosoftMonitoringAgent --publisher Microsoft.EnterpriseCloud.Monitoring --force-update --vm-name $_.Name --resource-group $_.Resource_Group --no-wait --output none
                }
            }
            else {
                if ($_.Resource_Type -eq "VMSS") 
                {
                    az vmss run-command invoke --command-id RunPowerShellScript --name $_.Name -g $_.Resource_Group --instance-id $_.Instance_Id --scripts '@UpgradeMMA.ps1' --parameters "functionName=UpgradeMMA" --output none
                }
                else 
                {
                    az vm run-command invoke --command-id RunPowerShellScript --name $_.Name -g $_.Resource_Group --scripts '@UpgradeMMA.ps1' --parameters "functionName=UpgradeMMA" --output none
                }
            }
        }
    }
}

function GetInventory
{
    param(
        $fileName = "MMAInventory.csv"
    )

    # create a new file 
    New-Item -Name $fileName -ItemType File -Force
    GetVmsWithMMAInstalled $fileName
    GetVmssWithMMAInstalled $fileName
}

switch ($args.Count)
{
    0 {
        Write-Host "The arguments provided are incorrect."
        Write-Host "To get the Inventory: Run the script as: PS> .\UpdateMMA.ps1 GetInventory"
        Write-Host "To update MMA from Inventory: Run the script as: PS> .\UpdateMMA.ps1 Upgrade"
        Write-Host "To do the both steps together: PS> .\UpdateMMA.ps1 GetInventory & .\UpdateMMA.ps1 Upgrade"
    }
    1 {
        $funcname = $args[0]
        Invoke-Expression "& $funcname"
    }
    2 {
        $funcname = $args[0]
        $funcargs = $args[1]
        Invoke-Expression "& $funcname $funcargs"
    }
}