Condividi tramite


Risolvere i problemi relativi all'agente Log Analytics per Windows

Questo articolo fornisce informazioni utili per la risoluzione degli errori che possono verificarsi con l'agente di Log Analytics per Windows in Monitoraggio di Azure e suggerisce le possibili soluzioni per risolverli.

Strumento di risoluzione dei problemi di Log Analytics

Lo strumento di risoluzione dei problemi dell'agente di Log Analytics per Linux è una raccolta di script di PowerShell progettati per individuare e diagnosticare i problemi relativi all'agente di Log Analytics. Viene incluso automaticamente con l'agente al momento dell'installazione. L'esecuzione dello strumento deve essere il primo passaggio per la diagnosi di un problema.

Utilizzare lo strumento per la risoluzione dei problemi:

  1. Aprire il prompt di PowerShell come amministratore nel computer sul quale è installato l'agente di Log Analytics.

  2. Passare alla directory che contiene lo strumento:

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

  3. Eseguire lo script principale utilizzando comando:

    .\GetAgentInfo.ps1

  4. Selezionare uno scenario di risoluzione dei problemi.

  5. Seguire le istruzioni sulla console. Tenere presente che i passaggi dei log di analisi richiedono l'intervento manuale per arrestare la raccolta dei log. In base alla riproducibilità del problema, attendere l'intervallo di tempo, quindi selezionare "s" per arrestare la raccolta dei log e procedere con il passaggio successivo.

    Il percorso del file dei risultati viene registrato al completamento e si apre una nuova finestra di esplorazione evidenziata.

Installazione

Lo strumento di risoluzione dei problemi è automaticamente incluso in fase di installazione dell'agente di Log Analytics build 10.20.18053.0 e versioni successive.

Scenari possibili

Lo strumento di risoluzione dei problemi verifica gli scenari seguenti:

  • L'agente non segnala dati o i dati heartbeat non sono presenti.
  • La distribuzione dell'estensione dell'agente non viene eseguita.
  • L'agente si arresta in modo anomalo.
  • L'agente ha un intenso di CPU o di memoria.
  • Si verificano errori in fase di installazione e di disinstallazione.
  • I log personalizzati presentano dei problemi.
  • Il gateway OMS presenta dei problemi.
  • I contatori delle prestazioni presentano dei problemi.
  • Non è possibile raccogliere i log dell’agente.

Nota

Quando si verifica un problema, eseguire lo strumento di risoluzione dei problemi. La presenza dei log dalla fase iniziale aiuterà il team di supporto a risolvere il problema più velocemente.

Fonti importanti per la risoluzione dei problemi

Per agevolare la risoluzione dei problemi relativi all'agente di Log Analytics per Windows, l'agente registra gli eventi nel registro eventi di Windows e nello specifico in Applicazioni e servizi\Operations Manager.

Problemi di connettività

Se l'agente comunica tramite un server proxy o un firewall possono essere presenti restrizioni che impediscono la comunicazione tra il computer di origine e il servizio Monitoraggio di Azure. Se la comunicazione è bloccata a causa di una configurazione errata, la registrazione in un'area di lavoro potrebbe non riuscire durante il tentativo di installare l'agente o di configurare la post-configurazione dell'agente affinché faccia riferimento a un'altra area di lavoro. La comunicazione dell'agente potrebbe non riuscire, dopo la registrazione. Questa sezione tratta i metodi per risolvere questo tipo di problema con l'agente di Windows.

Verificare che il firewall o il proxy sia configurato per consentire la comunicazione sulle porte e tra gli URL seguenti, descritti in questa tabella. Verificare anche che l'ispezione dell'HTTP non sia abilitata per il traffico web. Può impedire la comunicazione su un canale TLS sicuro tra l'agente e Monitoraggio di Azure.

Risorsa dell'agente Porte Direzione Ignorare il controllo HTTPS
*.ods.opinsights.azure.com Porta 443 In uscita
*.oms.opinsights.azure.com Porta 443 In uscita
*.blob.core.windows.net Porta 443 In uscita
*.agentsvc.azure-automation.net Porta 443 In uscita

Per informazioni sul firewall necessarie per Azure per enti pubblici, vedere Gestione di Azure per enti pubblici. Se si prevede di usare il ruolo di lavoro ibrido per runbook di Automazione di Azure per connettersi e registrarsi al servizio di automazione per usare i runbook o le soluzioni di gestione nell'ambiente in uso, è necessario avere accesso al numero di porta e agli URL descritti in Configurare la rete per il ruolo di lavoro ibrido per runbook.

È possibile verificare in diversi modi se l'agente comunica correttamente con Monitoraggio di Azure:

  • Abilitare la valutazione dell'integrità dell'agente di Azure Log Analytics nell'area di lavoro. Nel dashboard Integrità agente, visualizzare la colonna Conteggio di agenti che non rispondono per verificare rapidamente se l'agente è presente nell'elenco.

  • Eseguire la seguente query per verificare che l'agente invii un segnale di heartbeat all'area di lavoro alla quale deve fare riferimento. Sostituire <ComputerName>con il nome effettivo del computer.

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

    Se il computer comunica correttamente con il servizio la query deve restituire un risultato. Se la query non ha restituito risultati, verificare innanzitutto che l'agente sia configurato per fare riferimento all'area di lavoro corretta. Se è configurato correttamente, procedere con il passaggio 3 e svolgere ricerche nel registro eventi di Windows per capire se l'agente sta registrando il problema che potrebbe impedire la comunicazione con Monitoraggio di Azure.

  • Un altro metodo per individuare un problema di connettività consiste nell'eseguire lo strumento TestCloudConnectivity. Questo strumento viene installato per impostazione predefinita con l'agente nella cartella %SystemRoot%\Program Files\Microsoft Monitoring Agent\Agent. Da un prompt dei comandi con privilegi elevati, passare alla cartella ed eseguire lo strumento. Lo strumento restituisce i risultati ed evidenzia il momento in cui il test non è riuscito. Ad esempio, potrebbe esserci una correlazione con una porta o un URL specifico bloccato.

    Screenshot dei risultati dell'esecuzione dello strumento TestCloudConnection.

  • Filtrare il registro eventi di Operations Manager per Origini eventi Moduli del servizio integrità, Servizio integrità e Connettore di servizi, e filtrare per Livello evento Avviso e Errore per verificare che ci siano eventi scritti dalla tabella seguente. Se ce ne sono, esaminare i passaggi di risoluzione inclusi per ogni possibile evento.

    ID evento Origine Descrizione Risoluzione
    2133 e 2129 Servizio integrità Connessione con il servizio dall'agente non riuscita. Questo errore può verificarsi quando l'agente non riesce a comunicare direttamente o tramite un firewall o un server proxy con il servizio Monitoraggio di Azure. Verificare le impostazioni del proxy dell'agente o che il firewall di rete o il proxy consentano il traffico TCP dal computer verso il servizio.
    2138 Moduli del servizio integrità Il proxy richiede l'autenticazione. Configurare le impostazioni del proxy dell'agente e specificare il nome utente/password per l'autenticazione con il server proxy.
    2129 Moduli del servizio integrità Connessione non riuscita. Negoziazione TLS non riuscita. Controllare le impostazioni TCP/IP della scheda di rete e le impostazioni del proxy dell'agente.
    2127 Moduli del servizio integrità Errore durante l'invio dei dati: ricevuto codice errore. Se si verifica periodicamente solo durante il giorno; potrebbe trattarsi di un'anomalia casuale che si può ignorare. Monitorare per comprendere con quale frequenza si verifica. Se si verifica spesso durante tutto il giorno, controllare innanzitutto la configurazione di rete e le impostazioni del proxy. Se la descrizione include il codice di errore HTTP 404 ed è la prima volta che l'agente tenta di inviare dati al servizio, sarà presente un errore 500 con un codice di errore interno 404. Il codice di errore 404 significa "non trovato", il che indica che il provisioning dell'area di archiviazione per la nuova area di lavoro è ancora in corso. Al tentativo successivo i dati verranno scritti correttamente nell'area di lavoro come previsto. Un errore HTTP 403 può indicare un problema relativo all'autorizzazione o alle credenziali. L'errore 403 contiene ulteriori informazioni per risolvere il problema.
    4000 Connettore servizio Risoluzione dei nomi DNS non riuscita. Il computer non è riuscito a risolvere l'indirizzo Internet utilizzato durante l'invio dei dati al servizio. Il problema potrebbe essere causato da impostazioni del sistema di risoluzione DNS nel computer, impostazioni del proxy non corrette o un problema temporaneo del DNS con il provider. Se si verifica periodicamente, può essere causato da un problema temporaneo correlato alla rete.
    4001 Connettore servizio Connessione al servizio non riuscita. Questo errore può verificarsi quando l'agente non riesce a comunicare direttamente o tramite un firewall o un server proxy con il servizio Monitoraggio di Azure. Verificare le impostazioni del proxy dell'agente o che il firewall di rete o il proxy consentano il traffico TCP dal computer verso il servizio.
    4002 Connettore servizio Il servizio ha restituito il codice di stato HTTP 403 in risposta a una query. Contattare l'amministratore del servizio per verificare l'integrità del servizio. La query verrà riprovata in un secondo momento. Questo errore viene scritto nella fase di registrazione iniziale dell'agente. Viene visualizzato un URL avente questo aspetto https://<workspaceID>.oms.opinsights.azure.com/AgentService.svc/AgentTopologyRequest. Un codice di errore 403 significa "non consentito" e può essere causato da un ID o da una chiave dell'area di lavoro digitati in modo errato. Anche la data e l'ora potrebbero non essere corrette, nel computer. Se l'ora è sfasata di ±15 minuti rispetto all'ora corrente, l'onboarding non riesce. Per risolvere questo problema, aggiornare la data e/o l'ora del computer Windows.

Problemi nella raccolta dati

Dopo che l'agente è installato e fa riferimento all'area di lavoro o alle aree di lavoro configurata/e, l'agente potrebbe interrompere la ricezione della configurazione e la raccolta o l'inoltro di prestazioni, log o altri dati al servizio, a seconda di quanto è abilitato e destinato al computer. È necessario determinare:

  • Riguarda di un tipo di dati specifico o tutti i dati non disponibili nell'area di lavoro?
  • Il tipo di dati è specificato da una soluzione o è specificato come parte della configurazione della raccolta dati dell'area di lavoro?
  • Quanti sono i computer interessati? Riguarda un singolo computer o più computer che fanno riferimento all'area di lavoro?
  • Funzionava e c'è stata un'interruzione in un determinato momento della giornata oppure la raccolta non è mai avvenuta?
  • La sintassi della query di ricerca log usata è corretta?
  • L'agente ha ricevuto la configurazione da Monitoraggio di Azure?

Per la risoluzione dei problemi, il primo passaggio consiste nel determinare se il computer invia un evento heartbeat.

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

Se la query restituisce dei risultati è necessario determinare se un tipo di dati specifico non viene raccolto e inoltrato al servizio. Il problema potrebbe essere causato dall'agente che non riceve la configurazione aggiornata dal servizio o da un altro sintomo che impedisce il normale funzionamento dell'agente. Per proseguire nella risoluzione del problema, seguire questa procedura.

  1. Aprire un prompt dei comandi con privilegi elevati sul computer e riavviare il servizio agente immettendo net stop healthservice && net start healthservice.

  2. Aprire il registro eventi di Operations Manager e cercare fli ID eventi 7023, 7024, 7025, 7028, e 1210 in Origine evento Servizio integrità. Questi eventi indicano che l'agente riceve correttamente la configurazione da Monitoraggio di Azure e che monitora attivamente il computer. La descrizione dell'evento per l'ID evento 1210 specifica anche nell'ultima riga tutte le soluzioni e le informazioni dettagliate incluse nell'ambito del monitoraggio dell'agente.

    Screenshot con una descrizione dell'ID evento 1210.

  3. Attendere qualche minuto. Se non vengono visualizzati i dati previsti nei risultati o nella visualizzazione delle query, a seconda che si visualizzino i dati da una soluzione o da informazioni dettagliate, nel registro eventi di Operations Manager cercare per Origini eventi i moduli HealthService e Health Service. Filtrare per Livello evento Avviso ed Errore per verificare se sono stati scritti eventi dalla tabella seguente.

    ID evento Origine Descrizione Risoluzione
    8000 Servizio integrità Questo evento specifica se un flusso di lavoro correlato a prestazioni, eventi o altri tipi di dati raccolti non è in grado di inoltrare i dati al servizio per l'inserimento nell'area di lavoro. L'ID evento 2136 per HealthService dell'origine viene scritto insieme a questo evento e può indicare che l'agente non è in grado di comunicare con il servizio. I motivi potrebbero essere la configurazione errata delle impostazioni del proxy e dell'autenticazione, un malfunzionamento della rete o del firewall di rete oppure il proxy non consente il traffico TCP dal computer al servizio.
    10102 e 10103 Moduli del servizio integrità Il flusso di lavoro non ha potuto a risolvere l'origine dati. Questo problema può verificarsi se il contatore delle prestazioni o l'istanza specificata non esiste nel computer o è definito in modo errato nelle impostazioni dei dati dell'area di lavoro. Se si tratta di un contatore delle prestazioni specificato dall'utente, verificare che le informazioni specificate siano nel formato corretto ed esistano nei computer di destinazione.
    26002 Moduli del servizio integrità Il flusso di lavoro non ha potuto a risolvere l'origine dati. Questo problema può verificarsi se il registro eventi di Windows specificato non esiste nel computer. Questo errore si ignorare senza rischi se il computer non prevede la registrazione del registro eventi. In caso contrario, se si tratta di un registro eventi specificato dall'utente, verificare che le informazioni specificate siano corrette.

Problemi riguardanti i certificati aggiunti con gli agenti di monitoraggio Microsoft meno recenti - Modifica che causa un'interruzione

Panoramica delle modifiche all'autorità di certificazione radice

Dal 30 giugno 2023 il back-end di Log Analytics non accetta più connessioni da MMA che fanno riferimento a un certificato radice obsoleto. Questi MMA sono versioni precedenti alla Winter 2020 (agente di Log Analytics) e anteriori a SCOM 2019 UR3 (SCOM). Qualsiasi versione, bundle: 10.20.18053 / estensione: 1.0.18053.0 o versione successiva non avrà problemi; lo stesso vale per qualsiasi versione precedente alla SCOM 2019 UR3. Qualsiasi agente anteriore a quelli citati si interromperà e non potrà più funzionare ne caricare in Log Analytics.

Cosa sta cambiando esattamente?

Nell'ambito di un'attività di sicurezza continua in vari servizi di Azure, Azure Log Analytics passerà ufficialmente da Baltimore CyberTrust CA Root a DigiCert Global G2 CA Root. Questa modifica influirà sulle comunicazioni TLS con Log Analytics se il nuovo certificato radice ca DigiCert Global G2 non è presente nel sistema operativo o se l'applicazione fa riferimento all'autorità di certificazione radice Baltimore. Questo significa che Log Analytics non accetterà più connessioni da MMA che usano questa vecchia autorità di certificazione radice dopo il ritiro.

Prodotti della soluzione

È possibile che si sia ricevuta la notifica di modifica di rilievo anche se non si è installato personalmente Microsoft Monitoring Agent. Questo è dovuto al fatto che vari prodotti Di Azure utilizzano Microsoft Monitoring Agent. Se si usa uno di questi prodotti si potrebbe essere interessati dall'evento durante l'utilizzo dell'agente di Windows Log Analytics. Per i prodotti con i link riportati di seguito potrebbero essere disponibili istruzioni specifiche che richiederanno l'aggiornamento all'agente più recente.

Individuazione e risoluzioni degli agenti che causano interruzioni

Per le distribuzioni con un numero limitato di agenti è consigliabile aggiornare l'agente per nodo seguendo queste istruzioni di gestione.

Per le distribuzioni con più nodi abbiamo preparato scritto uno script che rileverà eventuali MMA interessati che causano interruzioni per ogni sottoscrizione, quindi li aggiornerà alla versione più recente. Questi script devono essere eseguiti in sequenza, iniziando da UpdateMMA.ps1, quindi UpgradeMMA.ps1. A seconda del computer lo script potrebbe richiedere un certo tempo. Per evitare un timeout è necessario usare PowerShell 7 o una versione successiva.

UpdateMMA.ps1 Questo script viene eseguito nelle macchine virtuali delle sottoscrizioni, verifica la presenza di MMA esistenti installati, quindi genera un file .csv di agenti che devono essere aggiornati.

UpgradeMMA.ps1 Questo script userà il file .CSV generato in UpdateMMA.ps1 per aggiornare tutti gli MMA che causano interruzioni.

Il completamento di entrambi gli script può richiedere alcuni minuti.

# 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"
    }
}