Aracılığıyla paylaş


Windows için Log Analytics aracısıyla ilgili sorunları giderme

Bu makale, Azure İzleyici'de Windows için Log Analytics aracısında karşılaşabileceğiniz hataları giderme konusunda yardım sağlar ve bunları çözmek için olası çözümler önerir.

Log Analytics Sorun Giderme Aracı

Windows için Log Analytics aracısı Sorun Giderme Aracı, Log Analytics aracısıyla ilgili sorunları bulmaya ve tanılamaya yardımcı olmak için tasarlanmış bir PowerShell betikleri koleksiyonudur. Yüklemeden sonra aracıya otomatik olarak eklenir. Aracı çalıştırmak, bir sorunu tanılamanın ilk adımı olmalıdır.

Sorun Giderme Aracı'nı kullanma

  1. Log Analytics aracısının yüklü olduğu makinede Yönetici olarak PowerShell istemini açın.

  2. Araç dosyasının yer aldığı dizine gidin.

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

  3. Şu komutu kullanarak ana betik dosyasını yürütün:

    .\GetAgentInfo.ps1

  4. Bir sorun giderme senaryosu seçin.

  5. Konsoldaki yönergeleri izleyin. İzleme günlükleri adımlarının günlük toplamayı durdurmak için el ile müdahale gerektirdiğini unutmayın. Sorunun yeniden üretilebilirliğine bağlı olarak, belirtilen süreyi bekleyin ve günlük toplamayı durdurmak için "s" harfini seçin ve sonraki adıma geçin.

    Sonuç dosyasının konumu tamamlandıktan sonra günlüğe kaydedilir ve dosyayı vurgulayan yeni bir gezgin penceresi açılır.

Yükleme

Sorun Giderme Aracı, Log Analytics Aracısı sürüm 10.20.18053.0 ve sonrasında otomatik olarak eklenir.

Kapsanan senaryolar

Sorun Giderme Aracı aşağıdaki senaryoları denetler:

  • Aracı veri bildirmiyor veya kalp atışı verileri eksik.
  • Aracı uzantısı dağıtımı başarısız oluyor.
  • Aracı çöküyor.
  • Aracı yüksek bir CPU veya bellek tüketiyor.
  • Yükleme ve kaldırma işlemlerinde karşılaşılan hatalar.
  • Özel günlüklerde sorunlar var.
  • OMS Ağ Geçidi'nin sorunları var.
  • Performans sayaçlarında sorunlar vardır.
  • Aracı günlükleri toplanamıyor.

Not

Bir sorunla karşılaştığınızda Sorun Giderme Aracı'nı çalıştırın. Günlüklerin başlangıçta olması, destek ekibimizin sorununuzu daha hızlı gidermesine yardımcı olur.

Önemli sorun giderme kaynakları

Windows için Log Analytics aracısına ilişkin sorunları gidermeye yardımcı olmak üzere, olayları Windows Olay Günlüğü'nde, özellikle Application and Services\Operations Manager altında günlüğe kaydeder.

Bağlantı sorunları

Aracı bir ara sunucu veya güvenlik duvarı üzerinden iletişim kuruyorsa, kaynak bilgisayardan ve Azure İzleyici hizmetinden iletişimi engelleyen kısıtlamalar söz konusu olabilir. Yanlış yapılandırma nedeniyle iletişim engellenirse, aracıyı yüklemeye veya kurulum sonrasında aracıyı başka bir çalışma alanına rapor vermek üzere yapılandırmaya çalışırken çalışma alanına kayıt başarısız olabilir. Başarılı bir kayıttan sonra ajan iletişimi başarısız olabilir. Bu bölümde, Windows aracısıyla ilgili bu tür sorunları giderme yöntemleri açıklanmaktadır.

Güvenlik duvarının veya ara sunucusunun aşağıdaki tabloda açıklanan aşağıdaki bağlantı noktalarına ve URL'lere izin verecek şekilde yapılandırılıp yapılandırılmadığını bir kez daha denetleyin. Ayrıca web trafiği için HTTP incelemesinin etkinleştirilmediğini onaylayın. Aracı ile Azure İzleyici arasında güvenli bir TLS kanalını engelleyebilir.

Aracı kaynağı Bağlantı noktaları Yön HTTPS denetlemesini atla
*.ods.opinsights.azure.com Bağlantı Noktası 443 Giden Evet
*.oms.opinsights.azure.com Bağlantı Noktası 443 Giden Evet
*.blob.core.windows.net Bağlantı Noktası 443 Giden Evet
*.agentsvc.azure-automation.net Bağlantı Noktası 443 Giden Evet

Azure Kamu için gereken güvenlik duvarı bilgileri için bkz. Azure Kamu yönetimi. Ortamınızda runbook'ları veya yönetim çözümlerini kullanmak üzere Otomasyon hizmetine bağlanmak ve bu hizmete kaydolmak için Azure Otomasyonu Karma Runbook Çalışanı'nı kullanmayı planlıyorsanız, bağlantı noktası numarasına ve Karma Runbook Çalışanı için ağınızı yapılandırma başlığında açıklanan URL'lere erişimi olmalıdır.

Aracın Azure Monitor ile başarılı bir şekilde iletişim kurduğunu doğrulamanın birkaç yolu vardır.

  • Çalışma alanında Azure Log Analytics Aracısı Sistem Durumu değerlendirmesini etkinleştirin. Aracının listelenip listelenmediğini hızla görmek için, Aracı Sağlığı panosunda yanıt vermeyen ajanların sayısı sütununa bakın.

  • Aracın raporlamak üzere yapılandırıldığı çalışma alanına kalp atışı gönderdiğini onaylamak için aşağıdaki sorguyu çalıştırın. <ComputerName> değerini makinenin gerçek adıyla değiştirin.

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

    Bilgisayar hizmetle başarıyla iletişim kuruyorsa, sorgu bir sonuç döndürmelidir. Sorgu bir sonuç döndürmediyse, önce aracının doğru çalışma alanına rapor vermek üzere yapılandırıldığını doğrulayın. Doğru yapılandırılmışsa, 3. adıma geçin ve aracının Azure İzleyici ile iletişim kurmasını engelleyebilecek sorunu günlüğe kaydedip kaydetmediğini belirlemek için Windows Olay Günlüğü'nü arayın.

  • Bağlantı sorununu tanımlamanın bir diğer yöntemi de TestCloudConnectivity aracını çalıştırmaktır. Araç, varsayılan olarak %SystemRoot%\Program Files\Microsoft Monitoring Agent\Agent klasöründeki aracı ile birlikte yüklenir. Yükseltilmiş bir komut isteminden klasöre gidin ve aracı çalıştırın. Araç sonuçları döndürür ve testin başarısız olduğu noktayı vurgular. Örneğin, engellenen belirli bir bağlantı noktası veya URL ile ilgili olabilir.

    TestCloudConnection aracı yürütme sonuçlarını gösteren ekran görüntüsü.

  • Operations Manager olay günlüğünü Olay kaynaklarına Health Service Modules, HealthService, ve Hizmet Bağlayıcısı göre filtreleyin ve olayları aşağıdaki tablodan yazıp yazmadığını onaylamak için Olay Düzeyine Uyarı ve Hata göre filtreleyin. Varsa, her olası olay için dahil edilen çözüm adımlarını gözden geçirin.

    Olay Kodu Kaynak Açıklama Çözüm
    2133 & 2129 Sağlık Hizmeti Aracıdan hizmete bağlantı gerçekleştirilemedi. Bu hata, aracının Azure İzleyici hizmetine doğrudan veya bir güvenlik duvarı veya ara sunucu üzerinden iletişim kuramadığında oluşabilir. Aracı proxy ayarlarını doğrulayın veya ağ güvenlik duvarının veya ara sunucunun bilgisayardan hizmete TCP trafiğine izin verdiğinden emin olun.
    2138 Sağlık Hizmeti Modülleri Ara sunucu kimlik doğrulaması gerektirir. Aracı proxy ayarlarını yapılandırın ve ara sunucuyla kimlik doğrulaması yapmak için gereken kullanıcı adını/parolayı belirtin.
    2129 Sağlık Hizmeti Modülleri Bağlantı başarısız oldu. TLS anlaşması başarısız oldu. Ağ bağdaştırıcınızın TCP/IP ayarlarını ve aracı proxy ayarlarını denetleyin.
    2127 Sağlık Hizmeti Modülleri Veri gönderilirken hata oluştu, alınan hata kodu. Gün içinde zaman zaman gerçekleşiyorsa, göz ardı edilebilir rastgele bir anomali olabilir. Ne sıklıkta gerçekleştiğini anlamak için izleyin. Gün boyunca sık sık oluyorsa, önce ağ yapılandırmanızı ve ara sunucu ayarlarınızı denetleyin. Açıklama HTTP hata kodu 404'ü içeriyorsa ve bu, ajanın hizmete veri gönderme girişimindeki ilk denemesi ise, iç 404 hata koduyla birlikte bir 500 hatası içerecektir. 404 hata kodu, yeni çalışma alanı için depolama alanının hala sağlandığını gösteren "bulunamadı" anlamına gelir. Bir sonraki yeniden denemede veriler beklendiği gibi çalışma alanına başarıyla yazılacaktır. HTTP hatası 403 bir izin veya kimlik bilgileri sorununu gösterebilir. Sorunun giderilmesine yardımcı olmak için 403 hatasına daha fazla bilgi eklenmiştir.
    4000 Hizmet Bağlayıcısı DNS ad çözümlemesi başarısız oldu. Makine hizmete veri gönderirken kullanılan internet adresini çözümleyemedi. Bu sorun makinenizdeki DNS çözümleyici ayarları, yanlış ara sunucu ayarları veya sağlayıcınızla ilgili geçici bir DNS sorunu olabilir. Düzenli aralıklarla gerçekleşirse, bunun nedeni ağla ilgili geçici bir sorun olabilir.
    4001 Hizmet Bağlayıcısı Hizmete bağlantı başarısız oldu. Bu hata, aracının Azure İzleyici hizmetine doğrudan veya bir güvenlik duvarı veya ara sunucu üzerinden iletişim kuramadığında oluşabilir. Aracı proxy ayarlarını doğrulayın veya ağ güvenlik duvarının veya ara sunucunun bilgisayardan hizmete TCP trafiğine izin verdiğinden emin olun.
    4002 Hizmet Bağlayıcısı Hizmet, sorguya yanıt olarak 403 HTTP durum kodunu döndürdü. Hizmetin sistem durumu için hizmet yöneticisine başvurun. Sorgu daha sonra yeniden denenecek. Bu hata, ajanın ilk kayıt aşaması sırasında yazılır. Benzer bir URL görürsünüz: https://<workspaceID>.oms.opinsights.azure.com/AgentService.svc/AgentTopologyRequest. 403 hata kodu "yasak" anlamına gelir ve yanlış yazılmış çalışma alanı kimliği veya anahtarı nedeniyle oluşabilir. Tarih ve saat bilgisayarda da yanlış olabilir. Süre geçerli saatten +/- 15 dakika saparsa başlangıç başarısız olur. Bu sorunu düzeltmek için Windows bilgisayarınızın tarih ve/veya saatini güncelleştirin.

Veri toplama sorunları

Aracı yüklendikten ve yapılandırılan çalışma alanına veya çalışma alanlarına rapor vermeye başladıktan sonra, bilgisayara yönelik etkinleştirilmiş ayarlara bağlı olarak, yapılandırma almayı ve hizmete performans, günlük ve diğer verileri toplamayı veya iletmeyi durdurabilir. Aşağıdakileri belirlemeniz gerekir:

  • Belirli bir veri türü mü yoksa çalışma alanında kullanılamayan tüm veriler mi?
  • Veri türü bir çözüm tarafından mı yoksa çalışma alanı veri toplama yapılandırmasının bir parçası olarak mı belirtildi?
  • Kaç bilgisayar etkileniyor? Çalışma alanına rapor eden tek bir bilgisayar mı yoksa birden çok bilgisayar mı?
  • Çalışıyor muydu ve günün belirli bir saatinde mi durdu, yoksa hiç mi toplanmadı?
  • Kullandığınız günlük arama sorgusu sözdizimsel olarak doğru mu?
  • Aracı yapılandırmasını Azure Monitor'dan hiç aldı mı?

Sorun gidermenin ilk adımı, bilgisayarın kalp atışı olayı gönderip göndermediğini belirlemektir.

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

Sorgu sonuçları döndürürse, belirli bir veri türünün toplanıp hizmete iletilmediğini belirlemeniz gerekir. Bu sorun, aracının hizmetten güncelleştirilmiş yapılandırmayı almamasından veya aracının normal çalışmasını engelleyen başka bir belirtiden kaynaklanabilir. Daha fazla sorun gidermek için aşağıdaki adımları gerçekleştirin.

  1. Bilgisayarda yükseltilmiş bir komut istemi açın ve net stop healthservice && net start healthservice girerek ajan hizmetini yeniden başlatın.

  2. Operations Manager olay günlüğünü açın ve Olay kaynağıHealthService'ten 7023, 7024, 7025, 7028 ve 1210 olay kimliklerini arayın. Bu olaylar aracının Azure İzleyici'den yapılandırmayı başarıyla aldığını ve bilgisayarı etkin bir şekilde izlediğini gösterir. 1210 numaralı etkinlik kimliği için etkinlik açıklaması, aracın izleme kapsamına dahil edilen tüm çözümler ve içgörüler son satırda belirtilecektir.

    Olay Kimliği 1210 açıklamasını gösteren ekran görüntüsü.

  3. Birkaç dakika bekleyin. Sorgu sonuçlarında veya görselleştirmede beklenen verileri görmüyorsanız, verileri çözümden mi yoksa İçgörüden mi görüntülediğinize bağlı olarak Operations Manager olay günlüğünden Olay kaynaklarını ve HealthService ile Sağlık Hizmeti Modülleri arayın. Olay Düzeyi Uyarı ve Hata ile filtreleyerek aşağıdaki tablodan olaylar yazıp yazmadığını onaylayın.

    Olay Kodu Kaynak Açıklama Çözüm
    8.000 Sağlık Hizmeti Bu olay, performans, olay veya toplanan diğer veri türüyle ilgili bir iş akışının çalışma alanına alınması amacıyla hizmete yönlendirilememesi durumunu belirtir. HealthService kaynağından Olay Kimliği 2136 bu olayla birlikte yazılır ve aracının hizmetle iletişim kuramadığını gösterebilir. Olası nedenler ara sunucu ve kimlik doğrulama ayarlarının yanlış yapılandırılması, ağ kesintisi veya ağ güvenlik duvarı ya da ara sunucusunun bilgisayardan hizmete TCP trafiğine izin vermemesi olabilir.
    10102 ve 10103 Sağlık Hizmeti Modülleri İş akışı veri kaynağını çözümleyemedi. Belirtilen performans sayacı veya örneği bilgisayarda yoksa veya çalışma alanı veri ayarlarında yanlış tanımlanmışsa bu sorun oluşabilir. Bu kullanıcı tarafından belirtilen bir performans sayacıysa, belirtilen bilgilerin doğru biçimde olduğunu ve hedef bilgisayarlarda mevcut olduğunu doğrulayın.
    26002 Sağlık Hizmeti Modülleri İş akışı veri kaynağını çözümleyemedi. Belirtilen Windows olay günlüğü bilgisayarda yoksa bu sorun oluşabilir. Bilgisayarda bu olay günlüğünün kayıtlı olması beklenmiyorsa bu hata güvenle yoksayılabilir. Aksi takdirde, bu kullanıcı tarafından belirtilen bir olay günlüğüyse, belirtilen bilgilerin doğru olduğunu doğrulayın.

Eski Microsoft izleme ajanlarında sabit sertifika sorunları - önemli değişiklik.

Kök CA Değişikliğine Genel Bakış

30 Haziran 2023 itibarıyla, Log Analytics arka plan sistemi artık eski bir kök sertifikaya başvuran MMA bağlantılarını kabul etmeyecektir. Bu MMA'lar, Log Analytics Aracısı'nın Kış 2020 sürümünden ve SCOM 2019 UR3'ten önceki eski sürümlerdir. Herhangi bir sürüm, Paket: 10.20.18053 / Eklenti: 1.0.18053.0 veya üzeri sürümlerde ve SCOM 2019 UR3 üzerindeki herhangi bir sürümde sorun yaşanmaz. Bundan eski tüm aracılar bozulacak, artık çalışamayacak ve Log Analytics'e yükleme yapamayacak.

Tam olarak ne değişiyor?

Çeşitli Azure hizmetlerinde devam eden bir güvenlik çalışmasının parçası olarak Azure Log Analytics resmi olarak Baltimore CyberTrust CA Kökünden DigiCert Global G2 CA Köküne geçiş yapacaktır. Yeni DigiCert Global G2 CA Kök sertifikası işletim sisteminde eksikse veya uygulama eski Baltimore Kök CA'ya başvuruyorsa, bu değişiklik Log Analytics ile TLS iletişimlerini etkiler. Bu da Log Analytics'in kullanımdan kaldırıldıktan sonra MMA'dan bu eski kök CA'nın kullanıldığı bağlantıları kabul etmeyeceği anlamına gelir.

Çözüm ürünleri

Microsoft Monitoring Agent'ı kişisel olarak yüklememiş olsanız bile hataya neden olan değişiklik bildirimini almış olabilirsiniz. Bunun nedeni, çeşitli Azure ürünlerinin Microsoft Monitoring Agent'a sahip olmasıdır. Bu ürünlerden birini kullanıyorsanız Windows Log Analytics Aracısı'nı kullandıklarından etkilenebilirsiniz. Aşağıdaki bağlantıları olan ürünler için, en son aracıya yükseltmenizi gerektirecek belirli yönergeler olabilir.

Arıza Yapan Etkenleri Belirleme ve Düzeltme

Sınırlı sayıda aracı içeren dağıtımlar için, bu yönetim yönergeleri aracılığıyla düğüm başına aracınızı yükseltmenizi kesinlikle öneririz.

Her bir abonelik için bozulmaya neden olan MMAları algılayacak ve ardından bunları en son sürüme yükseltecek bir komut dosyası yazdık. Bu komut dosyası, birden çok düğüme sahip dağıtımlar için kullanılacaktır. Bu betiklerin UpdateMMA.ps1 ve upgradeMMA.ps1 ile başlayarak sırayla çalıştırılması gerekir. Makineye bağlı olarak komut dosyası biraz zaman alabilir. Zaman aşımından kaçınmak için PowerShell 7 veya üzeri gereklidir.

UpdateMMA.ps1 Bu betik, aboneliklerinizdeki sanal makinelerden geçer, yüklü mevcut MMAları denetler ve yükseltilmesi gereken aracılardan oluşan bir .csv dosyası oluşturur.

UpgradeMMA.ps1 Bu betik, UpdateMMA.ps1'de oluşturulan .CSV dosyasını kullanarak tüm sorun çıkaran MMA'ları yükseltecek.

Her iki betiğin de tamamlanması biraz zaman alabilir.

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