Podstawy PowerShell: Obiekty niestandardowe

Windows PowerShell jest środowiskiem typu command-shell, które obsługuje skryptowanie zorientowane obiektowo w oparciu o Microsoft .NET Framework. Jego sercem jest cmdlet PowerShell, lekkie polecenie, które wykonuje określoną akcję, a w procesie zwraca obiekt .NET. PowerShell pozwala na używanie cmdletów do uzyskiwania dostępu do różnych systemów i wykonywania wielu zadań na tych systemach. Jednak same polecenia cmdlet nie zawsze są wystarczające do wykonania pewnych akcji. Aby wykonać te czynności, często trzeba stworzyć własne obiekty oparte na klasach .NET. Jednym z typów obiektów .NET, które możesz zbudować jest obiekt niestandardowy. Obiekt niestandardowy pozwala na zdefiniowanie typów danych przypisanych do tego obiektu oraz akcji, które może on wykonywać. Po zrozumieniu, jak zbudować obiekt niestandardowy, będziesz miał potężne narzędzie do budowania skryptów, które mogą rozszerzyć i tak już znaczący zasięg PowerShella.

Zauważ, że .NET Framework i programowanie zorientowane obiektowo są złożonymi tematami, znacznie wykraczającymi poza zakres tego rozdziału. Aby w pełni docenić obiektową naturę PowerShella, pomocne może być przynajmniej podstawowe zrozumienie tych koncepcji. Więcej informacji na temat .NET Framework można znaleźć w artykule MSDN „Overview of the .NET Framework.” Wprowadzenie do programowania obiektowego można znaleźć w artykule MSDN „Programowanie obiektowe (C# i Visual Basic).”

Tworzenie obiektu niestandardowego

Aby utworzyć obiekt niestandardowy w PowerShell, należy najpierw użyć cmdleta Nowy-Objekt do zbudowania obiektu początkowego. Ten cmdlet pozwala na tworzenie obiektów .NET lub COM z zestawu klas. Obiekt niestandardowy jest specjalnym typem obiektu .NET opartym na klasie Object lub PSObject .NET. Podczas tworzenia obiektu początkowego nie ma różnicy pomiędzy tymi dwoma. Jednak klasa PSObject jest ogólnie preferowana ze względu na problemy, które mogą się pojawić podczas dodawania właściwości do obiektu opartego na klasie Object, więc użyjmy PSObject.

Aby utworzyć obiekt oparty na klasie PSObject, musisz użyć cmdletu New-Object z parametrem -TypeName i określić klasę PSObject jako wartość parametru, tak jak poniżej:

$system = New-Object -TypeName PSObject

Gdy uruchomisz to polecenie, wygeneruje ono obiekt PSCustomObject i przypisze go do zmiennej $system. Częściej niż nie, będziesz chciał przypisać obiekt do zmiennej tak, abyś mógł łatwo pracować z członkami tego obiektu. Członkowie są komponentami, które tworzą obiekt, takimi jak właściwości, metody, właściwości alias i zestawy członków.

Podczas pracy z obiektami w PowerShell, dwa typy członków, których prawdopodobnie będziesz używał to właściwości i metody. Właściwość opisuje konkretny aspekt obiektu. Na przykład, jednym z członków klasy FileInfo .NET jest właściwość Length, która podaje rozmiar pliku w bajtach. Jeśli stworzysz obiekt FileInfo bazujący na tej klasie, możesz użyć właściwości Length by uzyskać dostęp do rozmiaru pliku powiązanego z tym obiektem. Metoda wykonuje akcję związaną z obiektem. Na przykład, klasa FileInfo zawiera również metodę Delete, której możesz użyć do usunięcia pliku reprezentowanego przez obiekt.

Możliwość łatwej identyfikacji członków obiektu ułatwia pracę z tym obiektem. Aby uzyskać listę członków, którzy tworzą obiekt, możesz użyć polecenia cmdlet Get-Member. Na przykład, aby przejrzeć członków nowego obiektu, który został przypisany do zmiennej $system, można przekazać zmienną $system do cmdleta Get-Member:

$system | Get-Member

Jak widać na rysunku 1, utworzony obiekt jest oparty na klasie System.Management.Automation.PSCustomObject, która zawiera tylko niewielką liczbę członków, z których wszyscy są metodami. Ale właśnie dlatego jest on nazywany obiektem niestandardowym – możesz go dostosować poprzez dodanie własnych członków.

Figure 1: Lista członków nowego obiektu

Zanim pokażę jak dodać członków, pozwól mi tylko dodać, że jak wiele klas .NET, klasa PSCustomObject zawiera również pewną liczbę ukrytych członków różnych typów, takich jak memberset i codeproperty. Możesz zobaczyć tych członków poprzez włączenie parametru -Force podczas wywoływania cmdleta Get-Member. Chociaż omówienie ukrytych członków wykracza poza zakres tego rozdziału, może okazać się przydatne w pewnym momencie zbadanie ukrytych członków dostępnych dla klasy PSCustomObject i innych klas .NET, aby w pełni wykorzystać możliwości obiektów PowerShell.

Dodawanie właściwości do obiektu niestandardowego

Obiekt niestandardowy jest tylko tak użyteczny, jak członkowie z nim związani. Do obiektu niestandardowego można dodać kilka różnych typów członków. W tym przykładzie zostaną dodane właściwości NoteProperty i ScriptMethod. Członek NoteProperty jest podobny do zwykłej właściwości, a członek ScriptMethod jest podobny do zwykłej metody. Nie można dodać zwykłej właściwości lub metody do obiektu niestandardowego, dlatego też będziemy używać członków NoteProperty i ScriptMethod. (Aby uzyskać informacje na temat obsługiwanych członków w obiekcie niestandardowym, zobacz temat PowerShell TechNet „Add-Member.”)

Zacznijmy od dodania kilku członków NoteProperty do obiektu $system. Aby dodać członków, możesz użyć cmdleta Add-Member do zdefiniowania nazw i wartości właściwości. Na przykład, załóżmy, że chcesz dodać właściwości Note na podstawie danych pobranych za pomocą możliwości Windows Management Instrumentation (WMI) wbudowanych w PowerShell. (WMI zapewnia infrastrukturę do zarządzania danymi i operacjami w systemach operacyjnych Windows). Model obiektowy WMI zawiera liczne klasy, które obsługują szeroki zakres operacji zarządzania. Na przykład klasa Win32_OperatingSystem zapewnia dostęp do takich informacji, jak nazwa systemu operacyjnego zainstalowanego na komputerze i najnowszy dodatek Service Pack zastosowany do tego systemu operacyjnego.

Aby utworzyć obiekt WMI, należy użyć polecenia cmdlet Get-WmiObject i określić żądaną klasę. Na przykład, aby utworzyć obiekt WMI Win32_OperatingSystem i przypisać go do zmiennej $os, należy użyć następującego kodu:

$os = Get-WmiObject Win32_OperatingSystem

W tym przypadku pobierane są informacje o systemie z lokalnego komputera, ale piękno WMI polega na jego zdolności do uzyskiwania dostępu i zarządzania zdalnymi komputerami Windows.

Można następnie użyć zmiennej $os, aby uzyskać dostęp do informacji zwróconych przez ten obiekt. Przypisanie obiektu do zmiennej w ten sposób blokuje dane w tym punkcie w czasie. Na przykład, jeśli nowy Service Pack zostanie zastosowany do systemu operacyjnego po utworzeniu zmiennej $os, właściwość CSDVersion obiektu nie będzie odzwierciedlać zmiany, ponieważ obiekt został utworzony na podstawie oryginalnych danych.

Po zdefiniowaniu zmiennej $os należy określić dwa polecenia Add-Member. Każde polecenie będzie przyjmowało cztery parametry:

  • -InputObject. Parametru -InputObject używamy do określenia obiektu, który ma otrzymać nowe właściwości notatki. W tym przypadku należy określić obiekt $system.
  • -MemberType. Parametr -MemberType wskazuje typ członka, który ma zostać utworzony, dlatego należy określić NoteProperty.
  • -Name. Używasz parametru -Name, aby określić nazwę nowego członka. W tym przykładzie nazwiemy pierwszego członka OperatingSystem i drugiego członka ServicePack.
  • -Value. Ten parametr określa wartość członka. Dla pierwszej właściwości notatki, musisz określić $os.Caption, aby zwrócić nazwę systemu operacyjnego. Dla drugiej właściwości notatki należy określić $os.CSDVersion, aby zwrócić najnowszy Service Pack zastosowany do systemu operacyjnego.

Oto jak wyglądają dwa polecenia Add-Member:

Add-Member -InputObject $system -MemberType NoteProperty ` -Name OperatingSystem -Value $os.CaptionAdd-Member -InputObject $system -MemberType NoteProperty ` -Name ServicePack -Value $os.CSDVersion

Zauważ, że rozbiłem każde polecenie Add-Member na dwie linie. Na końcu każdej pierwszej linii umieściłem znacznik powrotu (`), aby procesor PowerShell wiedział, że ma kontynuować do następnej linii, aby uzyskać kompletne polecenie.

Po uruchomieniu poleceń Add-Member można wywołać zmienną $system, aby zobaczyć jej zawartość:

$system

Rysunek 2 pokazuje przykładowe wyniki.

Rysunek 2: Zawartość zmiennej $system

Można również użyć zmiennej $system do wywołania poszczególnych członków. Wystarczy podać nazwę zmiennej, po niej kropkę, a następnie nazwę członka. Na przykład, następujące polecenie zwraca aktualną wartość właściwości notatki OperatingSystem:

$system.OperatingSystem

Jedną z zalet tworzenia niestandardowego obiektu jest to, że pozwala on na tworzenie właściwości notatki na podstawie danych pochodzących z różnych źródeł, jak również właściwości notatki, której wartością jest określony ciąg znaków. Na przykład, spójrz na kod na Listingu 1, który dodaje trzy nowe właściwości notatki do obiektu $system.

$mem = Get-WmiObject Win32_PhysicalMemory$disk = Get-WmiObject Win32_DiskDriveAdd-Member -InputObject $system -MemberType NoteProperty ` -Name PhysicalMemory ` -Value (("{0:N2}" -f ($mem.Capacity/1GB)) + ' GB')Add-Member -InputObject $system -MemberType NoteProperty ` -Name DiskSize ` -Value (("{0:N2}" -f ($disk.Size/1GB)) + ' GB')Add-Member -InputObject $system -MemberType NoteProperty ` -Name Owner -Value "janetp"

Większość elementów na Listingu 1 widziałeś w poprzednim przykładzie. Zauważ jednak, że kod tworzy instancję klasy Win32_PhysicalMemory, która jest przypisana do zmiennej $mem, oraz instancję klasy Win32_DiskDrive, która jest przypisana do zmiennej $disk. Dwie z dodanych właściwości notatki wykorzystują te nowe obiekty WMI jako źródła danych.

Pierwsze polecenie Add-Member pobiera dane z właściwości $mem.Capacity, która podaje pojemność pamięci w systemie docelowym. W tym przypadku jednak parametr -Value jest nieco bardziej złożony niż w poprzednim przykładzie. Po pierwsze, polecenie określa „{0:N2}”, po którym następuje -f, co jest konstrukcją .NET służącą do formatowania wypisywanej liczby. Zasadniczo, określa to, że liczba ma być zwrócona z dwoma miejscami po przecinku. Po instrukcji formatowania następuje krótkie wyrażenie ($mem.Capacity/1GB), które dzieli wartość Capacity przez 1GB. Wartość Capacity podaje rozmiar pamięci w bajtach. PowerShell ułatwia konwersję bajtów na gigabajty po prostu dzieląc przez 1GB. Na koniec polecenie umieszcza na wyjściu ciąg znaków ’ GB’ (wraz ze spacją) i zamyka całość w nawiasach.

Drugie polecenie Add-Member postępuje według tej samej logiki, aby zwrócić rozmiar dysku twardego komputera. Używa właściwości $disk.Size do zwrócenia rozmiaru w bajtach, a następnie konwertuje go na gigabajty.

Trzecie polecenie Add-Member dodaje właściwość note o nazwie Owner i przypisuje jej wartość łańcuchową janetp. W tym przypadku „właściciel” może oznaczać cokolwiek – głównego użytkownika, ostatniego użytkownika, administratora lub jakiekolwiek inne znaczenie, które chcesz narzucić tej właściwości. Zamieściłem ją tutaj tylko po to, aby zademonstrować, że można dodać właściwość note, której wartością jest zwykły łańcuch znaków.

Po dodaniu trzech członków do obiektu niestandardowego, możesz ponownie wywołać zmienną $system. Zwróci ona wyniki, jak te pokazane na rysunku 3.

Rysunek 3: Właściwości Note dodane za pomocą polecenia Add-Member

Masz teraz pojedynczy obiekt, który zawiera dane pochodzące z trzech różnych obiektów WMI. Obiekt zawiera również właściwość Owner, która jest oparta na wartości łańcuchowej. Możesz wywołać tę właściwość Note tak samo, jak każdego innego członka:

$system.Owner

Jak można się spodziewać, polecenie zwraca wartość janetp. Można jednak zmienić tę wartość na inną, przypisując nową wartość do właściwości, jak poniżej:

$system.Owner = "rogert"

W tym przypadku wartość rogert została przypisana do właściwości Notatka właściciela. Jeśli teraz wywołasz tę właściwość notatki, zwróci ona nową wartość.

Podobnie jak w przypadku wielu zadań, które można wykonać w PowerShell, istnieje wiele różnych sposobów dodania członka do obiektu niestandardowego. Na przykład, PowerShell 3.0 pozwala utworzyć tablicę hash i przekazać hash do polecenia New-Object. Kod na Listingu 2 tworzy te same pięć właściwości notatki, ale używa tablicy hash do przekazania nazw i wartości członków.

$info = @{ "OperatingSystem" = $os.Caption; "ServicePack" = $os.CSDVersion; "PhysicalMemory" = (("{0:N2}" -f ($mem.Capacity/1GB)) + ' GB'); "DiskSize" = (("{0:N2}" -f ($disk.Size/1GB)) + ' GB'); "Owner" = 'janetp'}$system = New-Object -TypeName PSObject -Property $info$system

Kod ten najpierw tworzy tablicę hash, która definiuje pięć par właściwość/wartość, z których każda odpowiada właściwości notatki. Jak pokazuje kod, należy oddzielić pary właściwość/wartość średnikami. Należy również zawrzeć zestaw pięciu par właściwość/wartość w nawiasach klamrowych i poprzedzić nawias otwierający symbolem at (@). Na koniec należy przypisać tablicę haszującą do zmiennej $info.

Po zdefiniowaniu tablicy haszującej kod wykorzystuje cmdlet New-Object do utworzenia obiektu opartego na klasie PSObject i przypisuje go do zmiennej $system. Tylko tym razem polecenie zawiera parametr -Property, który przyjmuje zmienną $info jako swoją wartość.

Na koniec kod wywołuje zmienną $system, która zwraca wyniki takie jak na rysunku 4. Zwróć uwagę na kolejność, w jakiej właściwości zostały dodane do obiektu. Jednym z problemów związanych z użyciem tablicy haszującej do dodawania właściwości notatek jest to, że nie można kontrolować ich kolejności. Aby kontrolować kolejność, musisz użyć cmdleta Add-Member do dodania każdego członka.

Rysunek 4: Właściwości notatki utworzone za pomocą tablicy haseł

Dodawanie metod do obiektu niestandardowego

Teraz, gdy zobaczyłeś, jak łatwo jest dodawać właściwości, uzyskiwać dostęp do ich wartości i zmieniać te wartości, przejdźmy do metod. Stają się one nieco bardziej skomplikowane, ponieważ metody muszą coś robić i musisz zdefiniować to coś jako część wartości metody.

Na przykład, kod na Listingu 3 tworzy metodę, która pobiera aktualną datę i czas oraz zwraca je zarówno w oryginalnym formacie, jak i jako wartości uniwersalnego czasu koordynowanego (UTC).

$method ={ $a = Get-Date -Format F; "Local: " + $a; $b = Get-Date; "UTC: " + $b.ToUniversalTime().DateTime}Add-Member -InputObject $system -MemberType ScriptMethod ` -Name GetUTC -Value $method

Aby kod był czytelny, możesz przypisać wartość metody do zmiennej (np. $method). Wartość ta zawiera wyrażenia niezbędne do zwrócenia informacji o dacie i czasie. Aby jednak przekazać tę wartość do polecenia Add-Member, musisz ją zdefiniować jako blok skryptu. Aby to zrobić, należy zawrzeć zawartość wartości w nawiasach klamrowych. PowerShell przypisze wtedy wartość w jej aktualnej postaci do zmiennej jako obiekt ScriptBlock.

Na listingu 3 wartość metody zawiera dwa wyrażenia. Pierwsze wyrażenie zwraca bieżącą datę i czas, a drugie – wersję UTC. Pierwsze wyrażenie rozpoczynamy od użycia polecenia cmdlet Get-Date w celu pobrania bieżącej daty i godziny, którą przypisujemy do zmiennej $a. Zauważ, że kiedy wywołujesz cmdlet Get-Date, musisz dołączyć parametr -Format, wraz z wartością F. To mówi PowerShellowi, aby wyświetlić znacznik czasu w pełnym formacie daty i czasu, jak w poniedziałek, 19 sierpnia 2013 12:28:25 PM. Następnie dodajemy ciąg „Local: ” (wraz ze spacją) do wartości zmiennej, aby zwrócić bieżącą datę i godzinę wraz z tą etykietą.

W drugim wyrażeniu ponownie zaczynamy od cmdleta Get-Date, aby zwrócić bieżącą datę i godzinę, którą przypisujemy do zmiennej $b. Następnie używamy metody ToUniversalTime zmiennej, aby zwrócić datę i czas jako wartość UTC, a następnie określamy właściwość DateTime, aby zwrócić prawidłowy format.

Jeżeli w tym momencie wywołalibyśmy zmienną $method, zwróciłaby ona dwa wyrażenia jako ciągi znaków, tak jak zostały wpisane. Ponieważ zdefiniowałeś wartość zmiennej jako blok skryptu, polecenia nie są przetwarzane, kiedy są przypisywane do zmiennej $method. Zamiast tego zmienna $method jest wytworzona jako obiekt ScriptBlock, co można potwierdzić przy pomocy metody GetType, aby zobaczyć typ zmiennej:

$method.GetType()

Aby pracować z blokiem skryptowym, trzeba po zdefiniowaniu zmiennej $method dodać metodę jako członka obiektu $system. W tym celu tworzymy polecenie Add-Member, które określa ScriptMethod jako typ, GetUTC jako nazwę i zmienną $method jako wartość.

Po uruchomieniu kodu z Listingu 3, możesz użyć zmiennej $system do wywołania metody GetUTC w taki sam sposób, w jaki wywołałeś właściwości:

$system.GetUTC()

Zauważ jednak, że kiedy wywołujesz metodę skryptu, musisz dołączyć nawiasy, tak jak w przypadku każdej innej metody, nawet jeśli nie przekazujesz argumentów. Metoda powinna teraz zwrócić wyniki podobne do tych na rysunku 5, ale z datą i godziną wywołania metody.

Rysunek 5: Przykładowe wyniki metody GetUTC()

W prawdziwym życiu, prawdopodobnie będziesz chciał stworzyć metody, które będą miały większą siłę przebicia. Na przykład, obiekt $system może zawierać zadania zarządzania WMI w swoich metodach skryptowych. Jeśli to zrobisz, musisz w pełni przetestować metodę, aby upewnić się, że twoje polecenia robią dokładnie to, co powinny robić. PowerShell i WMI są potężnymi narzędziami, więc powinny być używane z ostrożnością podczas zarządzania komputerami Windows.

Dodawanie obiektów niestandardowych do tablicy

Obiekty niestandardowe nie są ograniczone do samodzielnych obiektów, których używamy raz i odkładamy na bok. Możesz dodać te obiekty do tablicy obiektów, a następnie uzyskać dostęp do obiektów poprzez tę tablicę. Na przykład, załóżmy, że chcesz manipulować informacjami pobieranymi z wielu komputerów. Informacje te mogą zawierać szczegóły dotyczące pamięci i dysków logicznych dostępnych w tych systemach. Chcesz być w stanie pracować z tymi szczegółami w znaczący sposób w PowerShell. Ze względu na obiektową naturę PowerShella, umieszczenie tych informacji w obiektach jest często najprostszym sposobem pracy z tymi danymi.

Przyjrzyjrzyjmy się przykładowi, jak można to zrobić. Dla tej dyskusji nie ma znaczenia, jakie podejście zostało użyte do zbierania informacji o różnych komputerach. Można na przykład skonfigurować pętlę foreach w PowerShell, która używa WMI do pobierania informacji z różnych stacji roboczych. Niezależnie od zastosowanej metody, dla zachowania zwięzłości przyjmijmy, że informacje zostały zebrane do pliku tekstowego oddzielonego przecinkami, który zawiera dane przedstawione na rysunku 6.

Rysunek 6: Zebrane dane WMI

Plik tekstowy zawiera wiersz nagłówka i wiersz dla każdego systemu dysków logicznych. Na przykład pierwszy wiersz danych zawiera szczegółowe informacje o dysku logicznym C na komputerze ws01. Dysk logiczny ma pojemność 500 GB, z 225 GB wolnego miejsca. System posiada również 4GB pamięci. Drugi wiersz wskazuje, że ten sam komputer zawiera również dysk logiczny D, który ma taką samą pojemność jak dysk C, ale 320 GB wolnego miejsca.

Celem jest przekształcenie każdego wiersza danych w jego własny obiekt niestandardowy, a następnie dodanie tych obiektów do tablicy. Następnie można podjąć działania na obiektach w obrębie tablicy, przekazując dane do innych poleceń PowerShell. Kod na Listingu 4 definiuje pustą tablicę, importuje dane z pliku tekstowego, a następnie używa pętli foreach do tworzenia obiektów i dodawania ich do tablicy.

$SystemInfo = @()$SourceData = Import-CSV C:\DataFiles\SourceData.txtforeach ($source in $SourceData){ $system = New-Object -TypeName PSObject $system | Add-Member -Type NoteProperty ` -Name Computer -Value $source.Computer $system | Add-Member -Type NoteProperty ` -Name DeviceID -Value $source.DeviceID $system | Add-Member -Type NoteProperty ` -Name DriveSize -Value ($source.DriveSize) $system | Add-Member -Type NoteProperty ` -Name UsedSpace ` -Value ($source.DriveSize - $Source.FreeSpace) $system | Add-Member -Type NoteProperty ` -Name FreeSpace -Value ($source.FreeSpace) $SystemInfo += $system}

Jak widać, pierwszym krokiem jest utworzenie pustej tablicy (@()) i przypisanie jej do zmiennej $SystemInfo. Następnie używamy cmdleta Import-CSV, aby zaimportować dane do zmiennej $SourceData. W tym ćwiczeniu plik tekstowy nosi nazwę SourceData.txt i został zapisany w folderze C:DataFiles. Polecenie Importuj-CSV pobiera każdy wiersz jako własny obiekt i zapisuje go w $SourceData. W tym momencie mógłbyś użyć tej zmiennej, aby uzyskać dostęp do danych, ale nie miałbyś kontroli nad członkami zawartymi w obiekcie, ani nie byłbyś w stanie dodawać członków.

Następnym krokiem jest utworzenie pętli foreach, która pozwala na utworzenie niestandardowego obiektu dla każdego wiersza w pliku tekstowym. Warunek foreach ($source in $SourceData) określa, że każdy wiersz w $SourceData powinien być przypisany do zmiennej $source, gdy kod iteruje przez pętlę foreach. Logika zdefiniowana wewnątrz bloku skryptu foreach (zawarta w nawiasach klamrowych) zostanie uruchomiona jeden raz dla każdego wiersza, z innym obiektem $source zastosowanym podczas każdej iteracji. (Więcej informacji na temat tworzenia pętli foreach można znaleźć w temacie TechNet PowerShell about_ForEach.)

Przyjrzyjrzyjmy się bliżej blokowi skryptu foreach. Pierwsze polecenie tworzy obiekt początkowy i zapisuje go do zmiennej $system, tak jak to widzieliśmy w poprzednich przykładach. Następnie zmienna $system jest przesyłana do polecenia Add-Member w celu utworzenia pierwszej właściwości note. Jest to nieco inny format niż używany poprzednio. Zamiast dołączać parametr -InputObject do polecenia Add-Member, po prostu przesyłasz $system do polecenia. Osiąga to te same rezultaty, które widziałeś we wcześniejszych przykładach komend Add-Member. Zastosowałem to podejście tutaj, aby zademonstrować jeszcze jeden sposób, w jaki PowerShell pozwala dodawać członków.

Dla wartości polecenia Add-Member używasz zmiennej $source, aby wywołać właściwość Computer, która odpowiada polu Computer w danych źródłowych. Drugie polecenie Add-Member działa w ten sam sposób, z tą różnicą, że pobiera dane z właściwości DeviceID. Zauważ, że właściwość Memory nie jest uwzględniona. Kiedy tworzysz obiekt niestandardowy, możesz pominąć określone właściwości lub umieścić je w innej kolejności.

Trzecie polecenie Add-Member działa podobnie jak dwa pierwsze, z wyjątkiem tego, że uzyskuje dostęp do właściwości DriveSize. Ponieważ możesz chcieć pracować z tymi danymi jako wartością numeryczną, a nie jako łańcuchem, polecenie to jawnie konwertuje dane na liczbę. Osiąga się to przez poprzedzenie nazwy właściwości znakiem wskazującym na typ danychint, a następnie zamknięcie całego wyrażenia właściwości w nawiasach.

Czwarte polecenie Add-Member robi coś nieco innego. Tworzy ono element obliczeniowy, który odejmuje wartość FreeSpace od wartości DriveSize w celu określenia ilości wykorzystanego miejsca. Ponownie, nazwa właściwości jest poprzedzona znakiem i całe wyrażenie jest ujęte w nawiasy. Możliwość tworzenia właściwości obliczanych jest jednym z głównych powodów, dla których można chcieć tworzyć obiekty niestandardowe.

Ostatnie polecenie Add-Member działa tak samo jak trzecie, z tą różnicą, że pobiera dane z właściwości FreeSpace.

Ostatnie polecenie w bloku skryptu foreach dodaje bieżący obiekt $system do tablicy $SystemInfo. Zauważ, że operator += jest używany, aby zapewnić, że nowy obiekt $system jest dodawany przy każdej iteracji pętli, bez nadpisywania czegokolwiek.

Po uruchomieniu kodu z Listingu 4 możesz wywołać zmienną, aby zobaczyć jej zawartość. Rysunek 7 pokazuje częściową listę danych przechowywanych teraz w tablicy $SystemInfo.

Rysunek 7: Dane przechowywane w tablicy $SystemInfo

Szczegółowo, pokazuje dane dla pierwszych siedmiu obiektów w tablicy, co odpowiada pierwszym siedmiu wierszom danych w oryginalnym pliku tekstowym. Każde zgrupowanie reprezentuje jeden z obiektów dodanych do tablicy $SystemInfo. Możesz sprawdzić, czy utworzyłeś tablicę obiektów używając metody GetType do pobrania typu zmiennej:

$SystemInfo.GetType()

Jeśli to polecenie zwraca BaseType of System.Array, zmienna $SystemInfo jest rzeczywiście tablicą obiektów zdolną do przechowywania niestandardowych obiektów. Możesz następnie użyć tej zmiennej do manipulowania danymi, jakkolwiek uznasz to za stosowne. Na przykład można przesłać zmienną do polecenia Sort-Object, aby posortować dane w porządku malejącym na podstawie wartości FreeSpace:

$SystemInfo | Sort FreeSpace -Descending

W tym przypadku polecenie używa aliasu Sort do odwołania się do cmdletu Sort-Object i zawiera właściwość FreeSpace oraz parametr -Descending. Jak widać na rysunku 8, obiekty są teraz uszeregowane według wartości FreeSpace, z największą ilością wolnego miejsca na liście jako pierwsze. Ponownie, jest to tylko częściowa lista.

Rysunek 8: Dane posortowane według ilości wolnego miejsca

Można również posortować dane na podstawie wielu kolumn. Na przykład można posortować dane najpierw według właściwości Computer, a następnie FreeSpace, w kolejności malejącej:

$SystemInfo | Sort Computer, FreeSpace -Descending

Jak można się spodziewać, wyniki są teraz znacznie inne, jak pokazuje Rysunek 9.

Rysunek 9: Dane posortowane według nazwy komputera i ilości wolnego miejsca w porządku malejącym

Jedną z konsekwencji sortowania kolumn w ten sposób jest to, że wartości Komputer, jak również wartości Wolne miejsce są posortowane w porządku malejącym. Polecenie cmdlet Sort-Object nie pozwala na łatwe sortowanie jednej kolumny w kolejności rosnącej, a drugiej w malejącej. Jeśli podasz parametr -Descending, wszystkie dane zostaną posortowane w tej kolejności. Można jednak obejść to ograniczenie, tworząc wyrażenia dla każdej właściwości, które określają sposób sortowania tych wartości. Na przykład następujące polecenie sortuje najpierw według właściwości Computer w kolejności rosnącej, a następnie według właściwości FreeSpace w kolejności malejącej:

$SystemInfo | Sort ` @{Expression="Computer"; Descending=$false}, @{Expression="FreeSpace"; Descending=$true}

Pierwsze wyrażenie Sort-Object ustawia właściwość Expression na Computer, a właściwość Descending na $false. Drugie wyrażenie ustawia właściwość Expression na FreeSpace i właściwość Descending na $true. (Zmienne $true i $false są wbudowanymi zmiennymi systemowymi, które zapewniają prawdziwe i fałszywe wartości logiczne, odpowiednio 1 i 0). Następnie należy zamknąć każde wyrażenie w nawiasach klamrowych i poprzedzić każdy nawias otwierający znakiem at (@). Teraz dane zostaną posortowane w żądanej kolejności, jak pokazano na rysunku 10.

Rysunek 10: Dane posortowane według nazwy komputera w porządku rosnącym i ilości wolnego miejsca w porządku malejącym

Może się to wydawać przesadą w temacie sortowania, ale wskazuje na elastyczność pracy z obiektami w tablicy. I z pewnością nie jesteś ograniczony do polecenia cmdlet Sort-Object. Na przykład następujące polecenie przesyła zmienną $SystemInfo do narzędzia Where-Object:

$SystemInfo | Where DriveSize -gt 250 | Sort FreeSpace -Descending

W tym przypadku polecenie używa aliasu Where do odwołania się do narzędzia Where-Object. Ponadto określa, że wartość DriveSize musi być większa niż 250, aby została uwzględniona w wynikach. (Wyniki spełniające te kryteria są przesyłane do cmdleta Sort-Object, dzięki czemu dane są wyświetlane w odpowiedniej kolejności.

Można nawet przesłać posortowane dane do polecenia Select-Object, jak poniżej:

$SystemInfo | Where DriveSize -gt 250 | Sort FreeSpace -Descending | Select -First 5

To polecenie używa cmdleta Select-Object (odwołującego się do aliasu Select), aby zwrócić tylko pięć pierwszych wierszy zestawu wyników. Jak widać, po dodaniu niestandardowych obiektów do tablicy $SystemInfo, masz wiele opcji pracy z tymi obiektami.

Making the Most of Your Custom Objects

Przez większość czasu, tworzenie niestandardowych obiektów w PowerShell jest dość prostym procesem. Jeśli jest w tym jakaś złożoność, to zazwyczaj wynika ona z wyrażeń wartości, które definiujemy dla właściwości notatki lub metod skryptu. Wyrażenia w tych przykładach są stosunkowo proste w porównaniu z typami wyrażeń, które można tworzyć w PowerShell. Mimo to, to co tutaj zobaczyłeś powinno dostarczyć Ci podstaw potrzebnych do tworzenia niestandardowych obiektów. Jeśli są one efektywnie wykorzystywane, mogą być potężnym składnikiem skryptów PowerShell, niezależnie od tego, czy tworzysz pojedyncze obiekty, dodajesz je do tablicy, czy używasz ich w inny sposób. Można na przykład utworzyć obiekty niestandardowe w profilu PowerShell, aby były one dostępne za każdym razem, gdy użytkownik rozpoczyna nową sesję. To, jak wykorzystasz obiekty niestandardowe w swoich skryptach, zależy od Ciebie. Wystarczy wiedzieć, że obiekt niestandardowy jest skutecznym, elastycznym narzędziem, które może zaspokoić wiele potrzeb skryptowych.

Dodatkowe informacje na temat tworzenia obiektów niestandardowych w Windows PowerShell można znaleźć w dokumencie Billa Stewarta „Tworzenie obiektów niestandardowych w Windows PowerShell.”

.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.