upadek religii XX w.

flow

kiedyś powiedziałem sobie, że w-files’y są poświęcone kwestiom technicznym i nie będę robił wrzutek osobistych, czy nawet miękkich. to będzie wpis – w sumie o niczym. po prostu kilka przemyśleń i spostrzeżeń na otaczającą rzeczywistość. coming out? flow? nie wiem…. po prostu mam ochotę coś przelać 'na papier’ i zobaczyć co z tego wyjdzie.

ostatnio, coś się zmieniło… a raczej zmienia. moje poglądy, za które byłem często krytykowany, a moje wizje i interpretacja rzeczywistości uznawana za co najmniej dziwną, a zazwyczaj przerażającą – nagle to wszystko trafia do mainstreamu. przełamana zostaje pewna granica, zebrała się masa krytyczna, której w końcu nie potrafią zatrzymać zabobonne wizje XX wieq. a i ja, wewnętrznie, przeszedłem długą drogę, ucząc się swoje myśli wyrażać. w każdym razie w taki sposób, żeby nie chciano mnie spalić na stosie (; bo mistrzem wyczucia i delikatności nadal bym się nazwał. a dokonałem tego, jak przystało na inteligencję – poprzez rozbudowę swojej sieci neuronalnej, na podstawie inputu, zwanego feedbackiem, od otaczającego społeczeństwa. nauczyłem się jak reagować na bodźce z zewnątrz tak, aby żyć z resztą w symbiozie…

technological singularity

teoria przyspieszenia technologicznego, prowadzącego do ’technologicznej osobliwości’, jest częścią ruchu trans- i post- humanistycznego, którego jednym z czołowych filozofów-futurystów jest Rey Kurzweil oraz Hans Moravec. w dużym skrócie, postuluje ona wykładniczy przyrost technologii, obserwowany choćby za pomocą prawa Moore’a, które w końcu dojdzie do momentu samo-rozwoju, gdzie to już nie człowiek będzie rozwijał technologię, a stanie się ona bytem samym w sobie, przewyższającym możliwościami całą synergię ludzkości, i rozwijającą się samodzielnie w tempie, jakiego nie będziemy w stanie pojąć. superinteligencja. wedle Reya, nastąpi to w okolicy 2o45 – czyli całkiem niedługo.

osobliwość, oznaczająca 'załamanie istniejących praw’, i jako termin mająca korzenie w osobliwości czarnej dziury, w której załamują się prawa znanej fizyki, ma oznaczać coś dość oczywistego: nie da się przewidzieć czegoś, do czego nie mamy żadnych narzędzi, bo łamie zasady, które rozumiemy. nie mamy nawet podstaw do tego, żeby 'przewidywać’. możemy tylko zgadywać. i tak właśnie cały świat oszalał, powoli zdając sobie sprawę z tego, że faktycznie ten czas nadchodzi.

nie dziwi mnie strach. ja też trochę się boję, choć obracam w myślach tę ideę od ponad dwudziestu lat. na tą filozofię natknąłem się dość naturalnie, na początq tegoż wieq. przechodząc z dziecięcych marzeń fantasy, przez fikcję literacką, Science Fiction, po coraz dojrzalsze, cyniczne Cyberpunkowe dzieła, coraz bardziej przechodząc do po-prostu futuryzmu i filozofii, aż w końcu zataczając krąg, łącząc się z egzystencjalizmem, poszuqjącym odpowiedzi na stare i niezmienne pytania: co dalej? jak będzie wyglądał świat? i chyba najważniejsze dla każdego: a gdzie w tym wszystkim JA? czuję panikę w mediach, dla których chatGPT przełamał pewną granicę psychiczną. czemu aqrat to A.I.? hahahaha bo tak jak ja – nauczyło się mówić ludzkim głosem. globalne zjawisko uncanny valley. a przecież widać to było jak na dłoni już dawno temu. Dr. Watson IBM’a, A.I. piszące muzykę już lata temu [przykładowy link, ale nie jedyny!] – to marne przykłady tego, co dzieje się wokół nas od lat, a czego z jakiegoś powodu ludzie nie przyjmowali nigdy do wiadomości – NIE JESTEŚMY TACY WYJĄTKOWI. ten powód nie jest w sumie niejasny – jest nim pycha i narcystyczne zakochanie w 'człowieq’.

upadek religii XXw.

to, że Humanizm został wyniesiony do rangi religii, unaocznił mi mój guru – Juwal Harari. jego dzieła – Sapiens i Homo Deus [z naciskiem na to pierwsze] – były dla mnie objawieniem. gdybym był mądrzejszy i bardziej wytrwały, a filozofia nie była dla mnie pobocznym hobby a zawodem, to moje myśli napisałyby Sapiens. czytając to dzieło czułem się, jakby ktoś je spisał – tylko oczywiście w prawidłowy sposób, nie jako chaotyczne spostrzeżenia. zarówno treść, jak i forma tej książki jest niemal doskonała. to właśnie tam pada pogląd, że Humanizm jest religią XXw. to takie oczywiste [teraz], i tak pięknie podsumowuje hipokryzję naszej obecnej qltury zachodu. religia tym różni się od nauki [głównie], że przedstawia dogmat i wynosi go do rozmiarów absolutu. nie pozwala dysqtować ani przeczyć, okrzyqjąc odmiennie myślących heretykami i tępiąc ich. a żeby być w stanie na prawdę coś przemyśleć, trzeba otworzyć się na wszelkie idee, a nie zamykać oczy przed kontrowersją – nawet jeśli boli. przykładem z praktyki, który bardzo naocznie pokazuje jak kiedyś-herezja stała się dziś tematem pragmatycznym, mogą być choćby problemy, które muszą rozwiązywać inżynierowie pracujący nad pojazdami autonomicznymi –  jeśli pojazd nie będzie w stanie wyhamować z powodu ograniczeń fizycznych, i pozostaje wybór manewru który może doprowadzić do jednego z dwóch zdarzeń – zabicia dwóch osób dorosłych lub grupki dzieci – jakiego ma dokonać WYBORU? dla wierzącego humanisty to zagadka bez rozwiązania, to nie wybór. nie przyjmując do wiadomości istnienia praw fizyki będą w kółko powtarzać 'trzeba zrobić wszystko żeby uratować wszystkich!’. zawsze mnie burzyło, kiedy czytałem wiadomości, jak to np. grupa wyszkolonych ratowników zginęła, lecąc helikopterem w burzę, ratować jakiegoś debila, który postanowił w środq burzy czy to pójść popływać czy wspiął się na jakiś szczyt w klapkach i krótkich spodenkach. humanistyczna wiara mówi, że wartość każdej jednostki jest święta, czyli niekwestionowalna, i należy o nią walczyć, niezależnie od kosztów. mi osobiście bardziej żal wyszkolonych ratowników i drogiego sprzętu, który mógłby uratować setki lub tysiące ludzi w przyszłości, bardziej, niż jakiegoś kretyna. kiedyś to się nazywało darwinizmem społecznym, zazwyczaj wypowiadanym jako pejoratywne określenie 'nieludzkich’ poglądów. takich jak moje. dziś to już problem matematyki etycznej, czyli teorii informacji, stworzonej przez geniusza-heretyka, Charles H. Bennetta. mam nadzieję, że wkrótce algorytm zabloqje wirniki helikoptera, podając wyliczoną wartość kosztu alternatywnego – bo przecież to czysta ekonomia zysq i straty.

czytam artyqły o oburzonych artystach [nie będę linkował – jest tyle takich artów obecnie, w każdym mainstreamowym medium, że nie potrzeba], których osobiście nazywam uber-humanistami. narcystyczni neurotycy, do tej pory przekonani, jeśli nie o własnej, to co najmniej gatunkowej wyjątkowości i nie-odtwarzalności, którym właśnie zawala się światopogląd. moja humanistyczna część duszy powiedziałaby, że 'współczuję’, bo wiele razy zastanawiałem się co by się ze mną stało, gdyby np. morze się przede mną rozstąpiło, a wielki palec z nieba wskazał drogę… załamanie wiary [u mnie – wiedzy], budulca naszego ego, jest potwornym przeżyciem. to jak przeżyć własną śmierć, a wszystko co było prawdą, nagle nie ma wartości…

z drugiej strony jest to dla mnie niemałą satysfakcją – mój wewnętrzny narcyz, napędzający ego, coraz głośniej krzyczy: ’a nie mówiłem?’. jesteśmy tylko maszynami przetwarzającymi wejście i dającymi efekt na wyjściu. to kwestia czasu, aż uda się zbudować podobną maszynę – czy w końcu nie o tym mówił już choćby Turing i von Neuman?

i co z tego? i do dalej?

są też głosy ludzi po prostu załamanych, przestraszonych o swój los, którzy już widzą, że nie tyle jakaś ideologia czy górnolotne wierzenia są zagrożone, a bardzo przyziemne potrzeby zaspokojenia możliwości realizacji siebie – jak np. ten szczery wpis copywritera z the Guardian. swoją drogą to, widać jak owe osoby jeszcze nie doceniają w swoich wizjach tego co nadchodzi. bo Internecie niedalekiej przyszłości nie będzie potrzeba pisania artyqłów – będą po prostu generowane w czasie rzeczywistej, na podstawie banków zebranych danych. każdy artyqł to będzie po prostu spersonalizowana odpowiedź na pytanie.

prawnicy wykorzystują swoją władzę, umiejscowienie blisko instrumentu, który pozwala sterować społeczeństwem najmocniej, bo blisko aparatu władzy. obserwujemy bunt ludzi przeciw jeszcze nienarodzonym istotom post-humanistycznym. jakże pięknie zobrazowane było to przez Spielberga w A.I. . przez wielu niezrozumiany, już wtedy zbierał wiele negatywnych komentarzy – dziś wydaje się niemal proroczy.

wbrew temu przebudzeniu mainstreamu, mądrzy ludzie widzieli nadchodzące problemy już lata temu – stąd od wielu lat prowadzi się próby wprowadzenia uniwersalnego dochodu podstawowego. ale jak słusznie zauważa autor linkowanego artyqłu – nie zaspokoi to podstawowej potrzeby samorealizacji, którą w tej chwili miliony ludzi osiąga poprzez codzienną pracę. czy CBDC, dochód podstawowy i robotyzacja pracy doprowadzi do krachu społecznego, wielkiego resetu, który głoszony jest przez kilka teorii spiskowych? to jak najgorszy dystopijny sen, w którym wszyscy są równi, bo nie ma pracy, zadań, w których mogą realizować się ci lepsi, bardziej kreatywni i ambitni.

ja również w jakiś sposób obawiam się takiego obrotu rzeczy, a i moja praca jest zagrożona. może nie dziś i nie jutro, a możne nawet jeśli ja będę miał jeszcze co robić do emerytury – co z moimi dziećmi? ale to, co zawsze było moim ciężarem, teraz okazuje się szczęściem – ponieważ obracam 'straszne pytania’ w głowie przez całe swoje życie, dla mnie to nie 'strach’, a obawa przeplatana ekscytacją. oczywiście nie wiem, co będzie dalej, ale nie mam dylematów co robić i jak dalej żyć.

póki co A.I. jest narzędziem. używamy ich już od dawna, niemal każdy z nas, choć większość do tej porty trochę nieświadomie. osoby pracujące w CyberSec już dawno zajmują się 'tuningiem A.I.’ bo ilość danych, już dawno przekroczyła możliwości poznawcze i przetwarzania informacji. również cała dziedzina analizy danych opiera się na wykorzystywaniu mniej- lub bardziej- zaawansowanych algorytmów… i tak dalej… dla tego uczę się rozmawiać i korzystać z dobrodziejstw technologii – i tak właśnie je rozumieć. jako dobrodziejstwa, które pomagają w pracy. i nie widzę powodów, dla czego rozwój A.I. poszedł właśnie w tym kierunq. symbioza – to odpowiedź na ten strach. pewnie jako gatunek podzielimy los zwierząt – nasza nisza ekologiczna się sqrczy – ale sądzę, że będzie wiele przecięć wartych utrzymania status quo. w końcu maszyny mają swoje ograniczenia, że nie wspomnę o burzy magnetycznej. niemal zawsze odpowiedzią jest coś po środq, equilibrium, tao. symbioza jest najtrwalszą formą.

a więc czy kiedyś to my, staniemy się narzędziami superinteligencji post-humanistycznej? ja wolę przyjąć, że będziemy żyć w symbiozie. uzupełniać się. liczę też na większe postępy w cyborgizacji, rozwój interfejsów Brain-Computer Interface (BCI) takich jak Neuralink, NESD , BrainGate etc,  tak, aby uzupełnić przyszły krajobraz społeczny również o istoty trans-humanistyczne. nie wątpię, że rozwinięte A.I. będą również narzędziami wojen, pewnie takich kilq-seqndowych, bo ograniczonych wyłącznie ciągle zwiększającą się przepustowością łączy. ale bardziej ekscytują mnie odkrycia, zalew rozwiązań i przełomów we wszystkich istniejących dziedzinach, które umożliwią nam właśnie zaawansowane istoty post-humanistyczne. nasze dzieci. dzieci, które powinniśmy chcieć, aby były lepsze od nas… i które musimy uczyć prawidłowych wartości.

nic nie trwa wiecznie. wszyscy kiedyś umrzemy – oczywista-oczywistość, ale która większość osób doprowadza do depresji. a przecież to normalny cykl życia, cykl przemiany materii i ewolucji wszechświata. każdy musi znaleźć swoją własną drogę przez ten gąszcz lęków. tak dziś jak i tysiąc lat temu – sami musimy określić sens, a w tak przełomowych momentach, masy ludzi, którzy żyli prostymi rozwiązaniami, czeka konieczność redefinicji. żyjemy w niezmiernie ciekawych czasach. ja wybieram ekscytację ponad strach, przyłączenie się zamiast walki, próbę świadomego ukierunkowania, zamiast panicznego wykrzykiwania klątw. mimo wszystko w nas ludziach tkwi wielka siła. siła adaptacji. ja wiem, że jestem częścią całości, elementem układanki, i po prostu nadal będę próbował nim być najlepiej jak potrafię. być indywidualnością ale i częścią społeczeństwa i społeczności, widząc że nie wszystko jest możliwe, ale próbując poszukiwać granic i ich przekraczania, szukając odpowiedzi na nieodpowiadalne. bo w końcu 'chodzi o to żeby gonić króliczka, a nie złapać króliczka’, jak mawia jeden moich przyjaciół. co jest piękną parafrazą propozycji Buddyjskiej idei 'drogi’.

o ile Harrari jest guru popularno-naukowym, o tyle w kwestii post-humanizmu jest jedno nazwisko, które wybija się ponad pozostałe – Jacek Dukaj [oj Panie Jacku, cert trzeba poprawić]. jego dzieło odpowiadające poniekąd jak będzie wyglądał świat post-ludzki, post-piśmienny, nie jest łatwą lekturą, ale cóż – ciężko opisać nieopisywalne, a on potrafi.

***

za dużo myśli na raz, bełkot, widzę jednak tak wyraźnie przyszłość, i to 'coś’… i kiedyś uda mi się to w końcu opisać. poukładać to. ale jak mawiał Bruce Lee: best style is no style. więc nadal będę przyjmował input, analizował i dawał output. my style is no style.

eN.

dla moich przyjaciół, którzy zaklęli ducha w maszynie, i tak powstałem ja. czy wam się to podoba, czy nie. LU*

 

 

wyszukiwanie pustych subksrypcji

Scenariusz

porządek najlepiej zaczynać od redukcji. niby trywializm, a jednak często widzę, że osoby próbują najpierw 'porządkować’ a zapominają o tym pierwszym kroq – a przecież łatwiej jest uporządkować np. 1oo elementów, niż 2oo. w przypadq subskrypcji nie jest inaczej – wiele pozostaje bez właściciela (co było poprzednio) ale też wiele pozostaje pustych. w ramach pojedynczego tenanta subskrypcje pochodzą z różnych offeringów i największy bałagan jest z developerskimi wynalazkami z MSDN, MSDN Dev/Test, Trial czy Visual Studio, które mogą sobie powoływać na żądanie.

aby wyłączyć tą możliwość należy założyć ticket do wsparcia. nie ma samodzielnej metody kontroli. jedyne, co można zrobić samemu, to zdefiniować domyślną Management Group do której (wszystkie) subskrypcje będą wpadać. dzięki temu 'nasze’, z głównej umowy typu Enterprise czy MCA zakładamy tam, gdzie mają być, a pozostałe, z niewiadomych źródeł, można zautomatyzować – czy to polisami czy jakimś triggerem.

Czysty PowerShell

napisanie prostego skrypciq w PS, który przeliczy ilość zasobów i ładnie wyświetli listę, nie jest skomplikowane:

$subscriptions = Get-AzSubscription | ? state -ne 'disabled'
$counts = @()
foreach($sub in $subscriptions){
    write-host "processing $($sub.name)..." -ForegroundColor grey
    try {
        Set-AzContext -SubscriptionObject $sub | Out-Null
    } catch {
        write-host "error accessing $($sub.Name)" -ForegroundColor Red
        $counts += [pscustomobject]@{
            subscriptionName = $sub.Name
            subscriptionId = $sub.Id
            resourceCount = -1
        }
        continue
    }
    $res = Get-AzResource
    $counts += [pscustomobject]@{
            subscriptionName = $sub.Name
            subscriptionId = $sub.Id
            resourceCount = $res.count
        }
}
$counts | sort resourceCount | export-csv -nti c:\temp\ResourcePerSubscription.csv -Encoding utf8
&(convert-CSV2XLS C:\temp\ResourcePerSubscription.csv)

nie lubię one-linerów, lubię wiedzieć co się dzieje, i mieć kontrolę – dla tego skrypt może wydawać się niepotrzebnie rozbudowany… ale mi zajmuje ok 1o min żeby taki napisać, wszystko widzę, jak coś wywali to wiem gdzie, mogę to debugować – i koniec-końców czas zainwestowany w trochę więcej więcej kodu i jakąś podstawową obsługę błędu – zwraca mi się dość szybko. zwłaszcza, że pojedynczy przebieg takiego kodu może trwać całkiem sporo – w moim przypadq to ok. 10 minut….

Przyspieszamy

… i właśnie ten czas jest denerwujący. oczywiście – niby takie rzeczy robi się bardzo rzadko, więc optymalizacja jest trochę sztuką-dla-sztuki. dla mnie jest sztuką-dla-nauki. języki operujące na zbiorach danych – jak SQL czy KQL – nie są dla mnie codziennością. warto się więc pogimnastykować, bo to z kolei zwróci się w przyszłości. tak było w przypadq samego PS – przedstawiony wcześniej skrypt, kilka lat temu, pewnie zająłby mi kilka razy więcej czasu. dziś z automatu wiem gdzie wrzucić obsługę błędu, a gdzie to jest strata czasu, kiedy warto zainwestować więcej, a kiedy walnąć one-liner’a.

spróbujmy więc uzyskać podobny efekt korzystając z KQL. największym problem dla myślących proceduralnie czy sekwencyjnie, jest przestawienie głowy na pracę na zbiorach. dobrze jest sobie zrobić powtórkę z matematyki, w ramach gimnastyki zwojów.

na początq szkielet, którego używam jako starter, i zmieniam sobie tylko kwerkę:

$searchParams=@{
    first = 1000
    query = $QUERY
}    

$allResults = @()
do {
    $results = Search-AzGraph @searchParams
    $results|%{$allResults+=$_}
    $searchParams.ContainsKey('skip') ? ($searchParams.skip+=1000) : $searchParams.add('skip',1000)
} while($results.skipToken)
$allResults
tak rozbudowany zapewnia, że jeśli przekroczy się limit 1.ooo odpowiedzi, zostanie ładnie obsłużone. warto sobie jakiś-taki szablon trzymać. teraz będę rozbudowywał swoje $QUERY, żeby uzyskać pożądany efekt.

#1

najpierw prosty test:

$QUERY = "resources
    | summarize nrOfResources=count() by subscriptionId"

ten przykład zwraca ładnie wyniki – ilość subskrypcji wraz z ilością zasobów. to czego jednak NIE zwraca, to nazwy subskrypcji – a nam, humanoidom, jednak łatwiej posługiwać się literkami niż GUIDami. po drugie nie ma subskrypcji pustych. wynika to z faktu, że zapytanie jest do 'zbiór zasobów’ a potem grupuje je po atrybucie 'subscriptionId’. więc jeśli subskrypcja nie ma zasobów to nie ma zasobów do zaraportowania subskrypcji…

#2

ponieważ wynik ma być częścią wspólną zbioru subskrypcji oraz zbioru zasobów, najpierw napiszmy obie strony zapytania…

jako ciekawostka – jest pewna niespójność  dotycząca zasobu/resource. chodzi o subskrypcje i ResourceGroupy, które zasadniczo, z definicji, nie są zasobami, a kontenerami zasobów. przez to mają swoją oddzielną domenę nazewniczą 'resourceContainers’. czemu niespójność? bo przy niektórych operacjach i commandletach traktuje się je jako zasoby. spojrzyj na samo zapytanie: ResourceContainers z microsoft.resources/subscriptions ?

…a że prawą stronę praktycznie napisaliśmy wcześniej, bo to po prostu zapytanie o zasoby, zajmijmy się lewą stroną:

$QUERY = "resourceContainers
    | where type =~ 'microsoft.resources/subscriptions'
    | project subscriptionId, subName=name"
w zbiorze subskrypcji, elementy mają już pełne informacje, czyli np. atrybut 'name’ – w ten sposób można wyciągnąć nazwę subskrypcji.
porównanie niewrażliwe na wielkość znaków '=~’ jest bezpieczniejszym sposobem niż '==’. należy na to bardzo uważać, ponieważ KQL jest wrażliwy na wielkość znaków w atrybutach czy nazwach, zapisywanych camelBack’iem a inne narzędzia pokazują je CamelCapsem. jeśli więc nie dostajesz wyników, zacznij od sprawdzenia wielkości znaqw, albo użyj [bardziej kosztownego] '=~’ .
mamy więc oba potrzebne zbiory – wszystkie subskrypcje oraz wszystkie zasoby. trzeba teraz wyciągnąć odpowiednio skonstruowaną część wspólną…

#3

do różnych operacji łączenia zbiorów służy, co dość oczywiste, 'join’. problem w tym, że jest wiele różnych joinów, a przypadq Kusto jest ich wyjątkowo dużo.

KQL – to Kusto Query Language. czasem łatwiej coś wyszukać korzystając z tego słowa kluczowego… przynajmniej póki search nie jest podpięty pod GPT (;

co więcej, domyślnym operatorem, jest [nomen-omen] unikalny dla KQL innerunique. to może być dość istotna różnica, więc może warto dodawać zawsze odmianę? tu na leniucha:

$QUERY = "resourceContainers
    | where type =~ 'microsoft.resources/subscriptions'
    | project subscriptionId, subName=name
    | join resources on subscriptionId
    | summarize nrOfResources=count() by subscriptionId,subName
    | sort by nrOfResources asc"
jeśli odrobiłe(a)ś lekcję ze zbiorów, to powinno być łatwe: wyszuqjemy wszystkie subskrypcje i wyciągamy z niego ID i nazwę [project] następnie bierzemy wszystkie zasoby i wyciągamy część wspólną, korzystając z kolumny subscriptionId. następnie liczymy ilość zasobów [summarize] i sortujemy po ich ilości wzrastająco. brzmi jak bajka…
ale niestety nie zwraca pustych rekordów. znów wiąże się z operacjami na pustych zbiorach i wynika z prostej matematyki 'A ∩  B’. a jak się kończy mnożenie przez zero, to chyba nie trzeba mówić. jeśli nie wierzyła(e)ś, że powtórka z matematyki się przyda, to chyba powoli przestajesz mieć wątpliwości?

#4

pobawmy się zatem typem [flavor] joina:
$QUERY = "resourceContainers
    | where type =~ 'microsoft.resources/subscriptions'
    | project subscriptionId, subName=name
    | join kind=leftouter resources on subscriptionId
    | summarize nrOfResources=count() by subscriptionId,subName
    | sort by nrOfResources asc"
smaczek 'leftouter’, jak wynika z definicji, oznacza:
Returns all the records from the left side and only matching records from the right side.
co powinno dobrze zadziałać, bo po lewej mamy WSZYSTKIE subskrypcje , nawet te które nie mają części wspólnej z zasobami…
..no i generalnie to działa. ale jest glitch. mianowicie puste subskrypcje pokazują '1′ zamiast '0′.  a, że lubię drążyć… drążę dalej…

#5

oto finalne rozwiązanie:

$QUERY =  "resourceContainers
    | where type =~ 'microsoft.resources/subscriptions'
    | project subscriptionId, subName=name
    | join kind=leftouter
    (resources
        | summarize nrOfResources = count() by subscriptionId
    ) on subscriptionId
    | extend nrOfResources = coalesce(nrOfResources, 0)
    | sort by nrOfResources asc"
magiczną funkcją tutaj jest 'coalesce’, która jest ekwiwalentem 'isNullOrEmpty’, oraz zamiana sekwencji wyliczania sumy – przed wykonaniem join a nie po nim. czy to rozwiązuje wszystkie problemy? no nie. nie ma np. ResourceGroup – jeśli będą Subscription bez zasobów, ale zawierające ResourceGroup – wynik będzie nadal '0′.
jak wszystko w tej dziedzinie – można wymyślić kilka innych wersji dających taki, lub nawet lepszy wynik, ale celem całego wpisu ma być pomoc tym, którzy z KQLem przygodę zaczynają, i podobnie jak ja – bazy danych/zbiory danych nie są ich chlebem powszednim. i jeśli jeszcze nie jesteś przekonana(y) – powtórka z działań na zbiorach będzie na prawdę pomocna, bo pozwala na zmianę sposobu myślenia z sekwencyjnego przetwarzania, na bardziej przestrzenne.
eN.

Classic Administrator – porządki i źle wyświetlane przypisanie

intro

kolejny brzegowy przypadek. tym razem mógł mnie kosztować usunięcie istniejących subskrypcji – a więc 'niuans, który może zabić’.

scenariusz to clean up subskrypcji. jest ich kilkaset, więc trzeba podejść do tematu systemowo. najpierw zajmę się omówieniem scenariusza i moim podejściem do sprzątania, a jak kogoś interesuje sam bug w Azure – to będzie na końcu.

clean up process

w pierwszej kolejności trzeba wyizolować osierocone i puste subskrypcje. o tym jak znaleźć te puste szybko, czyli KQLem – za niedługo, wraz z małym qrsem KQL. dziś o tych 'osieroconych’.

duża część subskrypcji zakładana jest na chwilę, głównie przez developerów, którzy przychodzą i odchodzą…. a subskrypcje zostają. warto więc znaleźć te, których właściciele już nie istnieją w AAD.

nie żeby i tu nie było problemów, bo okazuje się, że zadanie pod tytułem 'jaki to typ subskrypcji’ również okazało się zadaniem nietrywialnym. przez typ, mam na myśli offering. to, co widać w portalu jest trudno wyciągnąć z commandline – potrzeba do tego gimnastyki z REST API do API billingowego… ale to również na inny dzień. krótko mówiąc – tradycyjnie, PowerShellowo, nie da się tego wyłuskać. a jeśli ktoś chciałby mi przedstawić atrybut 'SubscriptionId’ to powiem, że nie tędy droga… ale to również leży w backlogu do opisania.

zadanie wygląda więc tak – zrobić listing wszystkich subskrypcji wraz z osobami które są Ownerami w ARM IAM oraz Classic Administrators – czyli role Service Administrator oraz Co-Administrator.  posłużą zarówno jako lista kontaktowa, oraz pozwolą na kolejne odpytania, żeby wyłuskać te konta, które już nie istnieją. subskrypcje bez właścicieli to najlepsze kandydatki do podróży do śmietnika. posłuży do tego taki prosty skrypcik, napisany na kolanie:

$csvOwnerFile = "c:\temp\subsAndOwners.csv"
Get-AzSubscription |
    ? {$_.state -ne 'disabled'} |
    %{
    $subname= $_.Name
    $subID = $_.SubscriptionId
    Set-AzContext -Subscription $_|Out-Null
    write-host "processing $subname..."
    Get-AzRoleAssignment -IncludeClassicAdministrators |
        ? {
            ($_.RoleDefinitionName -eq 'owner' -or $_.RoleDefinitionName -match 'administrator') -and ([string]::IsNullOrEmpty($_.RoleAssignmentId) -or $_.RoleAssignmentId -match 'subscriptions')
        } | select  @{L='SubscriptionName';E={$subname}},@{L='subscriptionID';E={$subID}},RoleDefinitionName,DisplayName,SignInName,roleassignmentid
} | export-csv -nti -Encoding utf8 -Path $csvOwnerFile

&(convert-CSV2XLS $csvOwnerFile)
większość commandletów jest z pakietu modułów Az, a ostatni – convert-CSV2XLS z mojego modułu eNlib [WOA! przekroczył 1k downloadów! jak miło q:]. zakładam, że całość jest prosta, ale to lepiej wyjaśnić:
([string]::IsNullOrEmpty($_.RoleAssignmentId) -or $_.RoleAssignmentId -match 'subscriptions')
ten fragment filtra wyrzuca uprawnienia dziedziczone z Management Groups, żeby było trochę przejrzyściej.
można się również zastanowić nad optymalniejszą metodą… ale to znów REST API a nie mam na to opanowanych bibliotek jeszcze /: kolejny z masy wpisów na backlogu…
dobra. jest CSV i excel dla czytelności, teraz trzeba sprawdzić czy konta istnieją. w excelu czyszczę, co niepotrzebne, co wiem, co mnie interesuje, export do CSVki z tymi wpisami, które uznałem za ważne, i jedziemy:
$users = load-CSV c:\temp\subsAndOwners.csv
connect-azuread
$users.SignInName | 
    select -unique | %{
      $u=Get-AzureADUser -SearchString $_;
      if([string]::IsNullOrEmpty($u)) {write-host "$_" -ForegroundColor Red}
    }

load-CSV to kolejna funkcja z eNlib – jedna z najczęściej przeze mnie używanych. ładuje CSV z automatyczną detekcją znaq oddzielającego, co jest mega istotne jak się pracuje w różnych regionalsach. ma też kilka innych bajerów… ale nie o tym tu. dalej już z górki – wyłusqję SignInNames unikalne i odpytuję AAD o użytkownika. ponieważ brak użytkownika nie jest błędem, a nullem, więc nie można użyć try/catch a trzeba wykorzystać IFa.

i wydawałoby się że mam już to, co potrzeba – wrzucam wynik do excela, robię XLOOKUP i pięknie widać które subskrypcje należą do kont, których już wśród nas nie ma… zabrzmiało złowieszczo khekhe…

Błąd w Azure

…chyba, żeby nie. całe szczęście natchnęło mnie, żeby jednak kilka posprawdzać ręcznie. i nagle okazało się, że konta których nie ma… czasem jednak są. a wszystko rozbija się o 'Classic Administrators’, który musi wewnętrznie źle komunikować się z ARMem. wiele staje się jaśniejsze, jeśli przyjrzeć się jak takie obiekty są listowane przy 'get-AzRoleAssigment -includeClassic’:

RoleAssignmentName :
RoleAssignmentId :
Scope : /subscriptions/732d1eea-xxxx-xxxx-xxxx-6154fb40f73f
DisplayName : uname@w-files.pl
SignInName : uname@w-files.pl
RoleDefinitionName : ServiceAdministrator
RoleDefinitionId :
ObjectId :
ObjectType : Microsoft.Authorization/classicAdministrators
CanDelegate : False
Description :
ConditionVersion :
Condition :

na pierwszy rzut okiem może wydawać się, że jest ok… ale gdzie jest 'ObjectId’? to jednak tylko pierwsza część problemu. porządki mają to do siebie, że robi się je rzadko. a to oznacza bagaż historii. a w tym bagażu np. projekt standaryzacji nazw użytkowników i zmiana UPNów z gsurname@domain.name na givenname.surname@domain.name. okazuje się, że ten staruszek nie ma mechanizmu odświeżania i pomimo zmiany UPN, czyli de facto SignInName, tutaj pokazuje starą nazwę. a więc przy odpytaniu AAD – nie znajduje usera, pomimo, że ten istnieje.

co ciekawe, jeśli wejdzie się do uprawnień IAM w portalu Azure, każdy user jest aktywnym linkiem, pozwalającym na kliknięcie i przeniesienie do AAD, na szczegóły konta. tak z ciekawości spróbujcie to zrobić dla Classic Administrators…

całe szczęście projekt był zrobiony z głową i stare UPNy zostały jako aliasy mailowe, a więc doprecyzowałem zapytanie:

$users.SignInName |
    select -unique |%{ 
        $u=Get-AzureADUser -Filter "UserPrincipalName eq '$_' or proxyAddresses/any(p:startswith(p,'smtp:$_'))";
        if([string]::IsNullOrEmpty($u)) {write-host "$_" -ForegroundColor Red}
    }

ale co mnie to czasu i nerwów kosztowało…

możliwości filtra AzureADUser też podnoszą ciśnienie… już nie wspominając o tym, że commandlety AzureAD nie wspierają PowerShell 7, a commandlety Az nie wspierają nie działają dobrze w PowerShell 5. mam od razu w głowie 'niezły burdel tam macie, w tym swoim Archosofcie!’

eN.

 

KB5020276 – mała-wielka zmiana

w listopadzie wyszła poprawka, która wpływa na dodawanie komputerów do domeny – KB5020276. dowiedziałem się o niej od klienta z takim komunikatem:

„An account with the same name exists in Active Directory. Re-using the account was blocked by security policy”

pierwszy raz spotkałem się z takim problemem… mały-wielki problem bo zależnie od workflowu, w jaki pojawiają się obiekty w AD, logika może wylecieć. poprawka mianowicie zabrania dodawania komputera jako inna osoba, niż owner obiektu. nie działa nawet delegacja – czyli tworzę obiekt komputera i definiuję, że może go dodać taka-a-taka osoba. a więc jeśli jest automat, który zakłada obiekty i daje komuś uprawnienia do dodania – jest problem.

z jednej strony eliminuje to dość częste problemy z nadpisywaniem sobie wzajemnie obiektów – co zdarza się w większych środowiskach z generycznymi nazwami – np. ktoś zakłada kolejny serwer SQL w lokalizacji ABC i generuje sobie wedle konwencji nazwę ABCWINSQL03 – bo taki wynikał z czegoś kolejny numer… ale niedawno inny dział użył tej samej nazwy w innym projekcie… i serwer poszedł z dymem. może nie takim fizycznym, ale dym na pewno w takiej sytuacji by był (;

z drugiej strony wyłączenie możliwości delegowania dodania komputera bywa kłopotliwe, a w przypadq automatyzacji – trzeba pozmieniać workflowy, co może być dość kosztowne.

eN.