Skip to Content

IT nieuczesane.
category

Category: DevOps/Scripting

skrypty, programy, command line i inne

repozytorium artów o PowerShell

wpisów ostatnio brak, ponieważ idą w eter. WDI już za nami – sesje niby mają być dostępne online. streamy będą chyba dostępne na PJWSTKTV – jest już dzień drugi, ale nie moja ścieżka. ciąg dalszy zmagań z PowerShell na WGUISW – to będzie poważny prima aprilis q:

w ramach przygotowań do wszystkich sesji zebrało mi się całkiem pokaźne repozytorium mniej lub bardziej przydatnych linków dot. PS. miłej lektury.

sporo fajnej wiedzy, która pokazuje, że PS to nie jest tylko głupi shell ale na prawdę potężne narzędzie – opanowanie wszystkich technik programowania to niemal developerka – ale korzyści będą nieocenione ^^

eN.

jak rozpoznać kartę WiFi?

scenariusz: trzeba napisać skrypt, który będzie wyłączał rejestrację DNS dla interfejsów LANowych. służy do tego metoda SetDynamicDNSRegistration klasy Win32_NetworkAdapterConfiguration. pozostaje problem – jak znaleźć owe interfejsy LANowe, bo zwykłe wylistowanie interfejsów pokaże ich multum… są dwa warunki, które trzeba sprawdzić – odfiltrować te, które nie są IPEnabled oraz te, które nie są Wired. i tu się zaczynają schody – IPEnabled to parametr klasy Win32_NetworkAdapterConfiguration a typ interfejsu pokazuje atrybut AdapterTypeID klasy Win32_NetworkAdapter.

sprawdzenie obu tych warunków byłoby niemożliwe [mega-złożone] gdyby nie klasy asocjacyjne – w tym przypadku Win32_NetworkAdapterSetting, która łączy obie wcześniej wymienione. klasy asocjacyjne pobierają atrybuty dla obu klas dla danego urządzenia i publikują je w dwóch gałęziach – element oraz setting. skrypt finalnie wygląda tak:

proste, nie? a teraz ciekawostka na koniec. na MSDN wyraźnie i jasno opisane są ‚adaptertype’ oraz ‚adaptertypeid’.. a oto jak przedstawia się moja karta WiFi /:

PS C:\_ScriptZ> .\setDynDNSReg.ps1
[debug] adapter type: Ethernet 802.3
[debug] zmieniam parametr dla: [00000000] Karta Intel(R) Centrino(R) Wireless-N 1000

eN.

przenoszenie uprawnień między domenami

jakiś czas temu pisałem o fajnym narzędziu do sprawdzenia uprawnień w AD – AD ACL Scanner. chciałem użyć go do przeniesienia uprawnień między domenami… i okazało się, że nie jest to wcale takie proste:

  • plik csv, który jest generowany jako raport, nie zawiera nagłówka – a więc nie wiadomo co oznaczają poszczególne wartości
  • wartości w raporcie HTML mają nagłówki… ale nie wszystkie i nie takie same
  • no i nawet jeśli znam nagłówek – to jak to przenieść?

oto szkic skryptu, który potrafi zaciągnąć plik z ADADCLscan i przenieść do innej domeny. to, co trzeba zrobić przed jego użyciem to:

  • zmienić w pliku raportu nazwę domeny źródłowej na docelową we wszystkich rekordach
  • wyciąć przedrostki z nazw grup [np. DOMAIN\mygroup -> mygroup]

skrypt jest bardzo prymitywny – np. zakłada, że uprawnienia są tylko dla grup a nie dla użytkowników czy komputerów, nie ma obsługi błędów, etc – niemniej pokazuje kilka ważnych elementów: jak wygląda pełny nagłówek, w jaki sposób korzysta się z cmdletów ACL.

eN.

 

Alternate Data Stream

o ADS już kiedyś pisałem – oj dawno. dziś tylko małe uzupełnienie dot. PowerShell:

do tej pory jedynym sensownym sposobem usunięcia ADS było zassanie streams.exe z sysinternalsów. ale lepiej znać narzędzia które w systemie są od razy – czyli PS. scenariusz: zassany skrypcik z netu na jednym z kompów ciągle jest klasyfikowany jako ‚zone.identifier 3’ czyli z Internetu. i choćbym klikał na ‚unblock’ 1ooo razy – ni huhu. z jakiegoś powodu nie kasuje tej informacji. z PS proste jak drut:

 

et voila!

eN.

obsługa błędów w PS

w ramach ciekawostek – żeby ładnie obsłużyć błędy korzysta się z try-catch-finally… ALE. jak zwykle jest jakieś ale. pisząc skrypty do AD straciłem sporo czasu nie rozumiejąc o co c’mon, ponieważ polecenia get-ad* inaczej zachowują się, jeśli korzysta się z ‚-identity’ a inaczej jeśli ‚-filter’. w sumie jest to całkiem logiczne – ponieważ identity oczeqje istniejącej nazwy więc zwraca błąd jeśli jej nie ma. filter to prostu filtr, więc jeśli takiej nazwy nie ma, to po prostu zwraca $null. a więc trzeba uważać ‚co jest błędem’ …

 

eN.

skrypt audytujący

zadanie – jak zaudytować komputery poza domeną tak, aby stwierdzić jakie są na nich aplikacje i jakie licencje? prostym zapytaniem WMI można dowiedzieć się, że wersja systemu to np. WinXP pro – ale OEM czy VLK?

nie udało mi się dotrzeć do samych linków na MSDN ale udało mi się zebrać te informacje. kilka ogólnych:

  • MAP toola nie da się użyć często ze względu na niedostępność komputerów a czasem credentiali. niestety takie środowiska są i to wcale nie tak rzadkie jakby się mogło wydawać…
  • wersję licencji OEM/VLK/MAK można wyciągnąć np. przy pomocy slmgr.vbs … ale tego nie ma na XP. poza tym lepiej mieć to we własnym skrypcie. kluczem jest „HKLM\SYSTEM\Setup\Pid”. w skrypcie poniżej pokazuję konkretne wartości.
  • można nawet dowiedzieć się jaka to wersja na podstawie innego klucza – ale pełnej listy nie mam.
  • korzystanie z metody Win32_product nie jest wskazane ponieważ każde takie odpytanie automatycznie uruchamia proces weryfikacji. trwa długo i może doprowadzić do dziwnych komunikatów – ogólnie wysypać się. dodatkowo – klasa PRODUCT nie jest standardowo instalowana na wersji XP /: trzeba ją oddzielnie dodać. lepiej skorzystać z zapytania do rejestru.
  • odpytując rejestr na 64 bitowej maszynie musimy zrobić dwa zapytania, zmieniając providera – inaczej dostaniemy tylko małą część aplikacji zainstalowanych.
  • do bardziej skomplikowanych operacji oraz bardziej wymyślny skrypt -> open audit

a poniżej kod. oczywiście w VBS ponieważ to jedyny ‚standard’ który zadziała na każdej wersji od w2k aż po dzisiejsze w8.1

eN.

wyszukiwanie ciągów znaków

kilka słów o jednej z najczęściej wykonywanej czynności – wyszukiwanie ciągów znaków. przydatne w każdym aspekcie – debugowanie wyników, przeglądanie logów lub po prostu zawężanie outputu. w Linuxie jest stary, dobry grep. a co jest w PS?

w pierwszej kolejności jest Select-String. narzędzie potężne – i jak to często w przypadq PS, zdradliwe. największą zdradą jest fakt, że sls [automatyczny alias od PS3.o] nie jest zwykłym grep’em textowym – jest narzędziem obiektowym. praktycznie wszystko w PS jest obiektem, więc również listingi nimi są.

zależnie od wersji PS – 1.o, …4.o – dostaniemy inne wyniki. w wersji 3.o i mniejszej, przy standardowej ‚tabelce’, dostaniemy wyłącznie wynik pojedynczej kolumny:

PS C:\> Get-Process | Select-String power

System.Diagnostics.Process (powershell)

w PS4.o wyniki najpierw są parsowane do stringa, więc wynik jest bardziej tym, czego można się spodziewać (ALLELUJA!):

PS C:\> Get-Process|sls power
512      25    72944      82868   611     4,05   3528 powershell

jak zatem radzić sobie z Select-String w PS3.o-? IMHO najprostszym sposobem jest wykorzystanie ‚starego, dobrego’ findstr. dość drastyczne różnice w wersjach PS to jedna z największych bolączek – wszystko idzie w dobrym kierunq, ale niespójność konsoli i narzędzi na poszczególnych serwerach jest WIELKIM PROBLEMEM. kiedyś o tym już pisałem obszerniej. dodatkowo, na dzień dzisiejszy, wersja 4.o [dostępna w win8.1/12] jest dostępna wyłącznie ‚preview’.

a jak ktoś się uprze, żeby jednak koszernie używać Select-String w PS3.o- oto jak to powinno wyglądać:

PS C:\> (Get-Process | Out-String ) -split "`n" | Select-String power
645      30   140712     157660   647    11.69   7728 powershell

masakra, co? nie dość, że trzeba najpierw skonwertować wynik na string, to jeszcze trzeba powstawiać line-feedy. jest jednak jedna cecha Select-String, która powoduje, że czasem warto się przemęczyć – parametr ‚context’. głupi findstr Ci tego nie da (; context powoduje wyświetlenie X linii przed i po wystąpieniu danego ciągu. jest to niezwykle przydatne np. przy filtrowaniu [grepowaniu (; ] netstat. odpowiedź na pytanie ‚jaka aplikacja bloqje port 53500?’:

PS C:\> netstat -anb |sls 53500 -Context 1
[lync.exe]
>   TCP    192.168.7.77:53500     157.55.236.69:443      ESTABLISHED
[Explorer.EXE]

przy prostym findstr dostaniemy wyłącznie pojedynczą linię – co nie odpowie na pytanie…

dość fajnym dodatkiem jest narzędzie outgridview, które przy przeglądaniu wyników może również wiele dobrego wnieść [dostępne po zainstalowaniu PS ISE]. daje możliwość graficznego przeglądania wyników i dynamicznego filtrowania:

PS C:|>Get-Process | Out-GridView

eN.

 

zarządzanie VM z hosta Hv

środowiskiem zarządza się z jakichś narzędzi infrastrukturalnych typu System Center – to oczywiście najlepszy sposób ale w pewnych warunkach mało przydatny lub niemożliwy. zarządzanie w tej warstwie jest niemal niemożliwe/totalnie skomplikowane w środowisq hostowanym – wiele domen nie powiązanych ze sobą, maszyny w podsieciach porozdzielanych VLANami, inne przestrzenie nazewnicze i tak dalej… efekt jest taki, że nawet jeśli dla narzędzi uwierzytelnienie w wielu domenach nie jest problemem, pozostaje bardzo skomplikowany schemat sieci i bezpieczeństwa – często niezależny od administratora i zarządzany przez klienta.

fajnie byłoby móc to wszystko ogarnąć z jednego, centralnego punktu – klastra Hyper-V, gdzie te wszystkie hosty sobie działają. skoro mam je w jednym miejscu logicznym się wydaje, aby z niego wykonywać pewne operacje maintenancowe czy administracyjne [oczywiście jeśli taka jest umowa z klientem]. na każdym guescie powinny być Integration Services, Hv komuniqje się z IS i … co możemy dzięki temu zrobić?

nic. w każdym razie bardzo niewiele. powód jest prosty – z założenia całość musi być bezpieczna a Hv ma być warstwą izolującą. nie bez powodu w Hv w konsoli zdalnej nie ma możliwości mountowania dysków czy nawet schowka. Hv ma pozostać możliwie najcieńszą i najbezpieczniejszą warstwą.

co zatem jednak można oraz jak sobie z takim środowiskiem poradzić?

root\virtualization

popatrzmy co nam daje WMI z poziomu hosta. skoro można coś zrobić z poziomu SCVMM to znaczy, że da się z konsoli w postaci skryptu. obszerna lista klas pozwala na pełną konfigurację i odpytanie maszyny – oczywiście od strony ‚wirtualnego hardwareu’ – czyli nadal nie to, co mnie w tej chwili interesuje, ponieważ chciałbym dostać się do OSa. i tutaj z ciekawszych klas można znaleźć:

  • MSVM_ComputerSystem – podstawowa klasa, pozwalająca dowiedzieć się czegoś o samym OS. informacje nie są jednak dostępne bezpośrednio z tego obiektu – trzeba informacje ‚wymienić’ między hostem a guestem, a robi się przy pomocy klasy…
  • Msvm_KvpExchangeComponent – to podstawowy komponent służący do wymiany informacji między hostem i guestem. dzięki kombinacji tych dwóch klas można m.in. sprawdzić: FQDN systemu, skonfigurowane adresy IP, wersję systemu i SP itp. to podstawowa klasa pozwalająca na dalszą automatyzację – nazwa maszyny wirtualnej jest zupełnie nie przydatna poza kontextem samego SCVMM/HvM. aby połączyć się czymś do VM trzeba będzie to zrobić ‚oficjalnie’ czyli via sieć. a do tego potrzebny jest IP, który można uzyskać właśnie z tej klasy.
  • kilka innych klas ‚Integration Services’ pozwalających na interakcję z wewnętrznym OSem – shutdown, timesync i VSS. szczególną uwagę zwraca – Msvm_GuestFileService i Msvm_CopyFileToGuestJob – dostępne od wersji Windows 8.1. zdaje się, że wraz z R2 będzie można w końcu normalnie kopiować pliki q: pojawia się też inne klasy sugerujące, iż ilość operacji jakie będzie można wykonać z hosta będzie się rozszerzać.

praktyka

jednym z przydatniejszych skryptów jaki często wykorzystuje jest Get-VMDetails wykorzystujący powyżej opisane klasy. importuję go jako funkcję dzięki temu na stacji zarządzającej jest zawsze dostępny:

funkcja wypluwa obiekt dzięki czemu łatwo jest potem dalej odpytywać o poszczególne atrybuty. przykładowe użycie:

środowisko

ostatecznie daje to tylko podstawowe informacje pozwalające na dalsze podłączanie się do maszyn. z samym system z tego poziomu nie zrobi się wiele więcej. nic zatem nie zastąpi odpowiednio przygotowanego środowiska tak, aby z centralnego punktu można było do maszyn się podłączyć.

można by poudostępniać sieci guest-VLAN dla hosta aby z jego poziomu dostawać się VMek. ale uważam, że to nie jest najlepszy sposób… izolację lepiej pozostawić. zależnie od polityki być może da się utworzyć stację, która będzie miała dostęp do wszystkich VLANów będące punktem styq. takim punktem mogą być  np.:

  • stacje monitorujące. np. nagios, open manage czy inne wynalazki. zależnie od polityki być może da się utworzyć stację, która będzie miała dostęp do wszystkich VLANów
  • system AV
  • system backupów
  • system dystrybucji poprawek

ponieważ klienci mogą nie wyrazić takiej zgody lub środowiska muszą być odizolowane w 1oo% z jakiś względów – pozostaje utworzenie kilq stacji w różnych sieciach, nawet jeśli wszystkie VM są na pojedynczym klastrze. fajnie byłoby mieć możliwość instalacji ‚superagenta’ – który pozwoliłby na pełny dostęp do VM z hosta po uwierzytelnieniu – IMHO jeśli ktoś ma uprawnienia/zalecenia do maintenancu maszyny, security nie powinno cierpieć szczególnie pozwalając na dodatkową metodę dostępu…

refs

suma wszystkich pestek

odwieczny problem – archiva maili. nieużywane, ale nie wolno tknąć, broń Cię Panie Wielki Kalqlatorze! bo może ktoś-kiedyś-coś-jakoś i co wtedy??

no więc serwery są zawalone pestkami. oczywiście nikt nie kontroluje co gdzie jest zbackupowane – leży więc po kilka kopii w różnych miejscach. ogrom. jak policzyć ile to zajmuje, żeby pokazać klientowi skalę problemu w cyferkach?

polecam w pierwszej kolejności sięgnąć po raporty FSRM. narzędzie jest od dawna w systemie i warto sobie o nim czasem przypomnieć. raporty/statystyki – trzeba to pamiętać – są łatwe w generowaniu, trochę trudniejsze w interpretacji.

jako przykład proponuję takie statsy:

  • „file by filegroup” i w opcjach zaawansowanych ‚Email Files’
  • oraz „least used” co by pokazać, że są to równocześnie nieużywane pliki.

nie daje to 1oo% aqracji ale na pewno są ‚na szybko’ i ‚wyglądają’ czyli dwie ważne rzeczy aby raport pokazać np. managementowi [czy adminom].

bardziej geekowe/administracyjne podejście to oczywiście powershell. najpierw łanlajner żeby zliczyć wielkość wszystkich plików typu XXX:

bardziej rozbudowane statsy pokazujące ilość plików, sumaryczną wielkość oraz ile z nich nie było używane przez ostatni rok:

Filter or Include?

i na koniec jeszcze ciekawostka. filtrować listę plików [i nie tylko] można na trzy sposoby: filter, include i late-filtering. bardziej po polsq: można zdefiniować filtr bezpośredni, można zdefiniować co ma zawierać lista [wbrew pozorom to co innego niż filtrowanie] i można zrobić listę a potem ją filtrować – której metody używać?

mi się nie chciało tego mierzyć q: ale komuś się chciało: http://tfl09.blogspot.com/2012/02/get-childitem-and-theinclude-and-filter.html . wynik: najszybszy jest filtr i to dość znacząco.

eN.

 

 

akapity w powershell i grupy uniwersalne.

zadanie: trzeba zmienić grupy globalne na uniwersalne. zadanie o tyle nietrywialne, że grupa uniwersalna, nie może być członkiem grupy globalnej. a więc nie da się po prostu zaznaczyć wielu grup [czy też przelecieć skryptem] i zmienić ich w uniwersalne, bo posypią się błędy właśnie z takim opisem. trzeba najpierw znaleźć zagnieżdżenia i zmieniać typ ‚od dołu’.[swoją drogą, to wymuszenie w Exchange 2o1o+ z grupami uniwersalnymi jest pasqdny – właśnie z powodu tego, jak trzeba się napocić z konwersją i konsekwencjami w produkcji…]

klient ma bardzo złożoną strukturę grup więc żeby sobie trochę pomóc na szybko napisałem skrypt, który rekursywnie listuje memberof… i zatrzymałem się nad głupim problemem – jak ładnie wyświetlić poziomy zagnieżdżenia? trzeba na początq wstawić jakieś spacje. szybko znalazłem funkcję ‚padleft’ tylko… że nie chciała działać. krótki test typu:

wszystko działa. tymczasem w mojej funkcji nie chce… o co c’mon? chwilę mi zajęło zanim zwróciłem uwagę na drobny szczegół – liczba, jaką się podaje, to nie długość akapitu a długość finalnego ciągu, który chcemy uzyskać. w sumie to faktycznie – tak właśnie ma działać funkcja ‚pad’! nie ‚przesuwać o’ a ‚przesuwać do‚.

finalnie skrypt wygląda tak:

i jak zwykle najwięcej czasu poszło na pierdoły q:
eN.