Wynik tekstowy poleceń w oknie interpretera PowerShell to tylko sposób na wyświetlenie informacji w formie odpowiedniej dla ludzkiej percepcji. Właściwie środa
Spis treści:
Obiekty w PowerShellu
Przypomnijmy, że obiekt to zbiór pól danych (właściwości, zdarzeń itp.) oraz metod ich przetwarzania (metod). Jego strukturę określa typ, który zwykle opiera się na klasach używanych w ujednoliconej platformie .NET Core. Możliwa jest także praca z obiektami COM, CIM (WMI) i ADSI. Do wykonywania różnych akcji na danych potrzebne są właściwości i metody, dodatkowo w PowerShellu obiekty można przekazywać jako argumenty do funkcji i poleceń cmdlet, przypisywać ich wartości zmiennym, jest też
Oglądanie struktury obiektów
Przykładowo uruchommy cmdlet Get-Process, który pozwala uzyskać informacje o procesach działających w systemie:
Wyświetli sformatowane dane tekstowe, które nie dają żadnego pojęcia o właściwościach zwracanych obiektów i ich metodach. Aby dostroić dane wyjściowe, musimy nauczyć się badać strukturę obiektów, a polecenie cmdlet Get-Member pomoże nam w tym:
Get-Process | Get-Member
Tutaj widzimy już typ i strukturę, a za pomocą dodatkowych parametrów możemy np. wyświetlić tylko właściwości obiektu zawarte na wejściu:
Get-Process | Get-Member -MemberType Property
Wiedza ta będzie potrzebna do interaktywnego rozwiązywania problemów administracyjnych lub do napisania własnych skryptów: na przykład w celu uzyskania informacji o zawieszonych procesach za pomocą właściwości Responding.
Filtrowanie obiektów
PowerShell umożliwia przekazywanie potokiem obiektów spełniających określony warunek:
Where-Object { блок сценария }
Wynik wykonania bloku skryptu w nawiasach musi być wartością logiczną. Jeśli ma wartość true ($true), obiekt wprowadzony do polecenia cmdlet Where-Object zostanie przekazany potokiem, w przeciwnym razie ($false) zostanie usunięty. Dla przykładu wyświetlmy listę zatrzymanych usług Windows Server, czyli: te, których właściwość Status jest ustawiona na „Zatrzymany”:
Get-Service | Where-Object {$_.Status -eq "Stopped"}
Tutaj ponownie widzimy reprezentację tekstową, ale jeśli chcesz zrozumieć typ i wewnętrzną strukturę obiektów przechodzących przez rurociąg, nie jest to trudne:
Get-Service | Where-Object {$_.Status -eq "Stopped"} | Get-Member
Sortowanie obiektów
Podczas przetwarzania obiektów potokowo często zachodzi potrzeba ich sortowania. Polecenie cmdlet Sort-Object przekazuje nazwy właściwości (klucze sortowania) i zwraca obiekty uporządkowane według ich wartości. Sortowanie wyników uruchomionych procesów według czasu wykorzystania procesora (właściwość cpu) jest łatwe:
Get-Process | Sort-Object –Property cpu
Parametr -Property można pominąć podczas wywoływania polecenia cmdlet Sort-Object; jest on używany domyślnie. Do sortowania odwrotnego użyj parametru -Descending:
Get-Process | Sort-Object cpu -Descending
Wybór obiektów i ich części
Polecenie cmdlet Select-Object umożliwia wybranie określonej liczby obiektów na początku lub na końcu potoku przy użyciu parametrów -First lub -Last. Za jego pomocą można wybierać pojedyncze obiekty lub określone właściwości, a także tworzyć na ich podstawie nowe obiekty. Przyjrzyjmy się działaniu polecenia cmdlet na prostych przykładach.
Poniższe polecenie wyświetla informację o 10 procesach zużywających maksymalną ilość pamięci RAM (właściwość WS):
Get-Process | Sort-Object WS -Descending | Select-Object -First 10
Można wybrać tylko niektóre właściwości obiektów przechodzących przez rurociąg i na ich podstawie utworzyć nowe:
Get-Process | Select-Object ProcessName, Id -First 1
W wyniku działania potoku otrzymamy nowy obiekt, którego struktura będzie się różnić od struktury zwróconej przez cmdlet Get-Process. Sprawdźmy to za pomocą Get-Member:
Get-Process | Select-Object ProcessName, Id -First 1 | Get-Member
Zauważ, że Select-Object zwraca pojedynczy obiekt (-First 1), który ma tylko dwa z określonych przez nas pól: ich wartości zostały skopiowane z pierwszego obiektu przekazanego do potoku przez cmdlet Get-Process. Jeden ze sposobów tworzenia obiektów w skryptach PowerShell opiera się na użyciu Select-Object:
$obj = Get-Process | Select-Object ProcessName, Id -First 1
$obj.GetType()
Używając Select-Object, możesz dodać obliczone właściwości do obiektów, które mają być reprezentowane jako
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}}
Przyjrzyjmy się strukturze obiektów przechodzących przez przenośnik:
Get-Process | Select-Object -Property ProcessName, @{Name="StartTime"; Expression = {$_.StartTime.Minute}} | Get-Member
ForEach-Object, Group-Object i Measure-Object
Istnieją inne polecenia cmdlet umożliwiające pracę z obiektami. Jako przykład porozmawiajmy o trzech najbardziej przydatnych:
Dla każdego obiektu pozwala uruchomić kod PowerShell dla każdego obiektu w potoku:
ForEach-Object { блок сценария }
Obiekt grupowy grupuje obiekty według wartości właściwości:
Group-Object PropertyName
Jeśli uruchomisz go z parametrem -NoElement, możesz sprawdzić liczbę elementów w grupach.
Miara-Obiekt agreguje różne parametry podsumowania według wartości pól obiektu w potoku (oblicza sumę, a także znajduje wartość minimalną, maksymalną lub średnią):
Measure-Object -Property PropertyName -Minimum -Maximum -Average -Sum
Zazwyczaj omawiane polecenia cmdlet są używane interaktywnie i często są tworzone w skryptach.
Tworzenie obiektów .NET i COM (New-Object)
Istnieje wiele komponentów oprogramowania z interfejsami .NET Core i COM, które są przydatne dla administratorów systemów. Korzystając z klasy System.Diagnostics.EventLog, można zarządzać dziennikami systemowymi bezpośrednio z poziomu programu Windows PowerShell. Przyjrzyjmy się przykładowi utworzenia instancji tej klasy przy użyciu polecenia cmdlet New-Object z parametrem -TypeName:
New-Object -TypeName System.Diagnostics.EventLog
Ponieważ nie określiliśmy konkretnego dziennika zdarzeń, powstała instancja klasy nie zawiera żadnych danych. Aby to zmienić należy w trakcie jej tworzenia wywołać specjalną metodę konstruktora za pomocą parametru -ArgumentList. Jeżeli chcemy uzyskać dostęp do logu aplikacji powinniśmy jako argument przekazać konstruktorowi ciąg „Aplikacja”:
$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
$AppLog
Należy pamiętać, że dane wyjściowe polecenia zapisaliśmy w zmiennej $AppLog. Chociaż potoki są powszechnie używane w trybie interaktywnym, pisanie skryptów często wymaga utrzymywania odniesienia do obiektu. Ponadto podstawowe klasy .NET Core są zawarte w przestrzeni nazw System: PowerShell domyślnie szuka w niej określonych typów, więc zapisanie Diagnostics.EventLog zamiast System.Diagnostics.EventLog jest całkiem poprawne.
Aby pracować z dziennikiem, możesz użyć odpowiednich metod:
$AppLog | Get-Member -MemberType Method
Załóżmy, że zostało to wyczyszczone metodą Clear() jeśli istnieją prawa dostępu:
$AppLog.Clear()
Polecenie cmdlet New-Object jest również używane do pracy ze składnikami COM. Jest ich całkiem sporo - od bibliotek dostarczanych wraz z serwerem skryptów Windows po aplikacje ActiveX, takie jak Internet Explorer. Aby utworzyć obiekt COM, należy ustawić parametr -ComObject z programowym ProgId żądanej klasy:
New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject
Aby utworzyć własne obiekty o dowolnej strukturze, użycie New-Object wydaje się zbyt archaiczne i kłopotliwe; to polecenie cmdlet służy do pracy z komponentami oprogramowania spoza PowerShell. W przyszłych artykułach kwestia ta zostanie omówiona bardziej szczegółowo. Oprócz obiektów .NET i COM przyjrzymy się także obiektom CIM (WMI) i ADSI.
Wywoływanie metod statycznych
Nie można utworzyć instancji niektórych klas .NET Core, w tym System.Environment i System.Math. Oni są
[System.Environment] | Get-Member
Aby wyświetlić tylko statyczne elementy, wywołaj Get-Member z parametrem -Static (zwróć uwagę na typ obiektu):
[System.Environment] | Get-Member -Static
Aby uzyskać dostęp do właściwości i metod statycznych, użyj dwóch kolejnych dwukropków zamiast kropki po literale:
[System.Environment]::OSVersion
Lub
$test=[System.Math]::Sqrt(25)
$test
$test.GetType()
Wpisz PSCustomObject
Wśród licznych typów danych dostępnych w PowerShell warto wymienić PSCustomObject, przeznaczony do przechowywania obiektów o dowolnej strukturze. Tworzenie takiego obiektu za pomocą polecenia cmdlet New-Object jest uważane za klasyczny, ale uciążliwy i przestarzały sposób:
$object = New-Object –TypeName PSCustomObject -Property @{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'}
Przyjrzyjmy się strukturze obiektu:
$object | Get-Member
Począwszy od PowerShell 3.0 dostępna jest inna składnia:
$object = [PSCustomObject]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
Dostęp do danych można uzyskać na jeden z równoważnych sposobów:
$object.Name
$object.'Name'
$value = 'Name'
$object.$value
Oto przykład konwersji istniejącej tablicy mieszającej na obiekt:
$hash = @{'Name'='Ivan Danko'; 'City'='Moscow'; 'Country'='Russia'}
$hash.GetType()
$object = [pscustomobject]$hash
$object.GetType()
Jedną z wad obiektów tego typu jest możliwość zmiany kolejności ich właściwości. Aby tego uniknąć, musisz użyć atrybutu [ordered]:
$object = [PSCustomObject][ordered]@{Name = 'Ivan Danko';
City = 'Moscow';
Country = 'Russia'
}
Istnieją inne opcje tworzenia obiektu: powyżej omówiliśmy użycie polecenia cmdlet
$object | Add-Member –MemberType NoteProperty –Name Age –Value 33
$object | Get-Member
Polecenie cmdlet Add-Member umożliwia dodawanie nie tylko właściwości, ale także metod do wcześniej utworzonego obiektu $ za pomocą konstrukcji „-MemberType ScriptMethod”:
$ScriptBlock = {
# код
}
$object | Add-Member -Name "MyMethod" -MemberType ScriptMethod -Value $ScriptBlock
$object | Get-Member
Należy pamiętać, że do przechowywania kodu nowej metody użyliśmy zmiennej $ScriptBlock typu ScriptBlock.
Aby usunąć właściwości, użyj odpowiedniej metody:
$object.psobject.properties.remove('Name')
Tworzenie własnych klas
W PowerShell 5.0 wprowadzono możliwość definiowania
class MyClass
{
# тело класса
}
Jest to prawdziwy typ .NET Core z treścią opisującą jego właściwości, metody i inne elementy. Spójrzmy na przykład zdefiniowania najprostszej klasy:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
}
Aby utworzyć obiekt (instancję klasy), użyj polecenia cmdlet
$object = New-Object -TypeName MyClass
lub
$object = [MyClass]::new()
Przeanalizujmy strukturę obiektu:
$object | Get-Member
Nie zapomnij o zasięgu: nie możesz odwoływać się do nazwy typu jako ciągu znaków ani używać literału typu poza skryptem lub modułem, w którym zdefiniowano klasę. W tym przypadku funkcje mogą zwracać instancje klas (obiekty), które będą dostępne poza modułem lub skryptem.
Po utworzeniu obiektu uzupełnij jego właściwości:
$object.Name = 'Ivan Danko'
$object.City = 'Moscow'
$object.Country = 'Russia'
$object
Należy pamiętać, że opis klasy określa nie tylko typy właściwości, ale także ich wartości domyślne:
class Example
{
[string]$Name = 'John Doe'
}
Opis metody klasy przypomina opis funkcji, ale bez użycia słowa funkcyjnego. Podobnie jak w funkcji, w razie potrzeby parametry są przekazywane do metod:
class MyClass
{
[string]$Name
[string]$City
[string]$Country
#описание метода
Smile([bool]$param1)
{
If($param1) {
Write-Host ':)'
}
}
}
Teraz przedstawiciel naszej klasy może się uśmiechnąć:
$object = [MyClass]::new()
$object.Smile($true)
Metody mogą być przeciążane; ponadto klasa tak ma
class MyClass2 : MyClass
{
#тело нового класса, базовым для которого является MyClass
}
[MyClass2]::new().Smile($true)
Nasz opis pracy z obiektami w PowerShell nie jest wyczerpujący. W kolejnych publikacjach postaramy się to pogłębić na praktycznych przykładach: piąty artykuł z serii poświęcony będzie zagadnieniom integracji PowerShella z komponentami oprogramowania firm trzecich. Poprzednie części można znaleźć pod linkami poniżej.
Źródło: www.habr.com