Skip to Content

IT nieuczesane.
category

Category: DevOps/Scripting

skrypty, programy, command line i inne

Hyper-v integration services

do tej pory nie miałem problemow z ‘enlightments’ – czyli Integration Services dla systemu operacyjnego do współpracy z Hyper-v. po pierwsze dla w2k3 trzeba było instalować zawsze, po drugie w2k8 i w2k8R2 mają je wbudowane.

jeśli jednak zostawi się standardowe wersje na w2k8 R2 na Hv v3 [czyli na w12] to zaczynają się dziać różne dziwne rzeczy. np. potrafi się wywyalić CSV [w eventlogu wpisy o błędach ze sterownikiem dla vhd], czasem nie działa prawidłowo sieć – mieliśmy teraz guesta, który gubił 4o% pakietów, i inne drobniejsze wypadki. a więc – jest to ważne, aby je zupdateować. a ponieważ od w2k8 są one od razu w systemie, nie zawsze się o tym pamięta. jak hurtem sprawdzić wersje IS na guestach?

dla pojedynczego hosta jest to trywialne:

get-vm |%{ echo "$($_.name) -> $($_.IntegrationServicesVersion)"}

trochę bardziej [ale nie tak znowu bardzo] kompliqje się to na clustrze. można oczywiście ręcznie wykonywać host-by-host ale bardziej pro jest zrobić to jednolinijkowcem (:

wykonanie ‘get-vm –computername <clustername>’ zwróci wyniki wyłącznie z jednego węzła. trzeba więc wylistować węzły i przekazać listę do kolejnego wykonania przytoczonego polecenia:

Get-ClusterNode -cluster <NAME>|%{get-vm -ComputerName $_ |%{echo "$($_.name) -> $($_.IntegrationServicesVersion)" } }

więcej poleceń dla klastrów:

Get-Command -Module failoverclusters

P.S. wychodzi na tym przykaładzie problem, z jakim boryka się cała idea PowerShell – podany przykład działa tylko dla w12. na w2k8 nie ma modułu dla Hv. co prawda jak cluster jest na w2k8 to i nie ma problemu z IS niemniej globalnie, jeśli chce się coś zrobić na Hv na w2k8 to trzeba sobie radzić inaczej – albo via WMI albo instalować moduły z sieci. a jeśli środowisko jest mieszane… zaczyna się robić nieprzyjemnie /:

eN.

Konfiguracja środowiska PowerShell – cz. I. Inicjalizacja.

bez marudzenia więc zamieszczony na blogu technet (; tutaj tylko część nieoficjalna –

Post Scriptum 2.

zabawne… od kilq lat coraz mniej pracowałem z Linuxami i okazało się, że to Linuxy znalazły mnie – po skonfigurowaniu wszystkich opcji, otrzymujemy shell gotowy do pracy zdalnej tak, jak bash+ssh. czuję się trochę jakbym odbył podróż w przeszłość. biorąc pod uwagę masakrę, którą eMeS dokonał z interfejsem, oraz postęp, jaki nastąpił w linii poleceń – można mówić o tym systemie “Winux” (; oczywiście – PS jest dużo bardziej rozbudowany niż bash, obiektowy, zintegrowany via .NET framework z całym systemem i aplikacjami itd… niemniej to swoiste qui pro quo – Linux jest rozpizgany na 4 wiatry, nikt nie ogarnia ilości standardów, dystrybucji, window managerów, standardów pakietowania… i tak dalej. jak teraz rozmawiam z n00bami Linuxowymi to często nawet nie widzą, co to bash.. tylko KDE, gnom albo coś. a okienka eMeSowe nie dość, że przestają istnieć – bo jak tu mówić o ‘okienkach’ skoro na ekranie jest wyłącznie tryb pojedynczego kafelka w full screen – to jeszcze zarządzanie przenosi się do linii poleceń… się porobiło…

następna wersja systemu eMeSa będzie się nazywać nie “Windows 9” a raczej “Tiles One” q:

eN.

życie w skorupce mocy

chodzi mi od dłuższego czasu po głowie art dot. powershell, opisujący jak dobrze żyć z tym wynalazkiem. ponieważ pomysły roją się w głowie do absurdalnych wielkości małej książki czy kompendium, na razie drobny wpis tego, co mi zalega na płacie czołowym. będę wdzięczny za komentarze i linki (:

podstawowy pomysł to konfiguracja środowiska. kiedy pracowałem z Linuxami, spędziłem kiedyś dwa dni na tym, żeby prompt wyświetlał się w odpowiednich kolorach na odpowiednich serwerach. głupota? nie zupełnie. kiedy zaczyna się pracować na zdalnych hostach szybko można zgubic rachubę na którym się jest aktualnie. wtedy takie niuanse grają rolę – bo zrestartować nie-ten-serwer może mieć bardzo niemiłe konsekwencje. ponieważ PS daje możliwości pracy zbliżone do tych z Linuxa [lepsze? gorsze? hmm… inne], pozostaje podstawowe pytanie – jak sobie to wszystko poukładać, żeby pracowało się miło i wydajnie. najważniejsze aspekty:

  • włączenie usługi i credSSP – jedną z najfajniejszych opcji jest remoting, który po odpowiednim skonfigurowaniu jest tak wygodny, jak ssh na Linuxach. żeby jednak to się stało, trzeba go włączyć oraz pozwolić na uwierzytelnienie credSSP, które jest standardowo wyłączone. bez włączenia przekazania credntiali po zalogowaniu zdalnym jest się zsandboxowanym do lokalnego serwera, czyli odpają jakiekolwiek operacje sieciowe. dodatkowo warto na firewallu zrobić wyjątek dla winRM.
  • historia – kolejny ficzer, który radykalnie zmienia komfort pracy z linią poleceń jest historia. genialny wynalazek z basha – ‘!’ – oraz .bash_history to potęga nie do przecenienia. wielokrotnie ratował mi tyłek [samo-dokumentacja], pomagał w śledztwach [po domniemanych włamaniach, czy ‘kto co robił’] i oczywiście przyspieszał normalną pracę. o ile historia w PS jest całkiem fajna, to jest ograniczona do jednej sesji. aby była permanentna – trzeba sobie dokonfigurować.
  • script signing – standardowo nie da się korzytać ze skryptów. trzeba zmienić politykę uruchomienia … albo podpisywać każdy skrypt certem.

te rzeczy mam już zebrane i opisane. te, nad którymi pracuję jeszcze [i liczę na pomoc] to:

  • zbiór dodatkowych aliasów – na razie poza standardowymi, których jest na prawdę wiele, bardzo mi się podoba pomysł ‘ssh –> enter-pssession’… wydaje mi się jednak, że takich dodatków jest więcej
  • własne funkcje – PS bardzo mocno czerpie z pomysłów basha i tak samo można ‘wczytać plik’ za pomocą kropki ‘.’. to otwiera drogę do utworzenia czegoś bardziej zaawansowanego niż aliasy – całe funkcje, które są wczytywane podczas logowania. na razie nie mam pomysłu co z tą wiedzą można zrobić ciekawego.
  • centralne repozytorium skryptów – na to póki co nie mam konkretnych pomysłów. kombinowałem z przekierowaniem katalagoów [folder redirection] ale to rozwiązanie trochę zbyt ‘globalne’. a warto mieć pod ręką zbiór swoich własnych skryptów.
  • w efekcie – dokładny opis co się dzieje podczas uruchomienia PS. zrozumienie tego procesu pozwoli na realizację wszelkich pomysłów:
  • co jest ładowane w jakiej kolejności
  • jak załadować własne fukcje, aliasy i inne
  • automatyczna modyfikacja zmiennych środowiskowych [np. path dla skryptów]
  • globalna historia
  • … i cała reszta.
  • zmiana promptu i kolorów. jedną z najbardziej vq*wiających błędów są te dziwne opcje ze zmieniającymi się wilkościami fontów. raz małe, raz jakieś wielkie… trzeba w końcu ogarnąć skrypt, który będzie to konfigurował i załadować go podczas startu. wraz z kolorami samego okna [ten navy-blue powoduje u mnie problemy ze zdrowiem]
  • pierwsze [włączenie,signing,historia] postaram się wkrótce opisać… jeśli macie inne ciekawe pomysły to zapraszam do współpracy.

    eN.

    powershell – kiedy będzie standardem?

    globalnie – nie prędko. z jednej strony możliwości PS się zwiększają z każdą wersją systemu, z drugiej strony – pozostają bez zmian dla wersji starych. potworny dualizm – jest wiele zapowiedzi, że będzie wycofane wsparcie konfiguracji TCP/IP z netsh, wmic – z drugiej strony po uruchomieniu w12 w wersji core nadal jesteśmy witani CMD – co jest zresztą dla mnie zupełnie niezrozumiałe /: . taki oto scenariusz, na który często trafiam:

    trzeba coś zautomatyzować/zmienić u klienta. wersje serwerów – od W2k3R2 po w12. jakie mamy środowisko do tego?:

    • na w2k3R2 powershella nie ma w ogóle
    • na w2k8 jest, ale dla tej wersji była bardzo ograniczona liczna cmdletów
    • na w2k8R2 cmdletów jest więcej ale nadal są ograczniczone
    • na w12 jest ich na prawdę dużo, ale część operacji i tak trzeba wykonywać via stare commandlineowe toole.

    i tak wybór jest pomiędzy:

    • zainstalować na wszystkich maszynach powershell. zadanie nietrywialne bo nie wszędzie jest v3, trzeba spełnic szereg wymagań, być może dograć jakieś moduły. sporo zachodu ale jeśli jest się adminem sieci to można się pobawić. jednak dla konsultanta – osoby z zewnątrz – jest to nieopłacalne.
    • być uniwersalnym – korzystać z VBS + CMD

    finalnie – jeśli ma być uniwersalnie to trzeba sięgnąć do VBSa, co jest bolesne. po wygodzie i mozliwościach, jakie daje PS, grzebanie się w basicu jest ciężkim doznaniem.

    niezrozumiałe dla mnie pozostaje:

    • czemu default shell w core to cmd
    • czemu PS nie jest poprawką obligatoryjną/sugerowaną dodatkową – w końcu to podstawowe środowisko zarządzania! na stronie opisującej WMF 3.o jest informacja iż nie jest kompatybilny z <tu całkiem spora lista>. niewątpliwie odpowiada to bezpośrednio na pytanie ‘czemu nie jest poprawką obligatoryjną’ ale rodzi pytanie – skąd te niekompatybilności?
    • czemu nie ma oficjalnych update’ów modułów do PS?

    w efekcie, pomimo ostrego parcia w kierunq PS nie można mu zaufać – skrypty napisane na jeden system mogą nie działać na innym. brak jest spójności i jednego, porządnego środowiska.

    Powershell basics mini-FAQ

    • jak sprawdzić wersję powershell:

    $host.version

    • czy da się zupgradeować powershell do wersji 3 na wszystkich systemach?

    po pierwsze to nie tylko PowerShell ale ‘Windows Management Framework’. na cały framework składa się kilka komponentów, wykorzystywanych na końcu łańcucha przez PS: BITS, WinRM i kilka innych komponentów, +oczywiście .NET framework. na staszych systemach trzeba więc zupdateować i pozostałe komponenty.

    dla w2k8, w2k8R2 i w7 da się – można zaciągnąć z download center
    dla wersji 2k3/XP SP3 jest tylko v2 i nowszej nie będzie

    • jak sprawdzić dostępne moduły

    get-module –listAvailable

    użytkownika: userdocumentswindowspowershellmodulesmymodule
    systemowe: windowssystem32windowspowershellV1.0modulesmymodule

    • skąd wziąć moduły?

    sporo jest na codeplexie. jedno z fajniejszych repozytoriów jest na technetowym wiki.

    eN.

    maintenance kont AD

    skrypty PS w dawno nie odświeżanym dziale skryptów..

    do prawidłowego działania nie potrzeba modułu AD – kiedy je pisałem jeszcze go nie było q: poza tym czasem lepiej mieć pełną kontrolę.
    skrypt bloqjący jest już zrobiony ‚na łatwiznę’ – korzysta dsmove.

    eN.

    wyszukiwanie kont, które się nie logują

    przez kilka lat używałem skryptu do wyszukiwania kont, które nie są już używane. jest w nim taki fragment:
    # Get the current date
    $currentDate = [System.DateTime]::Now
    # Convert the local time to UTC format because all dates are expressed in UTC (GMT) format in Active Directory
    $currentDateUtc = $currentDate.ToUniversalTime()
    $lastLogonTimeStampLimit = $currentDateUtc.AddDays(-$MAXUSERIDLE)
    $lastLogonIntervalLimit = $lastLogonTimeStampLimit.ToFileTime()

    $searcher.Filter = "( &(objectCategory=person)(objectClass=user)(lastLogonTimeStamp< =$lastLogonIntervalLimit) )" $results=$searcher.findall()
    i nagle, po tych kilq latach ktoś mi mówi - "ty, ale tu nie ma kont, które się w ogóle nie logowały"
    UPS! /:
    faktycznie - w takim wypadku lastLogonTimeStamp jest nullem a więc porównanie nie udaje się... poprawny filtr:
    $searcher.Filter = "(&(objectCategory=person)(objectClass=user)(|(lastLogonTimeStamp< =$lastLogonIntervalLimit)(!lastLogonTimeStamp=*)))"

    huh. jak ktoś chce cały skrypt - pisać.

    eN.

    powershell–uruchomienie exe z parametrem

    w całej ‘genialności’ projektanci PS zapomnieli o totalnie najprostszych rzeczach, które co-i-rusz wychodzą. bardzo chciałbym się pozbyć nawyq uruchamiania konsolki cmd ale do cholery… uruchomienie najprostszej instalki z parametrem bywa co najmniej uciążliwe.

    w przeciwieństwie do starego ‘okienka DOS’ konsola PS próbuje interpretować cały ciąg jako instrukcję PS. i tak wpisanie:

    costam param=1 –option 2 {otherParam:3}

    w DOS spowoduje:

    • próbę odnalezienia polecenia ‘costam’
    • jeśli znaleziony – przekazanie całej reszty ciągu do obsłużenia przez ‘costam’

    w PS natomiast sprawdzana jest składania całego polecenia. w win 8 jest powershell v3 gdzie pojawiło się specjalne oznaczenie:

    --%

    które mówi PS aby nie interpretować dalszej części linii. w starszych PS można albo łapać się prawą ręką za lewe ucho przekładając ją pod tyłkiem, albo po prostu odpalić cmd – np. ‘cmd /c polecenie’. dla chętnych do zabawy proszę najlepszy link jaki znalazłem: http://edgylogic.com/blog/powershell-and-external-commands-done-right/

    a dodawanie wynalazków typu – – % może i działa i jest wyjściem, niemniej zaczyna przypominać wynalazki z cmd – gdzie zależnie od wykonania używało się coraz dziwaczniejszcyh figur i sztuczek. mam nadzieję, że nie doprowadzą do podobnego bałaganu…

    eN.

    hurtowa zmiana nazw grup

    jak zmienić hurtem nazwy grup? aby to zrobić trzeba zastosować drobny trik.

    było 1ooo razy i każdy powinien wiedzieć… ale odświeżyć sobie widomości raz na jakiś czas jest dobrze. trik polega na tym, że nie da się stricte zmienić nazwy grupy – można natomiast przenieść obiekt i podać nową nazwę. i tak jeśli wyświetli się ‘dsmod group /?’ to operacji zmiany nazwy nie ma. natomiast przy ‘dsmove /?’ można znaleźć taki przykład:


    The user object for the user Jane Doe can be renamed to Jane Jones
    with the following command:

        dsmove „cn=Jane Doe,ou=sales,dc=microsoft,dc=com” -newname „Jane Jones”

    teraz wystarczy dodać prostą logikę i całość gotowa:


    eN.

    tablice wielowymiarowe (multidimensional arrays)

    operacje na tablicach w powershell są dość dziwnie rozwiązane. jak zwykle przy walce z najprostszymi [wydawałoby się] operacjami jest całkiem sporo zabawy. dla tego ciekawostka: jak dodać element do tablicy wielowymiarowej?

    krótki scenariusz: dostaję dwuelementowe tablice wyników. chcę przechowywać je w dwuwymiarowej tablicy. czemu nie hashtable? ponieważ nie ma indexów i nie da się sprawdzić np. “3 elementu tablicy”.

    deklaracja tablicy jest trywialna:

    • $multiarray=@() – definicja pustej tablicy, uniwersalne
    • $multiarray=(“abc”,”def”),(“ghi”,”jkl”),(“mno”,”prst”) – definicja z 3ma elementami

    najpierw zajmę się drugim przypadkiem, bo działa prawidłowo i jest poprawną tablicą wielowymiarową:

    >echo $multiarray[0]

    abc
    def

    >echo $multiarray[1][1]

    jkl

    no i supa. teraz spróbujemy dodać kolejną tablicę … i tu zaczyna się robić dziwnie:

    >$multiarray+=(“uwx”,”yz”)
    >echo $multiarray[3]

    uwx

    >echo $multiarray[3][1]

    w

    he? o co c’mon? o fakt, iż tablice można mieszać – dodawać elementy różnych typów. wykonując dodanie +=(“uwx”,”yz”) de facto dodajemy dwa kolejne elementy do tablicy, będące jednowymiarowymi tablicami [po prostu stringami]. jak zatem dodać kolejną tablicę? spróbujmy tak:

    >$multiarray+=@(“uwx”,”yz”)

    eeee. WRONG! nadal dokładnie tak samo. aby dodać tablicę trzeba użyć takiej zupełnie intuicyjnej składni z przecinkiem (; pokażę od początq:

    >$multiarray=(“abc”,”def”),(“ghi”,”jkl”),(“mno”,”prst”)
    >$multiarray+=,(“uwx”,”yz”)
    >$multiarray[3]

    uwx
    yz

    >$multiarray[3][1]

    yz

    w końcu dobrze! w takim razie całe rozwiązanie będzie wyglądało tak:

    >$multiarray=@()
    >TUTAJ JAKIŚ LOOP
           $multiarray+=,($cos1,$cos2)

    pozostaje jeszcze kilka innych ciekawostek o tablicach wielowymiarowych, o których trzeba wiedzieć:

    podana przeze mnie definicja to ‘tablica tablic’ a nie stricte ‘tablica wielowymiarowa’. poprawny zapis tablicy wielowymiarowej to:

    $multiarray=New-Object ‘object[,]’ 10,2 – definicja tablicy wielowymiarowej 1ox2

    jednak operacje na takiej tablicy są trudniejsze – np. dodanie dwóch elementów wymagało by wykonania dwóch operacji – dla [x,0] i [x,1]. przy ‘tablicy tablic’ wystarczy +=,($x,$y) a więc jest łatwiej. dostanie się do komórek jest wtedy $multiarray[x,y] a nie jak przy ‘tablicy tablic’ $multiarray[x][y].

    pozostaje kwestia wyświetlenia na ekran i tutaj kolejna niemiła niespodzianka: wspaniała funkcja Format-Table nie potrafi poradzić sobie z takimi tablicami. czy będzie to prawdziwa wielowymiarowa czy tablica tablic – będą one wyświetlane jako kolejne elementy ): niestety pozostają stare niedobre sposoby iteracji i formatowanie pojedynczych rzędów ): i znów dla ‘tablicy tablic’ operacja enumeracji jest prostsza:

    >foreach($ma in $multiarray) { echo "$($ma[0]) -> $($ma[1])" }

    abc -> def
    ghi -> jkl
    mno -> prst
    uwx -> yz

    eN.

    wartościowy null – jak w Powershell sprawdzić limity skrzynek Exchange

    Sprawa dość trywialna… przynajmniej tak by się można spodziewać. Limity wielkości skrzynek zapisane są w dwóch miejscach:

    • w parametrach samej skrzynki na Exchange – to dla tych, którzy będą mieli ‘use mailbox default’
    • w atrybutach w AD, które będą za chwilę opisane.

    zacznę najpierw od szmacianego raportu SCCM:

    nie wiem czy panowie z centrali sami przygotowywali ten raport czy to standardowy [domel, wiesz może?] ale jest to jeden z najbardziej oszukańczych raportów jaki widziałem:

    • dla osób z flagą ‘use default’ pokazuje wszędzie wartości null – jak by nikt nie miał skrzynki
    • dla osób, które mają zarówno ‘use default’ ale kiedykolwiek miały inne wartości, wartości te zachowane są w atrybutach AD [tyle, że nieużywane]. w zwiazq z tym SCCM pokazuje nieprawdziwe wartości, które są nieużywane.
    • jedyne co pokazuje dobrze to osoby, które mają coś ręcznie ustawione i jest to w użyciu.

    masakra. trzeba było olać raport i zrobić to dobrze – czyli ręcznie. sprawa jest prosta. wykorzystywane są cztery atrybuty obiektu user [zapisuję małymi znakami, ponieważ przypominam, że PS wymaga używania w lowercase!]:

    • mdbusedefaults – czyli flaga ‘use defaults’. jeśli ustawiona jest na ‘true’ to reszta nie jest sprawdzana. po prostu dziedziczy parametry ustawione na storze [dla GT –> “na magazynie” (; ]
    • mdbstoragequota – wartość ‘issue warning’. quota
    • mdboverquotalimit – wartość ‘prohibit send’. softquota.
    • mdboverhardquotalimit – wartość ‘prohibit to send and receive’. hardquota.

    image

    so far, so good. problem zaczyna się kiedy próbuje się sprawdzić która skrzynka ma wartość domyślną, a która nie. powód – podstawowy dla PS czyli ‘co za cholerstwo zwraca ta funkcja?’. aby podjąć działanie zależnie od wartości mdbusedefaults trzeba sprawdzić czy ma wartość true czy false. a oto wyniki zabawy:

    PS C:> $r.properties.mdbusedefaults
    False
    PS C:> if ($r.properties.mdbusedefaults -eq $false) {echo „aaaa”}
    PS C:> if ($r.properties.mdbusedefaults -eq $true) {echo „aaaa”}
    PS C:> if ($r.properties.mdbusedefaults -eq $null) {echo „aaaa”}
    PS C:> if ($r.properties.mdbusedefaults) {echo „aaaa”}
    aaaa
    PS C:> if ($r.properties.mdbusedefaults -eq ‚False’) {echo „aaaa”}

    co widać? w pierwszym zapytaniu dostajemy wartość false. kiedy jednak próbuje się tą wartość porównać z $false czy $true – żadna z powyższych. nie jest to również $null. w takim razie oczywistym wydaje się, że to musi być po prostu string. ale i to zawodzi.

    pomimo usilnych prób nic z tego nie wyszło. poszedłem spać a na drugi dzień rozwiązanie jakoś tak samo przyszło:

    PS C:> $r.properties.mdbusedefaults.gettype()

    IsPublic IsSerial Name                                     BaseType
    ——– ——– —-                                     ——–
    True     False    ResultPropertyValueCollection            System.Collections.ReadOnlyCollectionBase

    skoro jest kolekcją to trzeba to zrobić tak:

    PS C:> $r.properties.mdbusedefaults[0]
    False
    PS C:> if ($r.properties.mdbusedefaults[0] -eq $false) {echo „aaaa”}
    aaaa

    pytanie ‘czemu, u licha, to jest kolekcją??!!’ pozostawiam otwarte. dla mnie to idiotyzm ale może ktoś zna jakieś logiczne wyjaśnienie?

    a na zakończenie cały skrypt:


    eN.