Jinsi ya kuunda nyongeza ya roketi kwa hati za PowerCLI 

Hivi karibuni au baadaye, msimamizi yeyote wa mfumo wa VMware anakuja kugeuza kazi za kawaida. Yote huanza na mstari wa amri, kisha inakuja PowerShell au VMware PowerCLI.

Wacha tuseme umeifahamu PowerShell mbele kidogo kuliko kuzindua ISE na kutumia cmdlets za kawaida kutoka kwa moduli zinazofanya kazi kwa sababu ya "aina fulani ya uchawi". Unapoanza kuhesabu mashine pepe katika mamia, utapata kwamba hati zinazosaidia kwa kiwango kidogo zinaenda polepole sana kwa kiwango kikubwa. 

Katika hali hii, zana 2 zitasaidia:

  • Nafasi za Run za PowerShell - njia ambayo hukuruhusu kusawazisha utekelezaji wa michakato katika nyuzi tofauti; 
  • Pata-Tazama - kazi ya msingi ya PowerCLI, analogi ya Get-WMIObject katika Windows. Cmdlet hii haitoi vitu vinavyoandamana na vyombo, lakini hupokea habari katika mfumo wa kitu rahisi na aina rahisi za data. Katika hali nyingi hutoka kwa kasi zaidi.

Ifuatayo, nitazungumza kwa ufupi juu ya kila chombo na kuonyesha mifano ya matumizi. Wacha tuchambue maandishi maalum na tuone wakati moja inafanya kazi vizuri zaidi kuliko nyingine. Nenda!

Jinsi ya kuunda nyongeza ya roketi kwa hati za PowerCLI

Hatua ya kwanza: Runspace

Kwa hivyo, Runspace imeundwa kwa usindikaji sambamba wa kazi nje ya moduli kuu. Bila shaka, unaweza kuzindua mchakato mwingine ambao utakula baadhi ya kumbukumbu, kichakataji, n.k. Ikiwa hati yako itaendeshwa kwa dakika kadhaa na kutumia kumbukumbu ya gigabaiti, kuna uwezekano mkubwa kwamba hutahitaji Runspace. Lakini kwa maandishi kwa makumi ya maelfu ya vitu inahitajika.

Unaweza kuanza kujifunza hapa: 
Kuanza kwa Matumizi ya Nafasi za Run za PowerShell: Sehemu ya 1

Kutumia Runspace kunatoa nini:

  • kasi kwa kupunguza orodha ya amri zilizotekelezwa,
  • utekelezaji wa kazi sambamba,
  • usalama.

Hapa kuna mfano kutoka kwa Mtandao wakati Runspace inasaidia:

β€œUgomvi wa hifadhi ni mojawapo ya vipimo vigumu zaidi kufuatilia katika vSphere. Ndani ya vCenter, huwezi kwenda tu na kuona ni VM gani inayotumia rasilimali zaidi za uhifadhi. Kwa bahati nzuri, unaweza kukusanya data hii kwa dakika shukrani kwa PowerShell.
Nitashiriki hati ambayo itaruhusu wasimamizi wa mfumo wa VMware kutafuta haraka katika vCenter nzima na kupokea orodha ya VM na data juu ya matumizi yao ya wastani.  
Hati hutumia nafasi za kukimbia za PowerShell ili kuruhusu kila seva pangishi ya ESXi kukusanya taarifa za matumizi kutoka kwa VM zake katika Runspace tofauti na kuripoti kukamilika mara moja. Hii inaruhusu PowerShell kufunga kazi mara moja, badala ya kurudia kupitia wapangishaji na kungoja kila mmoja kukamilisha ombi lake.

Chanzo: Jinsi ya Kuonyesha Mashine Pembeni I/O kwenye Dashibodi ya ESXi

Katika kesi iliyo hapa chini, Runspace haifai tena:

"Ninajaribu kuandika hati ambayo inakusanya data nyingi kutoka kwa VM na kuandika data mpya inapohitajika. Shida ni kwamba kuna VM nyingi sana, na sekunde 5-8 zinatumika kwenye mashine moja. 

Chanzo: Multithreading PowerCLI na RunspacePool

Hapa utahitaji Get-View, wacha tuendelee nayo. 

Hatua ya pili: Pata-Tazama

Ili kuelewa ni kwa nini Get-View ni muhimu, inafaa kukumbuka jinsi cmdlets hufanya kazi kwa ujumla. 

Cmdlets zinahitajika ili kupata habari kwa urahisi bila hitaji la kusoma vitabu vya marejeleo vya API na kuunda upya gurudumu linalofuata. Nini katika siku za zamani ilichukua mistari mia moja au mbili ya kanuni, PowerShell inakuwezesha kufanya na amri moja. Tunalipa kwa urahisi huu kwa kasi. Hakuna uchawi ndani ya cmdlets wenyewe: script sawa, lakini kwa kiwango cha chini, kilichoandikwa na mikono ya ujuzi wa bwana kutoka India ya jua.

Sasa, kwa kulinganisha na Get-View, hebu tuchukue Get-VM cmdlet: inafikia mashine ya kawaida na inarudisha kitu cha mchanganyiko, ambayo ni, inashikilia vitu vingine vinavyohusiana nayo: VMHost, Datastore, nk.  

Get-View katika nafasi yake haiongezi chochote kisichohitajika kwa kitu kilichorejeshwa. Zaidi ya hayo, inaturuhusu kutaja madhubuti ni habari gani tunayohitaji, ambayo itafanya kitu cha pato kiwe rahisi. Katika Windows Server kwa ujumla na katika Hyper-V hasa, Get-WMIObject cmdlet ni analog ya moja kwa moja - wazo ni sawa kabisa.

Get-View sio rahisi kwa shughuli za kawaida kwenye vitu vya uhakika. Lakini inapokuja kwa maelfu na makumi ya maelfu ya vitu, haina bei.

Unaweza kusoma zaidi kwenye blogi ya VMware: Utangulizi wa Get-View

Sasa nitakuonyesha kila kitu kwa kutumia kesi halisi. 

Kuandika hati ili kupakua VM

Siku moja mwenzangu aliniuliza niongeze hati yake. Kazi ni utaratibu wa kawaida: pata VM zote na parameter ya cloud.uuid duplicate (ndiyo, hii inawezekana wakati wa kuunda VM katika Mkurugenzi wa vCloud). 

Suluhisho dhahiri linalokuja akilini ni:

  1. Pata orodha ya VM zote.
  2. Changanua orodha kwa njia fulani.

Toleo la asili lilikuwa hati hii rahisi:

function Get-CloudUUID1 {
   # ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ список всСх Π’Πœ
   $vms = Get-VM
   $report = @()

   # ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, получая ΠΈΠ· Π½Π΅Π³ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ 2 свойства: Имя Π’Πœ ΠΈ Cloud UUID.
   # Заносим Π΄Π°Π½Π½Ρ‹Π΅ Π² Π½ΠΎΠ²Ρ‹ΠΉ PS-ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ с полями VM ΠΈ UUID
   foreach ($vm in $vms)
   {
       $table = "" | select VM,UUID

       $table.VM = $vm.name
       $table.UUID = ($vm | Get-AdvancedSetting -Name cloud.uuid).Value
          
       $report += $table
   }
# Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ всС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹
   $report
}
# Π”Π°Π»Π΅Π΅ РУКАМИ парсим ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚

Kila kitu ni rahisi sana na wazi. Inaweza kuandikwa kwa dakika chache na mapumziko ya kahawa. Screw juu ya filtration na ni kosa.

Lakini wacha tupime wakati:

Jinsi ya kuunda nyongeza ya roketi kwa hati za PowerCLI

Jinsi ya kuunda nyongeza ya roketi kwa hati za PowerCLI

Dakika 2 sekunde 47 wakati wa usindikaji karibu 10k VM. Bonasi ni kukosekana kwa vichujio na hitaji la kupanga matokeo mwenyewe. Ni wazi, hati inahitaji uboreshaji.

Nafasi za kukimbia ndizo za kwanza kusaidia wakati unahitaji kupata vipimo vya mwenyeji kutoka vCenter au unahitaji kuchakata makumi ya maelfu ya vitu. Hebu tuone mbinu hii inaleta nini.

Washa kasi ya kwanza: PowerShell Runspaces

Jambo la kwanza linalokuja akilini kwa hati hii ni kutekeleza kitanzi sio kwa mtiririko, lakini kwa nyuzi zinazofanana, kukusanya data zote kwenye kitu kimoja na kuchuja. 

Lakini kuna tatizo: PowerCLI haitaturuhusu kufungua vipindi vingi vya kujitegemea kwa vCenter na itatupa hitilafu ya kuchekesha:

You have modified the global:DefaultVIServer and global:DefaultVIServers system variables. This is not allowed. Please reset them to $null and reconnect to the vSphere server.

Ili kutatua hili, lazima kwanza upitishe maelezo ya kipindi ndani ya mtiririko. Tukumbuke kwamba PowerShell hufanya kazi na vitu vinavyoweza kupitishwa kama kigezo ama kwa chaguo za kukokotoa au kwa ScriptBlock. Wacha tupitishe kikao katika mfumo wa kitu kama hicho, tukipita $global:DefaultVIServers (Unganisha-VIServer na kitufe cha -NotDefault):

$ConnectionString = @()
foreach ($vCenter in $vCenters)
   {
       try {
           $ConnectionString += Connect-VIServer -Server $vCenter -Credential $Credential -NotDefault -AllLinked -Force -ErrorAction stop -WarningAction SilentlyContinue -ErrorVariable er
       }
       catch {
           if ($er.Message -like "*not part of a linked mode*")
           {
               try {
                   $ConnectionString += Connect-VIServer -Server $vCenter -Credential $Credential -NotDefault -Force -ErrorAction stop -WarningAction SilentlyContinue -ErrorVariable er
               }
               catch {
                   throw $_
               }
              
           }
           else {
               throw $_
           }
       }
   }

Sasa hebu tutekeleze usomaji mwingi kupitia Madimbwi ya Runspace.  

Algorithm ni kama ifuatavyo:

  1. Tunapata orodha ya VM zote.
  2. Katika mito sambamba tunapata cloud.uuid.
  3. Tunakusanya data kutoka kwa mitiririko hadi kitu kimoja.
  4. Tunachuja kitu kwa kukipanga kulingana na thamani ya uga wa CloudUUID: zile ambazo idadi ya thamani za kipekee ni kubwa kuliko 1 ndio VM tunazotafuta.

Kama matokeo, tunapata hati:


function Get-VMCloudUUID {
   param (
       [string[]]
       [ValidateNotNullOrEmpty()]
       $vCenters = @(),
       [int]$MaxThreads,
       [System.Management.Automation.PSCredential]
       [System.Management.Automation.Credential()]
       $Credential
   )

   $ConnectionString = @()

   # Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ с сСссионным ΠΊΠ»ΡŽΡ‡ΠΎΠΌ
   foreach ($vCenter in $vCenters)
   {
       try {
           $ConnectionString += Connect-VIServer -Server $vCenter -Credential $Credential -NotDefault -AllLinked -Force -ErrorAction stop -WarningAction SilentlyContinue -ErrorVariable er
       }
       catch {
           if ($er.Message -like "*not part of a linked mode*")
           {
               try {
                   $ConnectionString += Connect-VIServer -Server $vCenter -Credential $Credential -NotDefault -Force -ErrorAction stop -WarningAction SilentlyContinue -ErrorVariable er
               }
               catch {
                   throw $_
               }
              
           }
           else {
               throw $_
           }
       }
   }

   # ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ список всСх Π’Πœ
   $Global:AllVMs = Get-VM -Server $ConnectionString

   # ΠŸΠΎΠ΅Ρ…Π°Π»ΠΈ!
   $ISS = [system.management.automation.runspaces.initialsessionstate]::CreateDefault()
   $RunspacePool = [runspacefactory]::CreateRunspacePool(1, $MaxThreads, $ISS, $Host)
   $RunspacePool.ApartmentState = "MTA"
   $RunspacePool.Open()
   $Jobs = @()

# ScriptBlock с магиСй!)))
# ИмСнно ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π² ΠΏΠΎΡ‚ΠΎΠΊΠ΅
   $scriptblock = {
       Param (
       $ConnectionString,
       $VM
       )

       $Data = $VM | Get-AdvancedSetting -Name Cloud.uuid -Server $ConnectionString | Select-Object @{N="VMName";E={$_.Entity.Name}},@{N="CloudUUID";E={$_.Value}},@{N="PowerState";E={$_.Entity.PowerState}}

       return $Data
   }
# Π“Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΈ

   foreach($VM in $AllVMs)
   {
       $PowershellThread = [PowerShell]::Create()
# ДобавляСм скрипт
       $null = $PowershellThread.AddScript($scriptblock)
# И ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΄ΠΈΠΌ Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² скрипту
       $null = $PowershellThread.AddArgument($ConnectionString)
       $null = $PowershellThread.AddArgument($VM)
       $PowershellThread.RunspacePool = $RunspacePool
       $Handle = $PowershellThread.BeginInvoke()
       $Job = "" | Select-Object Handle, Thread, object
       $Job.Handle = $Handle
       $Job.Thread = $PowershellThread
       $Job.Object = $VM.ToString()
       $Jobs += $Job
   }

# Π‘Ρ‚Π°Π²ΠΈΠΌ градусник, Ρ‡Ρ‚ΠΎΠ±Ρ‹ наглядно ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π·Π°Π΄Π°Π½ΠΈΠΉ
# И здСсь ΠΆΠ΅ ΠΏΡ€ΠΈΠ±ΠΈΠ²Π°Π΅ΠΌ ΠΎΡ‚Ρ€Π°Π±ΠΎΡ‚Π°Π²ΡˆΠΈΠ΅ задания
   While (@($Jobs | Where-Object {$_.Handle -ne $Null}).count -gt 0)
   {
       $Remaining = "$($($Jobs | Where-Object {$_.Handle.IsCompleted -eq $False}).object)"

       If ($Remaining.Length -gt 60) {
           $Remaining = $Remaining.Substring(0,60) + "..."
       }

       Write-Progress -Activity "Waiting for Jobs - $($MaxThreads - $($RunspacePool.GetAvailableRunspaces())) of $MaxThreads threads running" -PercentComplete (($Jobs.count - $($($Jobs | Where-Object {$_.Handle.IsCompleted -eq $False}).count)) / $Jobs.Count * 100) -Status "$(@($($Jobs | Where-Object {$_.Handle.IsCompleted -eq $False})).count) remaining - $remaining"

       ForEach ($Job in $($Jobs | Where-Object {$_.Handle.IsCompleted -eq $True})){
           $Job.Thread.EndInvoke($Job.Handle)     
           $Job.Thread.Dispose()
           $Job.Thread = $Null
           $Job.Handle = $Null
       }
   }

   $RunspacePool.Close() | Out-Null
   $RunspacePool.Dispose() | Out-Null
}


function Get-CloudUUID2
{
   [CmdletBinding()]
   param(
   [string[]]
   [ValidateNotNullOrEmpty()]
   $vCenters = @(),
   [int]$MaxThreads = 50,
   [System.Management.Automation.PSCredential]
   [System.Management.Automation.Credential()]
   $Credential)

   if(!$Credential)
   {
       $Credential = Get-Credential -Message "Please enter vCenter credentials."
   }

   # Π’Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Get-VMCloudUUID, Π³Π΄Π΅ ΠΌΡ‹ распараллСливаСм ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ
   $AllCloudVMs = Get-VMCloudUUID -vCenters $vCenters -MaxThreads $MaxThreads -Credential $Credential
   $Result = $AllCloudVMs | Sort-Object Value | Group-Object -Property CloudUUID | Where-Object -FilterScript {$_.Count -gt 1} | Select-Object -ExpandProperty Group
   $Result
}

Uzuri wa hati hii ni kwamba inaweza kutumika katika hali zingine zinazofanana kwa kubadilisha tu ScriptBlock na vigezo ambavyo vitapitishwa kwa mkondo. Itumie!

Tunapima wakati:

Jinsi ya kuunda nyongeza ya roketi kwa hati za PowerCLI

Sekunde 55. Ni bora, lakini bado inaweza kuwa haraka. 

Wacha tuende kwa kasi ya pili: GetView

Hebu tujue ni nini kibaya.
Kwanza kabisa, Get-VM cmdlet inachukua muda mrefu kutekeleza.
Pili, Pata-AdvancedOptions cmdlet inachukua muda mrefu zaidi kukamilika.
Wacha tushughulike na ya pili kwanza. 

Pata-AdvancedOptions ni rahisi kwa vitu vya kibinafsi vya VM, lakini ni ngumu sana wakati wa kufanya kazi na vitu vingi. Tunaweza kupata habari sawa kutoka kwa kifaa cha mashine yenyewe (Pata-VM). Imezikwa vizuri tu kwenye kitu cha ExtensionData. Silaha na kuchuja, tunaharakisha mchakato wa kupata data muhimu.

Kwa harakati kidogo ya mkono hii ni:


VM | Get-AdvancedSetting -Name Cloud.uuid -Server $ConnectionString | Select-Object @{N="VMName";E={$_.Entity.Name}},@{N="CloudUUID";E={$_.Value}},@{N="PowerState";E={$_.Entity.PowerState}}

Inageuka hii:


$VM | Where-Object {($_.ExtensionData.Config.ExtraConfig | Where-Object {$_.key -eq "cloud.uuid"}).Value -ne $null} | Select-Object @{N="VMName";E={$_.Name}},@{N="CloudUUID";E={($_.ExtensionData.Config.ExtraConfig | Where-Object {$_.key -eq "cloud.uuid"}).Value}},@{N="PowerState";E={$_.summary.runtime.powerstate}}

Pato ni sawa na Pata-AdvancedOptions, lakini inafanya kazi mara nyingi haraka. 

Sasa kupata-VM. Sio haraka kwa sababu inahusika na vitu ngumu. Swali la kimantiki linatokea: kwa nini tunahitaji maelezo ya ziada na PSObject ya kutisha katika kesi hii, wakati tunahitaji tu jina la VM, hali yake na thamani ya sifa ya hila?  

Kwa kuongeza, kikwazo katika mfumo wa Pata-AdvancedOptions kimeondolewa kwenye hati. Kutumia Madimbwi ya Runspace sasa inaonekana kama kuzidi kwa kuwa hakuna tena haja ya kusawazisha kazi ya polepole kwenye nyuzi za squat wakati wa kukabidhi kipindi. Chombo ni nzuri, lakini si kwa kesi hii. 

Wacha tuangalie matokeo ya ExtensionData: sio kitu zaidi ya Get-View kitu. 

Wacha tuite mbinu ya zamani ya mabwana wa PowerShell: mstari mmoja kwa kutumia vichungi, kupanga na kuweka vikundi. Hofu zote za hapo awali zimeporomoka kwa mstari mmoja na kutekelezwa katika kipindi kimoja:


$AllVMs = Get-View -viewtype VirtualMachine -Property Name,Config.ExtraConfig,summary.runtime.powerstate | Where-Object {($_.Config.ExtraConfig | Where-Object {$_.key -eq "cloud.uuid"}).Value -ne $null} | Select-Object @{N="VMName";E={$_.Name}},@{N="CloudUUID";E={($_.Config.ExtraConfig | Where-Object {$_.key -eq "cloud.uuid"}).Value}},@{N="PowerState";E={$_.summary.runtime.powerstate}} | Sort-Object CloudUUID | Group-Object -Property CloudUUID | Where-Object -FilterScript {$_.Count -gt 1} | Select-Object -ExpandProperty Group

Tunapima wakati:

Jinsi ya kuunda nyongeza ya roketi kwa hati za PowerCLI

Sekunde za 9 kwa karibu vitu 10k na kuchuja kwa hali inayotaka. Kubwa!

Badala ya hitimisho

Matokeo yanayokubalika moja kwa moja inategemea uchaguzi wa chombo. Mara nyingi ni vigumu kusema kwa uhakika ni nini hasa kinapaswa kuchaguliwa ili kuifanikisha. Kila moja ya njia zilizoorodheshwa za kuharakisha hati ni nzuri ndani ya mipaka ya utumiaji wake. Natumai nakala hii itakusaidia katika kazi ngumu ya kuelewa misingi ya otomatiki ya mchakato na uboreshaji katika miundombinu yako.

PS: Mwandishi anawashukuru wanajamii wote kwa msaada na usaidizi wao katika kuandaa makala. Hata wale wenye miguu. Na hata wale ambao hawana miguu, kama mkandamizaji wa boa.

Chanzo: mapenzi.com

Kuongeza maoni