Risolvere i problemi relativi all'agente Log Analytics per Windows

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

Strumento di risoluzione dei problemi di Log Analytics

L'agente di Log Analytics per lo strumento di risoluzione dei problemi di Windows è 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.

Usare lo strumento di risoluzione dei problemi

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

  2. Passare alla directory in cui si trova lo strumento:

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

  3. Eseguire lo script principale usando questo comando:

    .\GetAgentInfo.ps1

  4. Selezionare uno scenario di risoluzione dei problemi.

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

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

Installazione

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

Scenari possibili

Lo strumento di risoluzione dei problemi controlla gli scenari seguenti:

  • L'agente non segnala dati o dati heartbeat mancanti.
  • La distribuzione dell'estensione dell'agente non riesce.
  • L'agente si arresta in modo anomalo.
  • L'agente utilizza una CPU o una memoria elevata.
  • Errori di installazione e disinstallazione.
  • I log personalizzati presentano problemi.
  • Il gateway OMS presenta problemi.
  • I contatori delle prestazioni presentano problemi.
  • Non è possibile raccogliere i log dell'agente.

Nota

Eseguire lo strumento di risoluzione dei problemi quando si verifica un problema. La presenza dei log inizialmente aiuterà il team di supporto a risolvere il problema più velocemente.

Origini importanti per la risoluzione dei problemi

Per facilitare la risoluzione dei problemi relativi all'agente di Log Analytics per Windows, l'agente registra gli eventi nel registro eventi di Windows, in particolare in Application and Services\Operations Manager.

Problemi di connettività

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

Verificare che il firewall o il proxy sia configurato per consentire le porte e gli URL seguenti descritti nella tabella seguente. Verificare anche che l'ispezione HTTP non sia abilitata per il traffico Web. Può impedire un canale TLS sicuro tra l'agente e Monitoraggio di Azure.

Risorsa dell'agente Porte Direzione Disabilita ispezione HTTP
*.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.

Esistono diversi modi per verificare 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 degli agenti che non rispondono per verificare rapidamente se l'agente è elencato.

  • Eseguire la query seguente per verificare che l'agente invii un heartbeat all'area di lavoro a cui è configurato per il report. 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 un risultato, verificare prima di tutto che l'agente sia configurato per segnalare all'area di lavoro corretta. Se è configurato correttamente, procedere con il passaggio 3 e cercare nel registro eventi di Windows per identificare se l'agente sta registrando il problema che potrebbe impedire la comunicazione con Monitoraggio di Azure.

  • Un altro metodo per identificare un problema di connettività consiste nell'eseguire lo strumento TestCloud Connessione ivity. Lo strumento viene installato per impostazione predefinita con l'agente nella cartella %SystemRoot%\Programmi\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 essere correlato a una porta o a un URL specifico bloccato.

    Screenshot that shows TestCloudConnection tool execution results.

  • Filtrare il registro eventi di Operations Manager in base alle origini eventi Servizio integrità Moduli, HealthService e Service Connessione or e filtrare in base all'avviso e all'errore a livellodi evento per verificare se sono stati scritti eventi dalla tabella seguente. In caso affermativo, esaminare i passaggi di risoluzione inclusi per ogni evento possibile.

    ID evento Origine Descrizione Risoluzione
    2133 & 2129 Servizio integrità Connessione ion al servizio dall'agente non è riuscito. Questo errore può verificarsi quando l'agente non può comunicare direttamente o tramite un firewall o un server proxy al servizio Monitoraggio di Azure. Verificare le impostazioni proxy dell'agente o che il firewall di rete o il proxy consenta il traffico TCP dal computer al servizio.
    2138 Moduli del servizio integrità Il proxy richiede l'autenticazione. Configurare le impostazioni proxy dell'agente e specificare il nome utente/password necessario 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 proxy dell'agente.
    2127 Moduli del servizio integrità Errore durante l'invio dei dati ricevuti nel codice di errore. Se si verifica periodicamente solo durante il giorno, potrebbe trattarsi di un'anomalia casuale che può essere ignorata. Monitorare per comprendere la frequenza con cui si verifica. Se accade spesso durante tutto il giorno, controllare prima di tutto la configurazione di rete e le impostazioni proxy. Se la descrizione include il codice di errore HTTP 404 ed è la prima volta che l'agente tenta di inviare dati al servizio, includerà un errore 500 con un codice di errore interno 404. Il codice di errore 404 indica che il provisioning dell'area di archiviazione per la nuova area di lavoro è ancora in corso. Al successivo tentativo, i dati verranno scritti correttamente nell'area di lavoro come previsto. Un errore HTTP 403 potrebbe indicare un problema di autorizzazione o credenziali. Altre informazioni sono incluse nell'errore 403 per risolvere il problema.
    4000 Connettore di servizi Risoluzione dei nomi DNS non riuscita. Il computer non è riuscito a risolvere l'indirizzo Internet usato quando ha inviato dati al servizio. Questo problema potrebbe essere rappresentato da impostazioni del sistema di risoluzione DNS nel computer, impostazioni proxy non corrette o un problema DNS temporaneo con il provider. Se si verifica periodicamente, potrebbe essere causato da un problema temporaneo correlato alla rete.
    4001 Connettore di servizi Connessione ion al servizio non è riuscito. Questo errore può verificarsi quando l'agente non può comunicare direttamente o tramite un firewall o un server proxy al servizio Monitoraggio di Azure. Verificare le impostazioni proxy dell'agente o che il firewall di rete o il proxy consenta il traffico TCP dal computer al servizio.
    4002 Connettore di servizi Il servizio ha restituito il codice di stato HTTP 403 in risposta a una query. Rivolgersi all'amministratore del servizio per verificare l'integrità del servizio. La query verrà ritentata in un secondo momento. Questo errore viene scritto durante la fase di registrazione iniziale dell'agente. Verrà visualizzato un URL simile a https:// workspaceID.oms.opinsights.azure.com/AgentService.svc/AgentTopologyRequest>.< Un codice di errore 403 indica "accesso negato" e può essere causato da un ID o 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 è +/- 15 minuti dall'ora corrente, l'onboarding ha esito negativo. Per risolvere il problema, aggiornare la data e/o l'ora del computer Windows.

Problemi di raccolta dati

Dopo l'installazione dell'agente e la segnalazione all'area di lavoro o all'area di lavoro configurata, 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 ciò che è abilitato e destinato al computer. È necessario determinare:

  • Si tratta di un tipo di dati specifico o di 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 computer sono interessati? Si tratta di un singolo computer o di più computer che segnalano all'area di lavoro?
  • Funzionava e si fermò in un determinato momento del giorno, o non è mai stato raccolto?
  • La query di ricerca log usata è sintatticamente corretta?
  • L'agente ha mai ricevuto la configurazione da Monitoraggio di Azure?

Il primo passaggio per la risoluzione dei problemi 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 risultati, è necessario determinare se un tipo di dati specifico non viene raccolto e inoltrato al servizio. Questo problema potrebbe essere causato dall'agente che non riceve la configurazione aggiornata dal servizio o da un altro sintomo che impedisce il funzionamento normale dell'agente. Per risolvere altri problemi, seguire questa procedura.

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

  2. Aprire il registro eventi di Operations Manager e cercare gli IDevento 7023, 7024, 7025, 7028 e 1210 da HealthService di origineeventi. Questi eventi indicano che l'agente riceve correttamente la configurazione da Monitoraggio di Azure e 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 sull'agente.

    Screenshot that shows an Event ID 1210 description.

  3. Attendere alcuni minuti. Se i dati previsti non vengono visualizzati nei risultati o nella visualizzazione delle query, a seconda che i dati siano visualizzati da una soluzione o informazioni dettagliate, nel registro eventi di Operations Manager cercare HealthService e Servizio integrità Modules. Filtrare in base all'avviso a livellodi evento e all'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 al servizio per l'inserimento nell'area di lavoro. L'ID evento 2136 di HealthService di origine viene scritto insieme a questo evento e può indicare che l'agente non è in grado di comunicare con il servizio. I possibili motivi potrebbero essere la configurazione errata delle impostazioni proxy e di autenticazione, dell'interruzione della rete o del firewall di rete o del proxy non consente il traffico TCP dal computer al servizio.
    10102 e 10103 Moduli del servizio integrità Il flusso di lavoro non è riuscito 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 non corretto nelle impostazioni dei dati dell'area di lavoro. Se si tratta di un contatore delle prestazioni specificato dall'utente, verificare che le informazioni specificate seguano il formato corretto ed esistano nei computer di destinazione.
    26002 Moduli del servizio integrità Il flusso di lavoro non è riuscito a risolvere l'origine dati. Questo problema può verificarsi se il registro eventi di Windows specificato non esiste nel computer. Questo errore può essere ignorato in modo sicuro 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 relativi ai certificati aggiunti con gli agenti di monitoraggio Microsoft meno recenti - Modifica che causa un'interruzione

Panoramica delle modifiche ca radice

A partire dal 30 giugno 2023, il back-end di Log Analytics non accetterà più connessioni da MMA che fanno riferimento a un certificato radice obsoleto. Questi MMA sono versioni precedenti alla versione winter 2020 (agente di Log Analytics) e precedenti a SCOM 2019 UR3 (SCOM). Qualsiasi versione, Bundle: 10.20.18053 / Estensione: 1.0.18053.0 o versione successiva non avrà problemi, nonché qualsiasi versione precedente a SCOM 2019 UR3. Qualsiasi agente precedente a quello verrà interrotto e non funzionerà più e non funzionerà più in Log Analytics.

Che cosa sta cambiando esattamente?

Nell'ambito di un'attività di sicurezza continuativa in vari servizi di Azure, Azure Log Analytics passerà ufficialmente dalla radice DELLA CA Baltimore CyberTrust alla radice della CA DigiCert Global G2. Questa modifica influirà sulle comunicazioni TLS con Log Analytics se il nuovo certificato radice ca DigiCert Global G2 non è presente nel sistema operativo o l'applicazione fa riferimento alla VECCHIA CA radice baltimora. Ciò significa che Log Analytics non accetterà più connessioni da MMA che usano questa CA radice precedente dopo il ritiro.

Prodotti della soluzione

È possibile che sia stata ricevuta la notifica di modifica di rilievo anche se non è stato installato personalmente Microsoft Monitoring Agent. Ciò è dovuto al fatto che vari prodotti Di Azure sfruttano Microsoft Monitoring Agent. Se usi uno di questi prodotti, potresti essere interessato quando sfruttano l'agente di Windows Log Analytics. Per questi prodotti con collegamenti riportati di seguito potrebbero essere presenti istruzioni specifiche che richiederanno l'aggiornamento all'agente più recente.

Identificazione e rimidiamento degli agenti di rilievo

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

Per le distribuzioni con più nodi, è stato scritto uno script che rileverà eventuali MMA di rilievo interessati per ogni sottoscrizione e quindi li aggiornerà alla versione più recente. Questi script devono essere eseguiti in sequenza, a partire da UpdateMMA.ps1 e quindi UpgradeMMA.ps1. A seconda del computer, lo script potrebbe richiedere del tempo. Per evitare un timeout è necessario PowerShell 7 o versione successiva.

UpdateMMA.ps1 Questo script passa attraverso le macchine virtuali nelle sottoscrizioni, verifica la presenza di MMA esistenti installati e quindi genera un file CSV di agenti che devono essere aggiornati.

UpgradeMMA.ps1 Questo script userà . File CSV generato in UpdateMMA.ps1 per aggiornare tutti gli MMA di rilievo.

Il completamento di entrambi gli script può richiedere qualche minuto.

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