Windows Server 2008

Windows PowerShell - dobry wygląd Udostępnij na: Facebook

Autor: Don Jones

Opublikowano: 29 września 2008

Zawartość strony
 Metoda tekstowa   Metoda tekstowa
 Metoda z wykorzystaniem Windows PowerShell   Metoda z wykorzystaniem Windows PowerShell
 Ale to jeszcze nie koniec!   Ale to jeszcze nie koniec!
 Dodatkowe materiały   Dodatkowe materiały

Nierzadko chcemy, aby nasze skrypty generowały atrakcyjnie prezentujące się dane wyjściowe. Autor niniejszego artykułu często pytany jest o najlepszą metodę tworzenia takich obiektów jak tabele. W rzeczywistości istnieje kilka sposobów podejścia do tego problemu. Pierwszy krok polega na napisaniu skryptu, który umieszcza dane (wszelkie dane, które chcemy wyświetlić w sformatowany sposób) w zmiennych o nazwach $data1, $data2 oraz $data3. A teraz możemy przejść do formatowania danych.

Metoda tekstowa

Zazwyczaj specjaliści IT radzą sobie z tym zadaniem w ten sam sposób, w jaki radziliby sobie z nim, pracując w języku takim jak VBScript, Perl, KiXtart czy inny język zorientowany tekstowo. Moglibyśmy rozpocząć od wypisania na ekranie zestawu nagłówków kolumn:

Write-Host "ColumnA'tColumnB'tColumnC"

Warto nadmienić, że `t to specjalna sekwencja wyjścia w powłoce Windows PowerShellTM, która powoduje wstawienie znaku tabulatora. Istnieje kilka możliwych metod wypisywania każdej linii tabeli przy założeniu, że dane znajdują się w zmiennych $data1, $data2 oraz $data3. Jedną z opcji jest po prostu wypisywanie zmiennych, bazując na dostarczanej przez powłokę funkcji zastępowania zmiennych ich zawartością w znakach podwójnego cudzysłowu:

Write-Host "$data1't$data2't$data3"

Inny odrobinę atrakcyjniejszy sposób osiągania tego celu polega na wykorzystaniu operatora –f. Ta technika rozdziela formatowanie od danych i tworzy linię kodu, która jest relatywnie czytelniejsza i łatwiejsza w utrzymywaniu:

Write-Host "{0}'t{1}'t{3}" –f $data1,$data2,$data3

Jednak to podejście pociąga za sobą pewne problemy. Po pierwsze bazując na stałych tabulatorach wyświetlonych w oknie konsoli, musimy nastawić się na to, że formatowanie może być nieco osobliwe. Na przykład jeśli wybrany wiersz tabeli ma 20-znakową wartość w pierwszej kolumnie, całe formatowanie tego wiersza zostaje zniweczone. Ponadto ponieważ wyświetlamy ten tekst przy użyciu polecenia Write-Host, jesteśmy w znacznym stopniu ograniczeni do widoku konsoli.

Nie istnieje prosta metoda wysyłania danych wyjściowych do pliku lub innego ich formatowania, jeśli kiedyś pojawi się taka potrzeba. A co więcej, to stosując bazujące na tekście podejście, kompletnie ignorujemy zasadniczo obiektową powłokę Windows PowerShell, w której pracujemy, zupełnie nie wykorzystując oferowanych przez nią rewelacyjnych technik i możliwości.

 Do początku strony Do początku strony

Metoda z wykorzystaniem Windows PowerShell

Windows PowerShell stanowi powłokę zorientowaną obiektowo. A to oznacza, że w idealnej sytuacji wszystkie przetwarzane przez nas dane powinny znajdować się w obiektach, które powłoka przekształcałaby w widok tekstowy dopiero wtedy, gdy byłoby to konieczne. Jednak w jaki sposób tworzyć obiekty dla dowolnych danych?

Kontynuując nasz przykład, rozpoczniemy od stworzenia pustego niestandardowego obiektu i umieszczeniu go w zmiennej:

$obj = New-Object PSObject

Dzięki temu otrzymujemy nowy, gotowy do pracy obiekt. Następnie dodajemy do obiektu dane w postaci właściwości. W tym celu po prostu przesyłamy obiekt potokiem do polecenia cmdlet Add-Member. Dodajemy właściwość NoteProperty, nadajemy jej nazwę (dobrym pomysłem jest wykorzystanie nagłówków kolumn w roli nazw właściwości), a następnie wstawiamy dane w postaci wartości właściwości:

$obj | Add-Member NotePropertyColumnA $data1

$obj | Add-Member NotePropertyColumnB $data2

$obj | Add-Member NotePropertyColumnC $data3

A teraz po prostu wyprowadzamy ten obiekt, nie do konsoli, ale do potoku:

Write-Output $obj

Następnie powtarzamy te czynności dla każdego wiersza w tabeli, który musimy wyprowadzić. Poniżej zaprezentowana została krótka funkcja, która akceptuje ciąg i wyprowadza jego wersje: oryginalną, z wielkimi literami i z małymi literami:

functionStringVersions {

param([string]$inputString)

  $obj = New-Object PSObject

  $obj | Add-Member NoteProperty Original($inputString)

  $obj | Add-Member NoteProperty Uppercase($inputString.ToUpper())

  $obj | Add-Member NoteProperty Lowercase($inputString.ToLower())

  Write-Output $obj

}  

$strings = @("one","two","three")

foreach ($item in $strings) {

StringVersions $item

}

Rozpoczynamy od tablicy zmiennych typu string, przechodząc przez każdą z nich jednokrotnie i przesyłając ją do funkcji. Dane wyjściowe funkcji zostają zapisane w potoku.

Warto zauważyć, że istnieją krótsze metody zapisania tego kodu, ale wybraliśmy tę technikę, ponieważ czytelniej ilustruje ona sens realizowanego zadania. Wynik, pokazany na Rysunku 1, to idealnie sformatowana tabela. A to dlatego, że powłoka sama obsługuje formatowanie obiektów tabeli.

Rysunek 1: Dane wyjściowe Windows PowerShell wyświetlane w tabeli.

Gdy obiekt posiada co najwyżej cztery właściwości, powłoka Windows PowerShell automatycznie wybiera opcję tabeli. A zatem bez żadnego wysiłku z naszej strony otrzymujemy świetnie prezentującą się tabelę.

 Do początku strony Do początku strony

Ale to jeszcze nie koniec!

Korzyści zastosowania tej techniki obejmują nie tylko formatowanie tabelaryczne. Gdy pracujemy z obiektami, Windows PowerShell wspiera realizację wielu funkcjonalności. Chcemy umieścić dane w pliku CSV? Wystarczy użyć polecenia Export-CSV. Bardziej odpowiada nam tabela HTML? Możemy przesłać obiekty potokiem do polecenia ConvertTo-HTML. Zależy nam na formatowaniu listowym? Przesyłamy je potokiem do Format-List. Zastosowanie obiektów sprawia, że możemy wykorzystywać wszystkie funkcje, które mogą być realizowane przez powłokę. Oto ulepszona wersja przykładu:

functionStringVersions {

  PROCESS {

   $obj = New-Object PSObject

   $obj | Add-Member NoteProperty Original($_)

   $obj | Add-Member NoteProperty Uppercase($_.ToUpper())

   $obj | Add-Member NoteProperty Lowercase($_.ToLower())

   Write-Output $obj

}

}

Tym razem zmodyfikowaliśmy funkcję tak, aby akceptowała ona wejście w postaci potoku (to zawsze dobry pomysł w przypadku z pracy z obiektami) i wyprowadzała dane do potoku.

Teraz kod funkcji znajduje się w bloku skryptu PROCESS. A to oznacza, że funkcja zaakceptuje wejście w postaci potoku i wykona blok skryptu PROCESS jednokrotnie do każdego przesłanego w potoku obiektu.

Znajdująca się w bloku skryptu PROCESS specjalna zmienna $_ odwołuje się do aktualnie przetwarzanego obiektu. Praktyczny efekt jest taki, że możemy teraz po prostu przesłać w potoku łańcuch ciągów:

@("one","two","three") | StringVersions

Otrzymamy tabelę, ponieważ funkcja umieszcza swoje dane wyjściowe w potoku. A na końcu potoku powłoka wywołuje swój własny podsystem formatowania, który podejmuje decyzję o wykorzystaniu tabeli, ponieważ strumień zawiera mniej niż pięć właściwości (dla większej liczby właściwości powłoka stosuje domyślnie format listy).

Choć wcale nie musimy polegać na domyślnym działaniu. Możemy po prostu przesłać te obiekty w potoku do innego polecenia cmdlet, aby wykonać na nich inną operację:

@("one","two","three") | StringVersions | Format-List

@("one","two","three") | StringVersions | ConvertTo-HTML | Out-File "strings.html"

@("one","two","three") | StringVersions | Export-CSV "strings.csv"

@("one","two","three") | StringVersions | Select Uppercase,Lowercase -unique

Rysunek 2 prezentuje wynikowy dokument HTML z drugiego przykładu wyświetlony w przeglądarce sieci Web. Reprezentowanie danych wyjściowych przy pomocy obiektów zamiast zwykłego tekstu daje nam pełny dostęp do bogactwa funkcji, które są wbudowane w powłokę: różnorodnych układów formatowania, konwersji HTML, opcji eksportowania, możliwości sortowania, filtrowania, grupowania i wielu innych.

Rysunek 2: Dane wyjściowe Windows PowerShell w formacie HTML.

Takie podejście zapewnia ogromne możliwości. Co więcej, autor niniejszego artykułu zachęca czytelników, aby wszystkie tworzone przez nich skrypty zwracały dane wyjściowe w postaci obiektów. Dzięki temu mogą być one wykorzystywane na wiele różnych sposobów. A wszystko to bez pisania ani jednej dodatkowej linii kodu.

 Do początku strony Do początku strony

Dodatkowe materiały

Video

Obejrzyjmy, jak Don Jones demonstruje prostą metodę dodawania formatowania do danych wyjściowych Windows PowerShell.

Cmdlet miesiąca: Get-Command

Z pewnością wielu czytelników korzystało już choć raz z polecenia Get-Command lub jego podręcznego aliasu (gcm) w celu wyświetlenia listy dostępnych poleceń cmdlet Windows PowerShell. Jednak być może nie wszyscy wiedzą, jak elastyczne jest polecenie gcm. Na przykład, jeśli chcemy zobaczyć wszystkie operacje, jakie powłoka Windows PowerShell może wykonać na usłudze, uruchamiany polecenie gcm -noun service. Jeśli chcemy zobaczyć wszystkie opcje eksportu oferowane przez powlokę Windows PowerShell, wpisujemy gcm -verb export. Jeśli potrzebujemy sprawdzić, jakie polecenia cmdlet zostały dodane przez określoną przystawkę, taką jak PowerShell Community Extensions, wpisujemy gcm -pssnapin pscx (możemy zastąpić "pscx" nazwą dowolnej przystawki, aby poznać jej polecenia cmdlet).

Jak widzimy, polecenie Get-Command stanowi kluczową metodę, ułatwiającą poznawanie możliwości powłoki Windows PowerShell. Pozwala nam odkrywać, jakie funkcje są dostępne, bez konieczności korzystania z podręcznika. Co więcej, polecenie gcm jest bardziej precyzyjnym sposobem odkrywania funkcjonalności niż na przykład polecenie Help *. Funkcja Help wymienia jedynie listę dostępnych tematów pomocy. Polecenia cmdlet, które nie oferują pomocy, nie są prezentowane na tej liście, mimo iż są one dostępne i moglibyśmy je wykorzystać.

O autorze

Don Jones jest ekspertem w zakresie automatyzacji zadań administracyjnych w systemie Windows oraz autorem wielu książek między innymi Windows PowerShell: TFM oraz VBScript, WMI, and ADSI Unleashed. Można skontaktować się z nim za pośrednictwem forów w witrynie ScriptingAnswers.com.

 Do początku strony Do początku strony

Windows Server 2008