Skip to Content

IT nieuczesane.
category

Category: DevOps/Scripting

skrypty, programy, command line i inne

statystki na Exchange 2o1o

2014-08-07 15_18_56-statistics - Szukaj w Googletrochę na temat statsów na Ex2kd. że PowerShell wymiata to już pisałem wiele razy, ale nie omieszkam jeszcze wiele napisać. „PowerShell wymiata„. wszystko co kiedyś było bardzo trudne, w porywach do niemożliwe i wymagało jakiejś tajemnej wiedzy – teraz leży okrakiem – nic tylko brać (; w przypadq Exchange trochę tajemnej wiedzy jest potrzebne żeby dobrać się do danych prawidłowo – w innym przypadq można ominąć ważne części. a w końcu w statystykach chodzi o dokładność.

najpierw kilka najprostszych poleceń do statystyk:

to jednak polecenie bardzo wredne i ma swoje humory. i to poważne. na początek fakt, że w środowisq wielodomenowym nie są przeszukiwane wszystkie domeny. wychodzą z tego niewidzialne skrzynki. sprawdzić to można:

chodzi konkretnie o parametr ‚ViewEntireForest’ który baj difolt jest ustawiony na $false. dość dziwne jest dodatkowo to, że nawet jak się go przestawi na $true, to potrafi wrócić, z niewiadomych względów, do ustawienia standardowego /: więc jeśli skrzynki znaleźć nie można, warto go sprawdzić.

set-ADServerSettings -ViewEntireForest $true

kolejną ciekawostką jest to, że to polecenie zwraca statystyki *wszystkich* skrzynek. że to przecież dobrze? no nie koniecznie – jeśli wykonuje się jakieś ruchy, przenosi się skrzynki między bazami, to taka skrzyneczka jest de facto kopiowana, a jej cień zostaje w bazie danych aż do czasu osiągnięcia czasu retencji. trzeba zatem takie skrzynki odfiltrować, a odpowiada za to parametr ‚disconnectDate’ – jeśli wartość jest $null, to znaczy, że skrzynka nie jest odłączona, to znaczy że jest dobra. wiedząc to, można sprawdzić zarówno ile zajmują skrzynki ale również ile miejsca się marnuje – odłączone mailboxy można wywalić przed czasem retencji. dodatkowo, ponieważ interesują nas wielkości, a te nie są standardowo wyświetlane, warto użyć ‚select’:

 

jeśli interesuje nas suma, to trzeba to sobie pododawać za pomocą ‚measure’ ale to za chwilę. najpierw zagadka – czemu to polecenie nie zadziała zgodnie z oczekiwaniami? otóż sortujemy po wielkości, a te zwracane są w różnych jednostkach – MB, GB, PTB [to skrzynka CEO (; ], więc 3MB będą większe od 1GB. trzeba zatem wykonać trochę matematyki:

i to niestety nie koniec. jednej rzeczy nie udało mi się odkryć. otóż po usunięciu skrzynki użytkownika i założeniu mu nowej, disconnectDate pozostaje $null /: a to oznacza, że cały czas pojawia się w statsach. za to mniej grymaśne jest polecenie get-mailbox a więc jeśli nie interesuje nas zużyte miejsce przez nieistniejące skrzynki, najlepiej korzystać od tej strony:

jeśli nie interesują nas poszczególne skrzynki a bardziej wielkości całych baz:

a co do mierzenia całej wielkości, to już odeślę do zewnętrznego wpisu, gdzie jest bardzo ładna i prosta funkcja, która to realizuje.

eN.

replikacyjna magia

są takie, jak to ktoś kiedyś pięknie przetłumaczył, dziwnostki. jak się na taką trafi to jak los w antylotto. właśnie straciłem 3h na debugowaniu takiego wynalazq z programu „niedowiary”. napisałem sobie skrypt, który sprawdza wszystkie hosty na SCVMM a potem odpytuje je o status replikacji i wysyła go mailem. działa ślicznie – jak odpala się z konsoli.

…wrzucam jako zadanie task scheduler… skrypt niby się odpala, ale wyraźnie coś nie do końca, bo output jest niepełny. zajmuje mi chwilę, żeby zawęzić niedziałanie do komendy get-vmreplication – najwyraźniej się wywala /: testowałem wszystko – sprawdzałem kontekst wywołania, poprawność skryptu, nawet szukałem pod względem tego, czy może get-vmreplication z jakiś powodu nie działa jako zadanie kalendarza. w końcu postanowiłem przejść do podstaw – wycinając cały skrypt i zostawiając tylko to jedno polecenie, w różnym kodowaniu – ANSI/UTF8. dupa. nadal zmienna jest pusta

w końcu założyłem nowy task i… działa! no więc odtwarzam pełną definicję zadania… znów nie działa @_@ o co qrva c’mon?!

teraz już szybkie testy i oto przed państwem dziwny, przedziwny, niewytłumaczalny wynik:

jeśli w trigerze taska ustawiona jest opcja „Stop task if it runs longer then” – get-vmreplication nic nie zwraca

sprawdzałem dla różnych wartości, i nie ważne, że sam task jest odpalany ręcznie /: cuda na kiju. nie testowałem na innych serverach – u mnie to jest w2k12 standard z SCVMM.

spis IP

***UPDATED

scenariusz: jest lista nazw komputerów, trzeba rozwiązać adresy IP. warunek konieczny – odpowiednie wpisy w DNS.

dla widoczności oneliner rozbity na kilka linijek:

podstawa to wyrażenie regularne. krótkie wyjaśnienie:

  • adres IPv4 to 3 cyfry, kropka … 3 cyfry. „[0-9]+” oznacza „wystąpienie dowolnej cyfry raz lub więcej”.
  • kropka jest znakiem specjalnym w wyrażeniach regularnych więc musi być wyeskejpowana – „\.”.
  • metoda Matches zwraca tablicę wyników, więc trzeba wybrać pierwszą wartość – stąd pojawia się „[0]” – jako pierwszy element tablicy.
  • no i na końcu wybranie atrybutu ‚value’, ponieważ każdy rekord tablicy Matches zawiera kilka atrybutów a tu chodzi konkretnie o wartość.

udpate:

Player uzupełnia, że prawidłowy zapis dla adresu IP powinien wyglądać „[0-9]{1,3}” a nie + bo w końcu może być tylko od jednej do trzech cyfr. w tym przykładzie nie ma to znaczenia, bo ping nie zwróci raczej nieprawidłowego adresu, ale lepiej pisać dobrze (:

Paweł pokazuje, że lepiej niż pinga użyć commandletu ‚test-connection‚ i się nie bawić w wyrażenia regularne.

eN.

PS: console … and beyond

jeśli mój pomysł z PowerPresentation wydaje się abstrakcyjny… to co powiedzieć o pisaniu gry w PS? (;

eN.

split, tablice, X400 i jeszcze więcej

scenariusz: w atrybucie proxyAddresses w AD użytkownicy mają wpisane nieużywane adresy X4oo, które trzeba było usunąć. prościzna… przynajmniej tak mi się wydawało. sporo ciekawych drobiazgów przy tym wyszło i zadanie, które oceniałem na 15-2o min zajęło mi ze 2h /:

a takież to ciekawostki powychodziły…

najpierw trzeba wyszukać wszystkie obiekty [user/contact], które mają w proxyaddresses X400. szczęśliwie filtry są na tyle sprytne, że radzą sobie z multivalue [zaraz napiszę jak to robią] i nie trzeba się męczyć z jakimiś konwersjami:

w ‚normalnym’ języq, trzeba by się pomęczyć najpierw wyszuqjąc wszystkie obiekty posiadające wartość proxyaddresses, potem konwertując tablicę do stringa, a potem sprawdzić czy w tym stringu jest wartość x400 – bo w ‚normalnym’ języq świat nie jest tak prosty (;

proxyaddresses jest tupu ‚mulivalue’ czyli jako parametr przyjmuje tablicę stringów i z tejże tablicy trzeba usunąć linijkę, która zawiera wartość ‚x4oo’. wartość można łatwo odczytać, ale jak z tej tablicy wywalić ową linijkę?i tutaj czas na wyjaśnienie, jakim cudem filtr zadziałał dla tablicy tak, jakby to był pojedynczy string. spróbuję to zobrazować na trochę prostszym przykładzie:

na powyższym przykładzie widać, że po zdefiniowaniu tablicy i sprawdzeniu jej typu przy pomocy get-member, PS traktuje ją jak zwykły string…  jeśli jednak sprawdzi się typ zmiennej….

choć nieco dziwne, to wiele ułatwia. pozostaje jednak nadal pytanie – jak łatwo usunąć element z tablicy stringów? można kombinować z metodami replace i remove, które tu zadziałają jak dla zwykłego stringa, ale dają średnie rezultaty. dużo ciekawszym sposobem jest metoda remove, dla klasy ArrayList.

na koniec jeszcze jedna ciekawostka. zanim wpadłem na konwersję do ArrayList, kombinowałem z przepisaniem zmiennej do drugiej tablicy i próbowałem wycinać z niej wartości na różne sposoby.  tak trafiłem na kolejną ‚ciekawostkę’ – w cudzysłowiu, bo de facto taki sposób działania jest normalny dla środowisk obiektowych: powiązanie zmiennej z atrybutem obiektu jest robione przez referencję a nie jest ona kopiowana. taki jakiś niedziałający kod:

podczas działania dostawałem taki błąd:

An error occurred while enumerating through a collection: Collection was modified; enumeration operation may not execute..At D:\ISCG\scriptz\cleanX400.ps1:11 char:16
     +         foreach <<<< ($p in $_.proxyaddresses) {
+ CategoryInfo          : InvalidOperation: (System.Collecti…numeratorSimple:ArrayListEnumeratorSimple) [], RuntimeException
+ FullyQualifiedErrorId : BadEnumeration

kolekcja została zmodyfikowana… i faktycznie – kiedy sprawdziłem modyfikacje na $newpa, wyświetlenie $_.proxyaddresses je odzwierciedlało. wniosek – z obiektami nie ma żartów, trzeba uważać (;

na koniec jeszcze jedna metoda usuwania konkretnej linii a tablicy stringów, która jednak mi się nie przydała, ponieważ trzeba znać index. załóżmy, że chcę usunąć 4tą wartość:

reasumując – atrybuty zostały poprawione, a te 2h nie poszły na marne – rozumiem bardziej ^^

eN.

 

przerwane dziedziczenie

***updated

migracja gównianej macierzy publikowanej via SMB. ADMT nie obsługuje dysqw sieciowych. jak sprawdzić na których katalogach zerwane jest dziedziczenie? może jakiś tool z netu? może jakiś super-skomplikowany kod? a może po prostu szybki test w PS ^^

wyszukaj wszystkie obiekty potomne, wybierz katalogi, wybierz te, które mają wyłączone dziedziczenie:

jakoś tak z przyzwyczajenia używam filtra, który pokazuje tylko katalogi „? PSIsContainer”… przewija się na wszystkich stronach i we wszystkich przykładach… a przecież get-childItem ma parametr -Directory /:

 

eN.

obsługa błędów w PS

obsługa błędów jest niezmiernie istotna – nie tylko ze względu za komunikaty na ekranie [choć i to jest często ważne] ale bardziej na zastosowanie konkretnej akcji zależnie od tego co się dzieje. najczęściej oczywiście stosuje się try/catch, z pewnymi niuansami, o których trzeba pamiętać i o czym już pisałem. są niemniej przypadki, w których obsługa błędów nie jest taka trywialna zwłaszcza, jeśli korzysta się wewnątrz skryptu z zewnętrznych narzędzi/aplikacji. dla tego też zawsze bronię się rękami i nogami przed niekoszernymi rozwiązaniami, czasem nadpisując wiele linii kodu, byle tylko nie korzystać z zewnętrznych aplikacji. bywa jednak, że nie ma wyjścia.

takim przypadkiem jest scenariusz, w którym trzeba podmapować rejestr użytkownika aby wykonać jakieś operacje. gdzieś tam udało mi się dogrzebać do artu, w którym ktoś wykonywał ciężkie akrobacje programistyczne, aby obsłużyć to ‚natywnie’ – czyli bez ‚reg.exe’, to już jednak za dużo. nie ma więc wyjścia – trzeba skorzystać z ‚reg load’. problem polega na tym, że reg load nie zwraca konkretnego błędu/informacji. próbowałem przypisywać jako zmienną, przekierowywać do pliq… pustka.

chwilkę mi zajęło, zanim przypomniałem sobie jak to się robiło za króla świeczka – i ta metoda działa tak samo obecnie. a chodzi konkretnie o to, że ‚reg’ wrzuca wszystko na standardowy strumień błędów, więc żeby go przechwycić, trzeba go przekierować na standardowy strumień wyjścia:

jak widać cała tajemnica tkwi w „2>&1”. więcej szczegółów a propos oznaczeń strumieni można przeczytać w about_redirection.

eN.

 

 

 

konQrs WGUiSW

zgodnie z zapowiedziami – po 3ciej części mini-serii dotyczącej PowerShell na WGUiSW rozpoczyna się konqrs, w którym do wygrania będzie na szczurach pędzona woda ognista (12to letni chivas). zasady konkursu są proste:

  • celem jest napisanie funkcji efektów dla silnika PowerPresentation czyli:
    • trochę zabawy nad niekonieczną rzeczą
    • dobry powód do nadrobienia zaległości z PS albo pouczenia się trochę
  • oceniane będą:
    • poprawność – czy funkcja napisana jest poprawnie, czyli ma odpowiednie deklaracje, opisy itd
    • fajność – czyli czy efekt robi wrażenie
    • kompatybilność – będzie wymagał możliwie mało zmian w kodzie głównym *[dalej napiszę o co cho]
  • oceniał będę ja, czyli nExoR, na podstawie subiektywnej oceny.
  • kod PP wraz z prezentacjami WGUiSW jako przykłady można zassać stąd.
  • efekty należy tworzyć jako oddzielne pliki zawierające funkcje efektów z podwójnym rozszerzeniem – .ppe.ps1 . takie pliki są automatycznie dot-soursowane przez PP
  • kod można przesyłać na mój adres nexorek[at]gmail.com do końca maja
  • wyniki zostaną podane na kolejnym WGUiSW – o3.o6.2o14

PowerPresentation to skrypt, który wyświetla prezentacje w hoście PS – ci, którzy uczestniczyli we WGUiSWach mieli okazję go zobaczyć w działaniu. na napisanie go nie poświęciłem jakoś specjalnie dużo czasu – chodzi o zabawę, więc proszę się nie czepiać kodu. nie pisałem modułu, ponieważ wymagało by to instalacji czy innych wynalazków a chodzi o to, żeby prezentację można było łatwo uruchomić na dowolnym kompie z PS np. z pendrive’a.

PP wykorzystuje prosty plik XML jako wsad prezentacyjny. opis podstawowych tagów znajduje się helpie do funkcji – są to tak nieskomplikowane rzeczy, że nie chce mi się tego opisywać w szczegółach. w razie co zawsze można napisać do mnie maila do wyjaśnię.

domyślam się, że ze względu na prymitywizm kodu niektóre pomysły mogą być nierealizowalne lub wymagałyby potwornej akrobatyki. dla tego dozwolona jest modyfikacja kodu PP ale:

  • zmiany powinny być możliwie niewielkie
  • cała reszta musi działać nawet po zmianach – czyli albo nie mogą one wpłynąć na działanie standardowych funkcji albo trzeba je również poprawić.

wszystkie działające efekty zostaną opublikowane (:

zapis sesji WGUiSW dostępny jest na http://wiki.wguisw.org/ w ramach spotkań 59-61.

DOBREJ ZABAWY! =^.^’=

eN.

 

WTF is OFS?

takie drobne ciekawostki w PowerShell… weźmy prosty operator join:

okazuje się, że można prościej:

druga ciekawostka, to tajemnicza zmienna $ofs:

ciekawe, co? ofs to Output Field Separator – globalna zmienna, która definiuje znak stosowany właśnie przy konwersjach tablicy do stringa. zmienna jest trwała dla całej sesji, czyli każda następna zmiana będzie z niej korzystać.

eN.

migracja, FSP i ogólnie bałagan

przejąłem projekt migracji – konsolidacja struktury domen do nowej, pojedynczej domeny. „wszystko już praktycznie zrobione, będziesz się nudził” – z taką optymistyczną informacją zaczynałem pracę nad zadaniem. z bardzo wielu krzaków, które wyszły, sqpię się nad jedną ciekawostką.

po przejrzeniu zmigrowanych grup okazało się, że część kont jest pokazywana jako konta external. listing członkostwa w grupie ujawniał wpisy typu:

CN=S-1-5-21-2096504233-xxxxxxxxx-944726268-2633,CN=ForeignSecurityPrincipals,DC=target,DC=domain

CN=S-1-5-21-2096504233-xxxxxxxxx-944726268-3498,CN=ForeignSecurityPrincipals,DC=target,DC=domain

Tak są właśnie przechowywane referencje do kont z lasów ztrustowanych. zacząłem więc szukać co to za domena. sprawa prosta, ponieważ zasada jest taka sama jak przy zwykłych SIDach – pierwsza część SID to domainSID. sprawdziłem więc ID wszystkich domen źródłowych [zwykły (Get-ADDomain).domainsid.value] … i okazało się, że takiej domeny nie ma /:

śledztwo. „taaaaakk…hmmm… była kiedyś migracja parę lat temu, tej domeny już nie ma”. tia. ostatnim etapem migracji jest cleanup SIDhistory, którego ktoś nie zrobił. sprawdzam grupy w domenie źródłowej – sweet, tam też członkowie pododawani są przez SIDHistory.

po dalszym przeglądzie okazało się, że w grupach były również konta z domen połączonych trustem nieprzechodnim z domeną źródłową, czyli nierozwiązywalne – kolejna grupa dziwnych FSP. tych niestety nie da się w żaden sposób przenieść chyba, że utworzy się trust z tymi externalami. poznajdywały się również konta CNF [w nowej domenie!] i inne wynalazki. i tak to właśnie się nudziłem…

po pierwsze wniosek/porada: migrację zaczyna się od czyszczenia. nawet jak klient mówi „przenosimy 1:1” – trzeba zweryfikować jak bardzo jest naśmiecone i poczyścić.

po drugie – skrypt, czyszczący FSP

z ciekawostek: do usunięcia usera z grupy korzystając z CN, musiałem użyć ADSI – nie potrafiłem zmusić koszernych cmdletów do obsłużenia CNa.

eN.