Profile – część pierwsza.

•15 marca, 2011 • 3 Komentarze

Większość z nas ma profil. Na nk, fejsbuku, golden lajn itd. itp. Ale czy nie byłoby świetnie móc podobnie przygotować sobie środowisko pracy? Pracując z cmd, czy nawet z vbs, takich możliwości w zasadzie nie było. A nawet jeśli były, niczym nie przypominały profili znanych z powłok *nixowych. PowerShell i tutaj nas nie zawodzi. Dziś chcę wspomnieć jedynie o podstawach: jakie profile posiadamy (potencjalnie), do czego służą i jak w prosty sposób “dobrać się” do nich z poziomu samego hosta.

1. Od ogółu do szczegółu.

PowerShell, jak wiadomo, może objawiać się w wielu postaciach: powershell.exe, ISE, PowerGUI… Każdy z tych hostów może wymagać innego traktowania. Oprócz tego część rzeczy może być przydatna dla wszystkich, część jest bardziej osobista i wymaga profilu osobnego. MS uwzględnił te potrzeby definiując cztery podstawowe profile:

Visibility

Ścieżki wszystkich profili są na sztywno zdefiniowane. Ma to oczywiście i wady (potencjalny wektor dla ataków typu ‘inject code’) jak i zalety (na każdym komputerze można bez trudu je odnaleźć i skonfigurować). Co w nich umieszczać? W najbardziej ogólnych można zdefiniować korporacyjne środowisko: przydatne dla wszystkich aliasy, funkcje, dyski. W tych przeznaczonych dla konkretnego hosta dodatkowo ustawić parametry dla tego hosta właściwe (menu w ISE, czy rozmiar kursora w powershell.exe). A dla poszczególnych użytkowników: ładowane na starcie moduły, własne funkcje, zmienne, aliasy. I oczywiście na ostatnim poziomie wszystko to, co przyda się tylko nam, w danej aplikacji (w ISE startowe ustawienie zakładek, kolory we wbudowanym edytorze a  w powershell.exe kolorki dla informacji typu debug i error np.). Oczywiście to tylko luźna propozycja, a raczej opis tego jak ja bym to podzielił. Plus takiej granularnej budowy jest chyba oczywisty: pewne rzeczy możemy narzucić (jeśli zależy nam na spójnej bazie aliasów np.) i ustawić przy pomocy GPO na wszystkich komputerach w naszej organizacji – dzięki temu siadając do każdego komputera możemy założyć pewne rzeczy odnośnie środowiska. A jeśli czegoś nam osobiście brakuje – wystarczy zdefiniować to w naszym osobistym profilu. Drugi plus jest taki, że profile ‘AllUsers’ wymagają odpowiednio wysokich uprawnień, więc nie ma możliwości by ktoś z niższymi uprawnieniami nam te profile ‘zepsuł’.

2. Znaleźć, stworzyć, zmodyfikować.

Zespół tworzący PowerShella zadbał o naszą wygodę. Stworzył zmienną o dość jednoznacznej nazwie: $profile. Zmienna jest typu string i zawiera ścieżkę do ostatniego elementu naszego profilowego łańcucha: CurrenUserCurrentHost. Dzięki temu mamy łatwy dostęp do profilu, który określa naszą bieżącą powłokę. Ale to nie wszystko – nazwy wyszczególnione w tabeli powyżej odnoszą się do nazw właściwości dodanych do zmiennej $profile by uczynić pracę z profilami jeszcze prostszą: $profile.AllUsersAllHosts, $profile.CurrentUserAllHosts itd. Dzięki temu wszystko mamy ‘na tacy’. Praca z profilami jest rzeczą, która zwłaszcza na początku może nieco zirytować. Aby tego uniknąć, trzeba pamiętać o trzech rzeczach:

  1. Profile nie istnieją ‘domyślnie’, a zmienna $profile zawiera jedynie string, jej obecność niczego nie przesądza.
  2. Folder, w którym profile mają być przechowywane zwykle też nie istnieje, więc notpepad $profile raczej nie zadziała.
  3. Profil to skrypt – by działał musi być zgodny z naszą ExecutionPolicy. Jeśli więc mamy inną niż Unrestricted (takie ustawienie zdecydowanie odradzam) to może nie zadziałać, nawet jeśli go już stworzymy.

Więc po pierwsze primo: stwórzmy nasz profil:

if (!(Test-Path $profile)) {            
    New-Item -ItemType File -Path $profile -Force            
}

Jak widać najpierw upewniamy się, że profilu nie stworzyliśmy wcześniej. Jeśli nie – zostanie on stworzony (razem z folderem, w którym powinien się znajdować – dzięki parametrowi –Force).

Po drugie: otwórzmy go przy pomocy edytora. Odradzam notepad.exe, nawet jeśli chcecie używać tylko powershell.exe najlepiej skorzystać z ISE. Piszemy więc:

ise $profile

I dodajemy wszystko, co nam potrzebne. Na koniec pozostaje plik ten zapisać i wczytać. Teraz możliwości są dwie: restart hosta (zwykle to przesada) lub wgranie profilu na żywym organiźmie. Ponieważ z założenia profil modyfikuje naszą sesję odpowiednikiem restartu byłoby uruchomienie $profile bez tworzenia nowej przestrzeni nazw (scope –> na pewno da się to przetłumaczyć lepiej…). Aby to zrobić używamy operatora: . $profile

Z ExecutionPolicy może być pewien problem. Idealnym rozwiązaniem byłoby ustawienie jej na AllSigned (czyli podpisujemy wszystkie skrypty) i podpisanie profili. To często jednak wymaga sporego nakładu pracy, jeśli nie mamy własnego certyfikatu do podpisywania kodu źródłowego. Zalecany kompromis to opcja RemoteSigned. W kolejnych częściach przedstawię ciekawe rozwiązanie, które pozwala tego uniknąć na poziomie systemu a pozwala ustawić na poziomie interaktywnej sesji. Alternatywą – niezbyt wygodną, a na pewno bezpieczną – jest ręczne uruchamianie PowerShella z odpowiednią ExecutionPolicy, ale na to pozwala tylko powershell.exe (ma on parametr –ExecutionPolicy, który pozwala w dowolny sposób wartość ExecutionPolicy zmienić).

Cudownie. Mamy więc profil, profil śmiga, ale co tam wepchnąć? Moje propozycje na ten temat postaram się umiescić w drugiej części tego cyklu. 🙂

Scripting Games 2011

•19 lutego, 2011 • 1 komentarz

Zbliża się wyjątkowa i jedyna w swoim rodzaju okazja, by ruszyć z miejsca w skryptach PowerShella. Właśnie zostały ogłoszone Scripting Games 2011. Jeśli jesteś kimś, kto dopiero zaczyna przygodę z PowerShellem – z całą pewnością będzie to dla Ciebie świetna okazja by posiłować się z zadaniami do wykonania. Jeśli piszesz już dobrze, czy wręcz doskonale – możesz wystartować i sprawdzić, czy inni podzielają Twoją opinię i co jeszcze w sposobie pisania skryptów mógłbyś poprawić. Dla mnie osobiście, gdy startowałem w SG 2010, była to wspaniała okazja by zmierzyć się z rzeczami, których wcześniej nie ‘tykałem’. Zachęcam wszystkich, bo to naprawdę wspaniała rzecz:

2011 Scripting Games

Pobierz znaczek tutaj!

Oczywiście sam też zamierzam wystartować. PowerShell wciąż jest dla mnie pełen niespodzianek. Kilukrotnie przekonałem się na tym na szkoleniu z PowerShella, w który uczestniczyłem od poniedziałku do piątku. To kolejna rzecz, do której mogę zachęcić. Ale porównując doświadczenia ze szkoleń MS moje i kolegi dochodzę do wniosku, że olbrzymie znaczenie ma nie tyle zestaw przygotowany przez Microsoft, co prowadzący. Osobiście mogę z czystym sumieniem polecić Marcina Kozakiewicza, z ALMADO. Firma nie jest wielka, panuje w niej niemal rodzinna atmsofera, a szkolenia z Marcinem to po prostu jakoś sama w sobie. Więc jeśli masz siłę przekonywania i szefa, który widzi sens w szkoleniu swoich pracowników – do dzieła. Szkolenie to, jak wszystkie MS, nie jest tanie, ale myślę, że warto. Choć z własnej kieszeni rzaczej bym tyle nie wyłożył… 😉

Weź, przetwórz, sformatuj.

•30 stycznia, 2011 • Dodaj komentarz

Jedna z pierwszych rzeczy, do których musimy się przyzwyczaić rozpoczynając pracę z PowerShellem jest model układanki. Rzadko kiedy pisząc jakąś komendę ograniczymy się do jednego puzzla. Bardzo często pierwsza komenda, choć wyświetli ‘coś’, to nie wyświetli tego, czego nam potrzeba. Prosty przykład to komenda Get-ChildItem (dir/ ls). W innych wierszach poleceń na ogół możemy osiągnąć pożądany rezultat bez dodatkowych komend filtrujących, przetwarzających wyjście, czy wreszcie wyjście to formatujących. Najprostszy przykład to potrzeba wyświetlenia tylko folderów. W cmd.exe wpisalibyśmy po prostu dir /ad i już, foldery fruną w naszą stronę. PowerShell? Jeden element zwróci nam wszystko, drugi – przefiltruje:

dir | where { $_.PsIsContainer }

Format wyjściowy też różnie może być odbierany – a to za szczegółowy, a to za mało szczegółowy, a to brzydki po prostu (z taką opinią zetknąłem się wczoraj). Dobra wiadomość dla nas: zawsze możemy format wyjściowy zmienić. I jeszcze lepsza: niezależnie od tego jaką komendę chcemy ‘poprawić’ w tym względzie – to zawsze formatować będziemy tymi samymi narzędziami/ składnią. Inna sprawa, że nieco trzeba poćwiczyć, by dojść do wprawy. Ale podstawowe tricki są niezmienne. Załóżmy więc, że z widoku folderów kompletnie zbędne nam są informacje o ostatniej modyfikacji, tryb pliku, czy pusta zawsze długość, a dla odmiany chcielibyśmy liczbę plików i folderów w środku. Pozbycie się czegoś w zasadzie oznacza nie wybranie tego w naszej tabulce. Dodanie wymaga już nieco więcej zabawy, więc może zacznijmy od usunięcia (czyt. wybrania) tego, co nam trza:

dir | where { $_.PsIsContainer } | Format-Table Name

Dalej zaczynają się schody, czyli elementy słownikowe (hashtable). W przypadku komend formatujących element taki może zawierać informację o:

  • tytule (label)
  • wyrażeniu ‘generującym’ zawartość (expression)
  • szerokości (width)
  • równaniu (alignment)

Najbardziej interesujące jest wyrażenie, które pozwala nam ‘wyciągnąć’ z obiektu naprawdę wszystko, tak naprawdę może tam być skrypt, który łączy się z jakimś hostem używając WMI i wyciąga z niego dane, które w danej chwili są potrzebne. Na ogół oczywiście jest to po prostu sięgnięcie po jakieś metody/ właściwości obiektu, który wpada do rurki. W tym wypadku (liczby plików i folderów) przydadzą nam się metody GetFiles() i GetDirectories() obiektu, z którym będziemy pracować:

$FileCount = @{            
Label = 'File(s)'            
Width = 20            
Expression = { $_.GetFiles().Count }            
Alignment = 'Left'            
}            
            
$FolderCount = @{            
Label = 'Folder(s)'            
Width = 10            
Expression = { $_.GetDirectories().Count }            
Alignment = 'Center'            
}            
            
dir | where { $_.PsIsContainer } |             
    Format-Table Name, $FileCount, $FolderCount

Zmienne $FileCount i $FolderCount to właście wspomniane elementy słownikowe. Jak widać napracowałem się nieco, by je rozpisać, ale to nie jest konieczne, obie definicje można skrócić używając po prostu pierwszych liter każdego z kluczy: l, w, e, a…:

$MyName = @{l='Name';e={$_.Name};a='center';w=30}            
            
dir | where { $_.PsIsContainer } |             
    Format-Table $MyName, $FileCount, $FolderCount

Teraz mamy już pełną kontrolę nad szerokością, rozmieszczeniem, nazwą i zawartością poszczególnych kolumn. Jak widać wymagało to nieco pracy i wiedzy, ale plus jest taki, że ta wiedza może być używana wielokrotnie, formatowanie listy procesów, serwisów czy kluczy w rejestrze nie będzie się niczym w zasadzie różnić. Dla wielu będzie to wada (nie ma zbyt wielu pre-formatowanych wyników polecenia ls) dla innych zaleta (każde polecenie można sobie dowolnie sformatować). Jedna, myślę dość ważna uwaga: formatowanie zostawiajmy sobie na koniec. Obiekty, które z niego wychodzą, nie mają już nic wspólnego z oryginałem. Nie da się ich sortować, grupować czy filtrować. Można je tylko wypchnąć na zewnątrz: Out-Host, Out-File, Out-Printer, Out-Null 😉 I jeszcze jedno: PowerShell daje nam możliwość zapisania sobie tych formatek w pliku XML. Ale to już całkiem inna historia…

Czemu PowerShell?

•16 stycznia, 2011 • Dodaj komentarz

Pracownik działu IT to na ogół osoba latająca od zlecenia do zlecenia, gasząca pożary i usiłująca jakoś ogarnąć “to wszystko”. Czasu na naukę na ogół nie ma wcale. Sporadycznie uda się wymusić na szefostwie jakieś szkolenie “zewnętrzne”, a i w jego trakcie nierzadko nadal trzeba odbierać telefony, odpowiadać na maile, gasić w/w pożary w dodatku rękami osób o mniejszym doświadczeniu. Po co więc uczyć się kolejnej technologii, kolejnego języka skryptowego czy kolejnej “konsoli”? Cóż, na początku bywa trudno, ale wierzcie mi, zwraca się ta inwestycja bardzo szybko. Jeśli zamierzacie pracować w systemie Windows (zarówno w wersji klient jak i serwer) to raczej nie uda Wam się przed tym uciec. W dodatku coraz więcej technologii nie będących produktem MS też zaczyna wspierać PowerShella. Od dawna takie wsparcie funkcjonuje w VMWare, ostatnio doszły NetApp i Intel (wsparcie dla vPro). No tak, ale to tylko nadal brzmi jak kolejne marketingowe bla, bla, bla. Jesteśmy najlepsi, najwspanialsi i w ogóle pochylcie głowy przed kolejny dzieckiem Microsoftu. Problem w tym, że przed tym produktem nie trzeba głowy pochylać. Więcej – to zespół tworzący ten produkt pochyla się nad każdym z nas i pyta: co nam nie wyszło? I trudno oprzeć się wrażeniu, że każda odpowiedź jest solidnie rozważana. A efekt? Wymienię tylko te technologie, z którymi na co dzień pracuję by pokazać, jak bardzo PowerShell pomaga je ogarnąć. I wspomnę o konkretnych przypadkach, nie o wszystkim co można zrobić. Zawsze to łatwiej skupić się na konkretnym problemie, niż generalizować… 🙂

1. Pliki

Wsparcie do walki z niesfornymi plikami jest moim zdaniem przednie. Komenda, która oszczędziła mi ostatnio pisania kilku linijek w .cmd czy .vbs:

dir –recurse –force -filter *-id-* | Rename-Item –NewName { $_.Name –replace ‘-id’ }

W skrócie: chodziło o wycięcie z nazw setek plików ‘-id’. Struktura katalogów przyprawiała o ból głowy, więc w cmd pewnie w końcu bym poległ na jakimś pliku. W vbs pewnie byłoby łatwiej, ale tworzyć obiekt by sięgnąć do plików… Buee… 😉

2. AD

Sam PowerShell wsparcie ma, ale nie najlepsze. Od czego jednak są inne firmy: Quest wieki temu opublikował darmowe narzędzia do zarządzania AD z PowerShella. Jeśli chcesz używać go do zarządzania AD – szczerze polecam. Problem: globalna grupa z której trzeba usunąć wszystkich członków, których konta znajdują się w danym OU. Chirurgicznie, bez usuwania innych. Oryginalny pomysł? Ldifde. Mój pomysł? Jedna linia w PowerShell:

Get-QADUser -SearchRoot $OU | Where-Object { @($_.MemberOf) -contains $Group } | Remove-QADGroupMember -Identity $Group -WhatIf

$OU i $Group to zmienne, w których miałem odpowiednio OU, którego zawartość mnie interesowała (oczywiście bez wnikania w strukturę wewnątrz tego OU). $Group to DN grupy. Do tego –WhatIf by najpierw sprawdzić co się stanie… 😉

3. WMI

Istnieje już tyle lat, a praktycznie mało który administrator go używa. Poza naturalnie tymi, którzy potrafią posłużyć się VBS, albo napisać program w C (ale to już quasi-programista 😉 ). Ale tam by w ogóle dobrać się do WMI trzeba kilku linii. By połączyć się z kilkoma komputerami – całą procedurę trzeba zamknąć w suba lub funkcję i ponowić dla każdego z nich. A później jeszcze masa linii by dane wyświetlić. PowerShell?

Get-WmiObject –ComputerName PC1, PC2, PC3 –Class Win32_Bios | select __Server, SerialNumber | Export-Csv –NoType Plik.csv

I już, mam informację o nr seryjnych PC1, PC2, PC3 w .csv, który otwieram sobie w Excelku i dalej działam już tam. Ale to nie wszystko – PowerShell pozwoliłby mi stosunkowo łatwo zmienić __SERVER na coś ładniejszego. Powiązać dane z kilku klas WMI też się da. A WMI to nieskończona kopalnia informacji o komputerze, który używamy i które używają nasi użytkownicy. Wszystko w naszym zasięgu… 🙂 A WMI to jeszcze metody, zdarzenia… Naprawdę, niewiele rzeczy na komputerze z Windows nie da się zrobić przy pomocy WMI. A teraz ta technologia jest na wyciągnięcie ręki. 🙂

Małe podsumowanie

Zamykając ten wpis chciałbym wspomnieć, że to wszystko to tylko skrobanie po powierzchni tego, co PowerShell ma nam do zaoferowania. Z silną wspólnotą zbudowaną wokół, z masą ludzi, którzy na żadne pytanie nie odpowiadają odruchowo “spytaj Google”, niemal wszystko jest możliwe. Jeśli sami macie problem z rozwiązaniem problemu – sięgnijcie do tego, co już stworzono i dostosujcie do swoich potrzeb. Możliwości są nieograniczone…

Raz, dwa, trzy… próba mikrofonu. ;)

•9 stycznia, 2011 • 1 komentarz

Od jakiegoś czasu noszę się z tym pomysłem, czas najwyższy by zacząć go realizować. Blog o PowerShellu po polsku. Już od kilku miesięcy pisuję na ten temat, ale są to wpisy po angielsku. Dlaczego? Głównie dlatego, że używając go posługuję się tym właśnie językiem. I to nie tylko pisząc skrypty, komentarze, pomoc do moich funkcji. Również czytając: książki, pomoc wbudowaną, czy pomoc online. Nie ma nadal żadnych znanych mi źródeł (poza kilkoma książki z MS Press, będącymi de facto tłumaczeniami książek pisanych w języku ‘domyślnym’), które o PowerShellu traktowałyby w języku moich ojców i dziadów. Szukając informacji po polsku trafiłem na ledwie kilka artykułów tu i ówdzie, ale nigdzie nie znalazłem osoby, która temu tematowi poświeciłaby znaczną część swojej uwagi.

W sumie nie powinno mnie to dziwić: próbując zapisać się na oficjalne szkolenie z PowerShella rok temu trafiłem na wielką pustkę. Nawet jeśli gdzieś takie szkolenia były w ofercie, to ostatecznie znikały z powodu braku chętnych. Gdy w końcu na takie szkolenie trafiłem, sam zdążyłem już sporo wiedzy o PowerShellu zdobyć ‘na piechotę’. Oczywiście, znajomość języka angielskiego była konieczna. Alternatywą było kupienie cieniutkich książeczek za wygórowaną cenę. Uznałem, że wolę jednak tym razem zaoszczędzić. Koniec końców kupiłem kilka książek (PowerShell TFM, PowerShell in Action, PowerShell CookBook), wszystkie po angielsku – a to dlatego, że po pierwsze: nigdzie nie trafiłem na tłumaczenie tych pozycji, a nawet jeślibym trafił – to pozycje tego typu wolę jednak czytać w oryginale… 😉

Tu jednak zaczął kiełkować pomysł, czy raczej grupa pomysłów. Zacząłem dumać czy przypadkiem pewną barierą w adaptacji PowerShella nie jest bariera językowa. Wiem, że większość z ludzi pracujących w branży IT język angielski zna, bo musi. Ale czy przypadkiem nie byłoby łatwiej – i mi, i innym – uczyć się go w języku ojczystym? Sam czasem nie do końca rozumiem treść artykułów/ książek/ wpisów w systemie pomocy, a na znajomość angielskiego raczej nie narzekam. Więc – po pierwsze: zadbać o polonizację PowerShella. Głównie chodzi o pomoc, która jest w niego wbudowana. Po drugie: przybliżyć sam produkt w naszym języku tym, którzy przez ową lukę, o której wspomniałem, raczej się nim nie zainteresowali. Po trzecie: jeśli czas, umiejętności i wiedza na to pozwolą – napisać książkę po polsku o PowerShellu. Nie jestem przesadnym optymistą, więc nie liczę na to, że – jeśli już powstanie – uda się gdzieś ją wydać. Skończy się więc pewnie na darmowym eBooku (o ile nie skończy się na słomianym zapale). Oczywiście idea jest prosta: nie tyle przetłumaczyć na język polski książkę/ książki już istniejące, ile w oparciu o wiedzę w nich zdobytą – napisać coś polskiego od pierwszego akapitu. Pracy będzie sporo. Choćby sama pomoc do cmdletów:

PowerShell, using GeSHi 1.0.8.8
  1. Get-Command -CommandType cmdlet | foreach { (Get-help $_ -full | Out-String).Length } | measure -Sum
  2. Count    : 331
  3. Average  :
  4. Sum      : 3697290
  5. Maximum  :
  6. Minimum  :
  7. Property :

Taki ogrom informacji niesie ze sobą system pomocy. A to przecież tylko opis poleceń – pozostaje jeszcze, kto wie czy nie istotniejsza, część konceptualna (wszystkie about_*). Ale czy nie będzie przyjemnie później rzucając okiem na pomoc ujrzeć coś takiego (to tylko szkic, wybaczcie kulawą nomenklaturę):

Get-Member -?

NAME
Get-Member
SYNOPSIS
Pokazuje właściwości i metody obiektów.
SYNTAX
Get-Member [-InputObject <PSObject>] [[-Name] <String[]>] [-MemberType {AliasProperty | CodeProperty | Property | NoteProperty | ScriptProperty | Properties | Property
Set | Method | CodeMethod | ScriptMethod | Methods | ParameterizedProperty | MemberSet | Event | All}] [-View {Extended | Adapted | Base | All}] [-Static] [-Force] [<C
ommonParameters>]
DESCRIPTION
Polecenie Get-Member pozwala uzyskać inforamcję o ‚członkach’ (właściwości i metody) obiektów.
Aby określić obiekt, użyj parametru InputObject albo przekieruj wyjście potoku do polecenia Get-Member. Aby uzyśkać informację o statycznych członkach (członkach klasy, a nie bieżącej jej instancji), użyj parametru ‚Static’. Aby wyświetlić tylko niektóre typy członków, takich jak NoteProperty, użyj parametru MemberType.

To nie kopiuj-wklej, naprawdę da się sprawić, by system pomocy dot. cmdletów wyświetlał informację po polsku.  🙂 To całe piękno PowerShella, można z nim zrobić niemal wszystko, nawet jeśli nie jest się programistą… 🙂