Memecahkan masalah dengan agen Analitik Log untuk Windows

Artikel ini menyediakan bantuan dalam memecahkan masalah kesalahan yang mungkin Anda alami dengan agen Analitik Log untuk Windows di Azure Monitor dan menyarankan kemungkinan solusi untuk mengatasinya.

Alat Pemecahan Masalah Log Analytics

Agen Analitik Log untuk Alat Pemecahan Masalah Windows adalah kumpulan skrip PowerShell yang dirancang untuk membantu menemukan dan mendiagnosis masalah dengan agen Analitik Log. Hal ini secara otomatis disertakan dengan agen saat penginstalan. Menjalankan alat harus menjadi langkah pertama dalam mendiagnosis masalah.

Menggunakan Alat Pemecahan Masalah

  1. Buka perintah PowerShell sebagai administrator di komputer tempat agen Analitik Log diinstal.

  2. Buka direktori tempat alat berada:

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

  3. Jalankan skrip utama dengan menggunakan perintah ini:

    .\GetAgentInfo.ps1

  4. Memilih skenario pemecahan masalah.

  5. Mengikuti petunjuk di konsol. Perhatikan bahwa langkah-langkah log jejak memerlukan intervensi manual untuk menghentikan pengumpulan log. Berdasarkan reproduksi masalah, tunggu durasi waktu dan pilih "s" untuk menghentikan pengumpulan log dan lanjutkan ke langkah berikutnya.

    Lokasi file hasil dicatat setelah selesai dan jendela penjelajah baru yang menyorotinya dibuka.

Penginstalan

Alat Pemecahan Masalah secara otomatis disertakan setelah penginstalan build Agen Analitik Log 10.20.18053.0 dan seterusnya.

Skenario tercakup

Alat Pemecahan Masalah memeriksa skenario berikut:

  • Agen tidak melaporkan data atau data heartbeat hilang.
  • Penyebaran ekstensi agen gagal.
  • Agen mengalami crash.
  • Agen mengkonsumsi CPU atau memori yang tinggi.
  • Kegagalan pengalaman penginstalan dan penghapusan instalasi.
  • Log kustom memiliki masalah.
  • Gateway OMS memiliki masalah.
  • Penghitung kinerja memiliki masalah.
  • Log agen tidak dapat dikumpulkan.

Catatan

Jalankan Alat Pemecahan Masalah saat Anda mengalami masalah. Memiliki log dari awal akan sangat membantu tim dukungan kami dalam memecahkan masalah Anda lebih cepat.

Sumber pemecahan masalah penting

Untuk membantu memecahkan masalah yang terkait dengan agen Log Analytics untuk Windows, agen mencatat peristiwa ke Log Peristiwa Windows, khususnya di bawah Application and Services\Operations Manager.

Masalah konektivitas

Jika agen berkomunikasi melalui server proksi atau firewall, pembatasan mungkin berlaku yang mencegah komunikasi dari komputer sumber dan layanan Azure Monitor. Jika komunikasi diblokir karena kesalahan konfigurasi, pendaftaran dengan ruang kerja mungkin gagal saat mencoba menginstal agen atau mengonfigurasi agen pasca-penyiapan untuk melaporkan ke ruang kerja lain. Komunikasi agen mungkin gagal setelah pendaftaran berhasil. Bagian ini menjelaskan metode untuk memecahkan masalah jenis ini dengan agen Windows.

Periksa kembali apakah firewall atau proksi dikonfigurasi untuk mengizinkan port dan URL berikut yang dijelaskan dalam tabel berikut. Konfirmasikan juga bahwa inspeksi HTTP tidak diaktifkan untuk lalu lintas web. Ini dapat mencegah saluran TLS yang aman antara agen dan Azure Monitor.

Sumber daya agen Port Arah Melewati inspeksi HTTPS
*.ods.opinsights.azure.com Port 443 Keluar Ya
*.ods.opinsights.azure.com Port 443 Keluar Ya
*.blob.core.windows.net Port 443 Keluar Ya
*.agentsvc.azure-automation.net Port 443 Keluar Ya

Untuk informasi firewall yang diperlukan untuk Azure Government, lihat Manajemen Azure Government. Jika Anda berencana menggunakan Azure Automation Hybrid Runbook Worker untuk terhubung dan mendaftar dengan layanan Otomatisasi untuk menggunakan runbook atau solusi manajemen di lingkungan Anda, itu harus memiliki akses ke nomor port dan URL yang dijelaskan dalam Mengonfigurasi jaringan Anda untuk Hybrid Runbook Worker.

Ada beberapa cara untuk memverifikasi apakah agen berhasil berkomunikasi dengan Azure Monitor:

  • Mengaktifkan penilaian Kesehatan Agen Log Analytics di ruang kerja. Dari dasbor Kesehatan Agen, lihat kolom Hitungan agen yang tidak responsif untuk melihat dengan cepat apakah agen terdaftar.

  • Jalankan kueri berikut untuk mengonfirmasi agen mengirim heartbeat ke ruang kerja yang dikonfigurasi untuk dilaporkan. Mengganti <ComputerName> dengan nama mesin yang sebenarnya.

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

    Jika komputer berhasil berkomunikasi dengan layanan, kueri harus mengembalikan hasil. Jika kueri tidak mengembalikan hasil, pertama-tama verifikasi agen dikonfigurasi untuk melaporkan ke ruang kerja yang benar. Jika dikonfigurasi dengan benar, lanjutkan ke langkah 3 dan cari Log Peristiwa Windows untuk mengidentifikasi apakah agen mencatat masalah yang mungkin mencegahnya berkomunikasi dengan Azure Monitor.

  • Metode lain untuk mengidentifikasi masalah konektivitas adalah dengan menjalankan alat TestCloudConnectivity. Alat ini dipasang secara default dengan agen dalam folder %SystemRoot%\Program Files\Microsoft Monitoring Agent\Agent. Dari prompt perintah yang ditingkatkan, buka folder dan jalankan alat . Alat mengembalikan hasil dan menyoroti di mana pengujian gagal. Misalnya, mungkin itu terkait dengan port atau URL tertentu yang diblokir.

    Screenshot that shows TestCloudConnection tool execution results.

  • Filter log peristiwa Pengelola Operasi menurut Sumber peristiwaModul Layanan Kesehatan, Layanan Kesehatan, dan Konektor Layanan dan filter menurut Tingkat PeristiwaPeringatan dan Kesalahan untuk mengonfirmasi apakah telah menulis peristiwa dari tabel berikut. Jika ya, tinjau langkah-langkah resolusi yang disertakan untuk setiap peristiwa yang mungkin terjadi.

    ID Peristiwa Sumber Deskripsi Resolusi
    2133 & 2129 Layanan Kesehatan Koneksi ke layanan dari agen gagal. Kesalahan ini dapat terjadi ketika agen tidak dapat berkomunikasi secara langsung atau melalui firewall atau server proksi ke layanan Azure Monitor. Verifikasi pengaturan proksi agen atau bahwa firewall jaringan atau proksi memungkinkan lalu lintas TCP dari komputer ke layanan.
    2138 Modul Layanan Kesehatan Proksi memerlukan autentikasi. Mengonfigurasi setelan proksi agen dan tentukan nama pengguna/kata sandi yang diperlukan untuk mengautentikasi dengan server proksi.
    2129 Modul Layanan Kesehatan Koneksi gagal. Negosiasi TLS gagal. Periksa setelan TCP/IP adaptor jaringan Anda dan setelan proksi agen.
    2127 Modul Layanan Kesehatan Gagal mengirim data yang menerima kode kesalahan. Jika hanya terjadi secara berkala di siang hari, itu bisa menjadi anomali acak yang dapat diabaikan. Pantau untuk memahami seberapa sering hal itu terjadi. Jika sering terjadi sepanjang hari, pertama-tama periksa konfigurasi jaringan dan pengaturan proksi Anda. Jika deskripsi memasukkan kode kesalahan HTTP 404 dan ini pertama kalinya agen mencoba mengirim data ke layanan,itu akan mencakup kesalahan 500 dengan kode kesalahan internal 404. Kode kesalahan 404 berarti "tidak ditemukan", yang menunjukkan bahwa area penyimpanan untuk ruang kerja baru masih diprovisikan. Pada percobaan ulang berikutnya, data akan berhasil menulis ke ruang kerja seperti yang diharapkan. Kesalahan HTTP 403 mungkin menunjukkan masalah izin atau informasi masuk. Informasi selengkapnya disertakan dengan kesalahan 403 untuk membantu memecahkan masalah.
    4000 Konektor Layanan Resolusi nama DNS gagal. Komputer tidak dapat menyelesaikan alamat internet yang digunakan saat mengirim data ke layanan. Masalah ini mungkin pengaturan pemecah masalah DNS di komputer Anda, pengaturan proksi yang salah, atau masalah DNS sementara dengan penyedia Anda. Jika itu terjadi secara berkala, itu dapat disebabkan oleh masalah terkait jaringan sementara.
    4001 Konektor Layanan Sambungan ke layanan gagal. Kesalahan ini dapat terjadi ketika agen tidak dapat berkomunikasi secara langsung atau melalui firewall atau server proksi ke layanan Azure Monitor. Verifikasi pengaturan proksi agen atau bahwa firewall jaringan atau proksi memungkinkan lalu lintas TCP dari komputer ke layanan.
    4002 Konektor Layanan Layanan mengembalikan kode status HTTP 403 sebagai respons terhadap kueri. Tanyakan kepada administrator layanan tentang kesehatan layanan. Kueri akan dicoba kembali nanti. Kesalahan ini ditulis selama fase pendaftaran awal agen. Anda akan melihat URL yang mirip dengan https://< workspaceID.oms.opinsights.azure.com/AgentService.svc/AgentTopologyRequest>. Kode kesalahan 403 berarti "terlarang" dan dapat disebabkan oleh ID atau kunci Ruang Kerja yang salah ketik. Tanggal dan waktu mungkin juga salah pada komputer. Jika waktunya +/- 15 menit dari waktu saat ini, onboarding gagal. Untuk memperbaiki masalah ini, perbarui tanggal dan/atau waktu komputer Windows Anda.

Masalah pengumpulan data

Setelah agen diinstal dan melaporkan ke ruang kerja atau ruang kerja yang dikonfigurasi, agen mungkin berhenti menerima konfigurasi dan mengumpulkan atau meneruskan performa, log, atau data lain ke layanan tergantung pada apa yang diaktifkan dan menargetkan komputer. Anda perlu menentukan:

  • Apakah jenis data tertentu atau semua data yang tidak tersedia di ruang kerja?
  • Apakah jenis data ditentukan oleh solusi atau ditentukan sebagai bagian dari konfigurasi pengumpulan data ruang kerja?
  • Berapa banyak komputer yang terpengaruh? Apakah komputer tunggal atau beberapa komputer melapor ke ruang kerja?
  • Apakah itu bekerja dan apakah itu berhenti pada waktu tertentu hari, atau tidak pernah dikumpulkan?
  • Apakah kueri pencarian log yang Anda gunakan secara sintis benar?
  • Apakah agen pernah menerima konfigurasinya dari Azure Monitor?

Langkah pertama dalam pemecahan masalah adalah menentukan apakah komputer mengirimkan peristiwa heartbeat.

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

Jika kueri mengembalikan hasil, Anda perlu menentukan apakah tipe data tertentu tidak dikumpulkan dan diteruskan ke layanan. Masalah ini dapat disebabkan oleh agen tidak menerima konfigurasi yang diperbarui dari layanan atau beberapa gejala lain yang mencegah agen beroperasi secara normal. Lakukan langkah-langkah berikut untuk memecahkan masalah lebih lanjut.

  1. Buka prompt perintah yang ditingkatkan di komputer dan mulai ulang layanan agen dengan memasukkan net stop healthservice && net start healthservice.

  2. Buka log peristiwa Manajer Operasi dan cari IDperistiwa 7023, 7024, 7025, 7028, dan 1210 dari Sumberperistiwa HealthService. Peristiwa ini menunjukkan agen berhasil menerima konfigurasi dari Azure Monitor dan mereka secara aktif memantau komputer. Deskripsi acara untuk peristiwa ID 1210 juga akan menentukan pada baris terakhir semua solusi dan Wawasan yang dimasukkan dalam lingkup pemantauan pada agen.

    Screenshot that shows an Event ID 1210 description.

  3. Tunggu beberapa menit. Jika Anda tidak melihat data yang diharapkan dalam hasil atau visualisasi kueri, bergantung pada apakah Anda menampilkan data dari solusi atau Wawasan, dari log peristiwa Manajer Operasi, cari Sumber peristiwa Modul Layanan Kesehatan dan Layanan Kesehatan. Filter menurut Peringatan TingkatPeristiwa dan Kesalahan untuk mengonfirmasi apakah telah menulis peristiwa dari tabel berikut.

    ID Peristiwa Sumber Deskripsi Resolusi
    8000 HealthService Peristiwa ini akan menentukan apakah alur kerja yang terkait dengan performa, peristiwa, atau jenis data lain yang dikumpulkan tidak dapat diteruskan ke layanan untuk diserap ke ruang kerja. ID Peristiwa 2136 dari sumber HealthService ditulis bersama dengan peristiwa ini dan dapat menunjukkan agen tidak dapat berkomunikasi dengan layanan. Kemungkinan alasannya mungkin salah konfigurasi pengaturan proksi dan autentikasi, pemadaman jaringan, atau firewall jaringan atau proksi tidak mengizinkan lalu lintas TCP dari komputer ke layanan.
    10102 dan 10103 Modul Layanan Kesehatan Alur kerja tidak dapat mengatasi sumber data. Masalah ini dapat terjadi jika penghitung kinerja atau instans yang ditentukan tidak ada di komputer atau salah ditentukan dalam pengaturan data ruang kerja. Jika ini adalah penghitung kinerja yang ditentukan pengguna, verifikasi informasi yang ditentukan mengikuti format yang benar dan ada pada komputer target.
    26002 Modul Layanan Kesehatan Alur kerja tidak dapat mengatasi sumber data. Masalah ini dapat terjadi jika log kejadian Windows yang ditentukan tidak ada di komputer. Kesalahan ini dapat diabaikan dengan aman jika komputer tidak diharapkan untuk mendaftarkan log kejadian ini. Jika tidak, jika ini adalah log peristiwa yang ditentukan pengguna, verifikasi informasi yang ditentukan sudah benar.

Masalah Sertifikat yang Disematkan dengan Agen Pemantauan Microsoft yang Lebih Lama - Melanggar Perubahan

Gambaran Umum Perubahan CA Akar

Mulai 30 Juni 2023, back-end Log Analytics tidak akan lagi menerima koneksi dari MMA yang mereferensikan sertifikat akar yang sudah kedaluarsa. MMA ini adalah versi lama sebelum rilis Winter 2020 (Agen Analitik Log) dan sebelum SCOM 2019 UR3 (SCOM). Versi apa pun, Bundel: 10.20.18053 / Extension: 1.0.18053.0, atau lebih besar tidak akan memiliki masalah, serta versi apa pun di atas SCOM 2019 UR3. Setiap agen yang lebih lama dari itu akan rusak dan tidak lagi berfungsi dan diunggah ke Analitik Log.

Apa sebenarnya yang berubah?

Sebagai bagian dari upaya keamanan yang sedang berlangsung di berbagai layanan Azure, Azure Log Analytics akan secara resmi beralih dari Baltimore CyberTrust CA Root ke DigiCert Global G2 CA Root. Perubahan ini akan berdampak pada komunikasi TLS dengan Analitik Log jika sertifikat Akar CA DigiCert Global G2 baru hilang dari OS, atau aplikasi mereferensikan CA Baltimore Root lama. Artinya, Analitik Log tidak akan lagi menerima koneksi dari MMA yang menggunakan CA akar lama ini setelah dihentikan.

Produk solusi

Anda mungkin telah menerima pemberitahuan perubahan yang melanggar meskipun Anda belum menginstal Microsoft Monitoring Agent secara pribadi. Itu karena berbagai produk Azure memanfaatkan Microsoft Monitoring Agent. Jika Anda menggunakan salah satu produk ini, Anda mungkin terpengaruh karena memanfaatkan Agen Analitik Log Windows. Untuk produk-produk dengan tautan di bawah ini mungkin ada instruksi khusus yang akan mengharuskan Anda untuk meningkatkan ke agen terbaru.

Mengidentifikasi dan Meremidiasi Agen Yang Melanggar

Untuk penyebaran dengan sejumlah agen terbatas, kami sangat menyarankan Anda meningkatkan agen per simpul melalui instruksi manajemen ini.

Untuk penyebaran dengan beberapa simpul, kami telah menulis skrip yang akan mendeteksi MMAs melanggar yang terpengaruh per langganan lalu kemudian meningkatkannya ke versi terbaru. Skrip ini perlu dijalankan secara berurutan, dimulai dengan UpdateMMA.ps1 lalu UpgradeMMA.ps1. Tergantung pada komputer, skrip mungkin memakan waktu cukup lama. PowerShell 7 atau yang lebih besar diperlukan untuk dijalankan untuk menghindari batas waktu.

UpdateMMA.ps1 Skrip ini akan melalui VM dalam langganan Anda, periksa MMAs yang ada yang diinstal lalu buat file agen .csv yang perlu ditingkatkan.

UpgradeMMA.ps1 Skrip ini akan menggunakan . File CSV yang dihasilkan di UpdateMMA.ps1 untuk meningkatkan semua MMAs yang melanggar.

Kedua skrip ini mungkin perlu waktu cukup lama untuk diselesaikan.

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