graphAPI czy PowerShell?
duża część mojej pracy to PowerShell – ponieważ częściej trzeba coś wykonać hurtem, a nie dla pojedynczego zasobu. różnego rodzaju raporty, wyszukiwanie, automatyzacje etc – wszystko to działa na dużych liczbach. commandlety Az, tak ogólnie mówiąc, są makabryczne – zawieszają się, mają niespójne atrybuty zwracanych obiektów, jest ich kosmicznie dużo i ogólnie – sprawiają problemy…
…ale największym problemem jest ich kontekstowość i wydajność. aby wykonać jakąś operację, najpierw trzeba ustawić kontekst, który wymusza ograniczenie danej operacji do konkretnej subskrypcji. a często zapytanie musi ograniczać wręcz do konkretnej Resource Group.
Microsoft Graph wymaga natomiast wiedzy developerskiej i korzysta z REST API do wykonywania zapytań, a więc mało przyjazne dla skryptera… tylko czy aby na pewno?
niekoniecznie! jest moduł Az.ResourceGraph, który nie wiem czemu, ale nie jest instalowany wraz z resztą modułów Az.*. trzeba go po prostu zainstalować jako 'standalone’, dodatkowo. dzięki niemu można nadal pisać w PowerShell’u równocześnie korzystając z dobrodziejstw, jakie daje Graph… czyli co konkretnie?
można się rozwodzić o tym jak wspaniałym wynalazkiem jest Graph, jak cudownie odzwierciedla rzeczywistość i jak miażdży relacyjne bazy danych [których nigdy nie lubiłem… no może nie samych baz, ale SQL jest pasqdny i prymitywny ]… o czym oczywiście warto poczytać – ale można po prostu 'dotknąć’ i przekonać się samemu.
no więc dotknijmy. taki scenariusz:
jak poustawiane mają opcje update’ów VMki?
teoria do tego zadania jest tutaj, i w klasycznym PowerShell algorytm jest prosty:
- wylistuj wszystkie subskrypcje
- dla każdej z nich wylistuj parametry patchowania dla wszystkich VMek.
dodam do tego pomiar czasu, który będzie odpowiedzią na pytanie czy warto korzystać z Microsoft Graph:
Measure-Command { Get-AzSubscription|%{ >> $sub=$_.name; >> $c = set-azcontext -SubscriptionObject $_; >> get-azvm | select @{L='sub';E={$sub}}, resourcegroupname,name, ` >> @{L='ostype';E={$_.StorageProfile.OsDisk.OsType}}, ` >> @{L='patchmode';E={ >> if($_.StorageProfile.OsDisk.OsType -eq 'linux') { >> $_.OSProfile.LinuxConfiguration.PatchSettings.PatchMode >> } else { >> $_.OSProfile.WindowsConfiguration.PatchSettings.PatchMode >> } >> } >> } >> } | export-csv c:\temp\patching.csv -nti -Encoding utf8 >> }
wynik:
TotalMinutes : 23.4296124083333
TotalSeconds : 1405.7767445
teraz zróbmy taki sam test, ale korzystając z zapytania MSGraph:
measure-command {(Search-AzGraph -Query "resources | where type =~ 'microsoft.compute/virtualmachines' | extend os = properties.storageProfile.osDisk.osType | extend patchMode = iff(properties.storageProfile.osDisk.osType=~'windows',properties.osProfile.windowsConfiguration.patchSettings.patchMode,properties.osProfile.linuxConfiguration.patchSettings.patchMode) | join kind=inner (resourceContainers | where type =~ 'microsoft.resources/subscriptions' | project subscriptionId,subscriptionName=name) on subscriptionId | project name,subscriptionName,resourceGroup,os,patchMode").getenumerator()|export-csv -Encoding utf8 -nti C:\temp\patchingGAPI.csv}
wynik:
TotalMinutes : 0.0394362883333333
TotalSeconds : 2.3661773
23 min vs 2.3 sec… komentarz wydaje się być zbędny….
interesuje was ten temat? napisać coś o wadach i zrobić jakiś wstęp do wykorzystania w skryptach?
PS. commandlety Az są w trakcie przypisywania na Microsoft Graph ze starszej wersji… to też dodatkowa niestabilność i sporadyczne różnice w wynikach. ot taka błahostka: czy jakieś polecenie get, kiedy nie znajdzie danego zasobu, zwróci błąd czy $null? … i logika skryptów idzie w …las.
eN.