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.