Dziś chciałbym opowiedzieć o dość istotnym elemencie, który pewnie wpłynie na twoją świadomość dalszej pracy z PowerShellem. Zanim na dobre rozgościsz się za sterami konsoli musisz wiedzieć, że jedną z cech, która zdecydowanie wyróżnia PowerShella na tle innych interpreterów poleceń jest zastosowanie logiki obiektowej. Mówiąc wprost wszystko co zaistnieje w PowerShellu jest obiektem, który jednocześnie jest egzemplarzem klasy szkieletowej platformy .NET. Tak, wiem brzmi to dość skomplikowanie ale za chwilę wszystko się wyjaśni.
Czym jest obiekt?
Powershell oparty jest na logice obiektowej, dlatego też czasem możesz usłyszeć, że aby w pełni zrozumieć PowerShella musisz zrozumieć obiekty. Zacznijmy więc od wyjaśnienia pojęcia obiekt. Otóż obiekt technicznie rzecz biorąc jest po prostu programową reprezentacją konkretnych danych. Każdy obiekt jest zbiorem elementów oraz działań potrzebnych, aby z tych elementów skorzystać. Zależnie od okoliczności, możemy być bardziej zainteresowani właściwościami albo metodami danego obiektu. Te pierwsze zapewniają możliwość opisania danego obiektu. Te drugie umożliwiają zrobienie czegoś. Właściwości oraz metody potocznie nazywane są elementami członkowskimi (members).
Każdy obiekt ma swój „schemat”, czyli pewien szablon, który zawiera plan tworzenia obiektu. Co zawiera taki plan? Przede wszystkim opisuje jakie właściwości i jakie metody będzie posiadał dany obiekt. Wyobraź sobie, że chcesz zbudować samochód, aby to zrobić potrzebny będzie Ci plan. Plan taki będzie zawierał informacje, opisujące samochód. Gabaryty auta, dane dotyczące silnika, kół itd. Dodatkowo będzie zawierał informacje o tym, że samochód może jechać do przodu, skręcać i hamować. Sam szablon nie zawiera konkretnych danych, jedynie określa pewne ramy funkcjonowania danego obiektu. Ten schemat czy też szablon nazywa się typem obiektu. Każdy obiekt, który zaistnieje w PowerShellu posiada określony typ, zatem musi posiadać szablon, z którego został stworzony. Resumując to wszystko.
Obiekt to wystąpienie, a mówiąc nieco bardziej technicznie instancja danego typu. Możesz stworzyć dowolną liczbę obiektów każdego typu i każdy z nich może przechowywać inne wartości poszczególnych właściwości. Brzmi skomplikowanie?
W takim razie wróćmy do naszego auta. Załużmy, że mamy już gotowy schemat naszego obiektu, który posiada dwie właściwości rozmiar i kolor oraz dwie metody ruszanie i hamowanie. Nie jest to może zbyt zaawansowany obiekt, ale jako przykład spokojnie wystarczy. Tak więc to jest typ obiektu. Wypełniając ten typ różnymi właściwościami możemy tworzyć różne obiekty. Auto 1 będzie małe i czerwone zatem konkretne właściwości będą posiadały odpowiednie wartości, auto 2 zielone i duże, natomiast auto trzecie średnie i żółte. Zauważ, że w zasadzie mamy trzy różne obiekty. Jednak każdy z nich zbudowany jest w oparciu o identyczny schemat. Zatem wszystkie te obiekty to wystąpienia tego samego typu.
Teraz, aby wykonać zadanie w naszym wyimaginowanym przypadku niech będzie to dojazd do pracy będę potrzebował obiektu samochód o konkretnych właściwościach i metodach. I podobnie sprawa wygląda w PowerShellu, w celu wykonania określonych zadań (np. zmiana hasła danego użytkownika) niezbędne będą konkretne obiekty (w tym przypadku obiekt danego użytkownika) o odpowiednich metodach i właściwościach (czyli np. pełna nazwa).
Konsola PowerShell pozwala na obsługuję naprawdę szerokiej gamy różnych typów obiektów. Co więcej możesz tworzyć własne typy i obiekty. Ale to już trochę bardziej zaawansowana sprawa i zajmiemy się tym kiedy indziej.
Obiekty w praktyce
Teraz przejdźmy do konsoli i pokażę Ci jak to wygląda w praktyce.
Na początek napiszę dowolny tekst i niech będzie to standardowe Hello world!.
PS C:\Users\Admin> Hello world!
Hello : The term 'Hello' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ Hello world!
+ ~~~~~
+ CategoryInfo : ObjectNotFound: (Hello:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Od razu dodam, że aby konsola uznała jakiś tekst za obiekt String tzn. łańcuch znaków musi być zapisywany w cudzysłowie, gdyż w przeciwnym wypadku PowerShell powie, że po prostu nie rozpoznaje takiego polecenia.
Warto wiedzieć
W PowerShellu spotkać można dwa rodzaje cudzysłowu podwójny i pojedynczy. Zwykle w przypadku standardowego łańcucha znaków stosowany jest pojedynczy, natomiast czasami w specyficznych przypadkach np. przy wykorzystaniu zmiennych czy konkretnych zapytań SQL używa się podwójnych.
Wróćmy jednak do naszego tekstu. Teraz zapisujemy go poprawnie.
PS C:\Users\Admin> 'Hello world!'
Hello world!
Po naciśnięciu klawisza Enter, w konsoli wyświetlony został nasz tekst. Wydawało by się nic specjalnego, ale nawet tak banalny tekst w PowerShellu, staje się obiektem, na którym można podjąć pewne działania i który posiada konkretne właściwości. Aby to udowodnić ponownie wpisujemy nasz tekst następnie spacja i pionowa kreska, tzw pipe, czyli znak potoku. Po znaku potoku wstawiamy kolejną spacje i cmdlet Get-Member, zwraca właściwości oraz metody danego obiektu. Przyjrzymy się mu dokładnie w innym wpisie. Natomiast teraz chciałbym abyśmy skupili się na korzystaniu z obiektów, a mówiąc dokładnie z ich metod i właściwości.
PS C:\Users\Admin> ‘Hello world!’ | Get-Member
TypeName: System.String
Name MemberType Definition
---- ---------- ----------
Clone Method System.Object Clone(), System.Object ICloneable.Clone()
CompareTo Method int CompareTo(System.Object value), int CompareTo(string...
Contains Method bool Contains(string value)
CopyTo Method void CopyTo(int sourceIndex, char[] destination,...
EndsWith Method bool EndsWith(string value), bool EndsWith(string value, ...
Equals Method bool Equals(System.Object obj), bool Equals(string value)...
GetEnumerator Method System.CharEnumerator GetEnumerator(), System.Collections....
GetHashCode Method int GetHashCode()
GetType Method type GetType()
GetTypeCode Method System.TypeCode GetTypeCode(), System.TypeCode
IndexOf Method int IndexOf(char value), int IndexOf(char value, int...
IndexOfAny Method int IndexOfAny(char[] anyOf), int IndexOfAny(char[]...
Insert Method string Insert(int startIndex, string value)
IsNormalized Method bool IsNormalized(), bool IsNormalized(System.Text.Normali...
LastIndexOf Method int LastIndexOf(char value), int LastIndexOf(char value, int...
LastIndexOfAny Method int LastIndexOfAny(char[] anyOf), int LastIndexOfAny(char[]...
Normalize Method string Normalize(), string Normalize(System.Text.Normalizati...
PadLeft Method string PadLeft(int totalWidth), string PadLeft(int total...
PadRight Method string PadRight(int totalWidth), string PadRight(int total...
Remove Method string Remove(int startIndex, int count), string Remove...
Replace Method string Replace(char oldChar, char newChar), string Replace(s...
Split Method string[] Split(Params char[] separator), string[] Split...
StartsWith Method bool StartsWith(string value), bool StartsWith(string value,...
Substring Method string Substring(int startIndex), string Substring(int...
ToBoolean Method bool IConvertible.ToBoolean(System.IFormatProvider provider)
ToByte Method byte IConvertible.ToByte(System.IFormatProvider provider)
ToChar Method char IConvertible.ToChar(System.IFormatProvider provider)
ToCharArray Method char[] ToCharArray(), char[] ToCharArray(int startIndex...
ToDateTime Method datetime IConvertible.ToDateTime(System.IFormatProvider...
ToDecimal Method decimal IConvertible.ToDecimal(System.IFormatProvider provider)
ToDouble Method double IConvertible.ToDouble(System.IFormatProvider provider)
ToInt16 Method int16 IConvertible.ToInt16(System.IFormatProvider provider)
ToInt32 Method int IConvertible.ToInt32(System.IFormatProvider provider)
ToInt64 Method long IConvertible.ToInt64(System.IFormatProvider provider)
ToLower Method string ToLower(), string ToLower(cultureinfo culture)
ToLowerInvariant Method string ToLowerInvariant()
ToSByte Method sbyte IConvertible.ToSByte(System.IFormatProvider provider)
ToSingle Method float IConvertible.ToSingle(System.IFormatProvider provider)
ToString Method string ToString(), string ToString(System.IFormatProvider......
ToType Method System.Object IConvertible.ToType(type conversionType,...
ToUInt16 Method uint16 IConvertible.ToUInt16(System.IFormatProvider provider)
ToUInt32 Method uint32 IConvertible.ToUInt32(System.IFormatProvider provider)
ToUInt64 Method uint64 IConvertible.ToUInt64(System.IFormatProvider provider)
ToUpper Method string ToUpper(), string ToUpper(cultureinfo culture)
ToUpperInvariant Method string ToUpperInvariant()
Trim Method string Trim(Params char[] trimChars), string Trim()
TrimEnd Method string TrimEnd(Params char[] trimChars)
TrimStart Method string TrimStart(Params char[] trimChars)
Chars ParameterizedProperty char Chars(int index) {get;}
Length Property int Length {get;}
Właściwości
W rezultacie wykonania polecenia otrzymaliśmy spis wszystkich metod i właściwości naszego obiektu 'Hello world!’. Na samej górze widnieje konkretny typ obiektu i jest to System.String. Zwróćmy uwagę, że nasz obiekt posiada kilka metod i tylko jedną właściwość Length. Aby użyć jakieś metody lub właściwości należy wypisać obiekt, a następnie po kropce konkretną nazwę danej właściwości lub metody. Zobaczmy to właśnie na przykładzie właściwości Length, która określa długość łańcucha znaków.
PS C:\Users\Admin> 'Hello world!'.Length
12
Metody
W przypadku metod powinniśmy pamiętać dodatkowo o nawiasach na końcu.
PS C:\Users\Admin> 'Hello World!'.ToUpper()
HELLO WORLD!
Zwróćmy uwagę, że po zastosowaniu konkretnej metody nasz obiekt się zmienił się nieco. Teraz czas na trochę inny przykład. Za pomocą polecenia Get- Date pobierzemy aktualną datę i godzinę z zegara systemowego:
PS C:\Users\Admin> Get-Date
środa, 11 października 2023 14:17:43
Następnie zobaczmy jakim typem obiektu jest nasza data i jakie metody oraz właściwości mamy do dyspozycji.
PS C:\Users\Admin> Get-Date | gm
TypeName: System.DateTime
Name MemberType Definition
---- ---------- ----------
Add Method datetime Add(timespan value)
AddDays Method datetime AddDays(double value)
AddHours Method datetime AddHours(double value)
AddMilliseconds Method datetime AddMilliseconds(double value)
AddMinutes Method datetime AddMinutes(double value)
AddMonths Method datetime AddMonths(int months)
AddSeconds Method datetime AddSeconds(double value)
AddTicks Method datetime AddTicks(long value)
AddYears Method datetime AddYears(int value)
CompareTo Method int CompareTo(System.Object value), int CompareTo(datetime...
Equals Method bool Equals(System.Object value), bool Equals(datetime...
GetDateTimeFormats Method string[] GetDateTimeFormats(), string[] GetDateTimeFormats...
GetHashCode Method int GetHashCode()
GetObjectData Method void ISerializable.GetObjectData(System.Runtime....
GetType Method type GetType()
GetTypeCode Method System.TypeCode GetTypeCode(), System.TypeCode IConvertible...
IsDaylightSavingTime Method bool IsDaylightSavingTime()
Subtract Method timespan Subtract(datetime value), datetime Subtract...
ToBinary Method long ToBinary()
ToBoolean Method bool IConvertible.ToBoolean(System.IFormatProvider provider)
ToByte Method byte IConvertible.ToByte(System.IFormatProvider provider)
ToChar Method char IConvertible.ToChar(System.IFormatProvider provider)
ToDateTime Method datetime IConvertible.ToDateTime(System.IFormatProvider provider)
ToDecimal Method decimal IConvertible.ToDecimal(System.IFormatProvider provider)
ToDouble Method double IConvertible.ToDouble(System.IFormatProvider provider)
ToFileTime Method long ToFileTime()
ToFileTimeUtc Method long ToFileTimeUtc()
ToInt16 Method int16 IConvertible.ToInt16(System.IFormatProvider provider)
ToInt32 Method int IConvertible.ToInt32(System.IFormatProvider provider)
ToInt64 Method long IConvertible.ToInt64(System.IFormatProvider provider)
ToLocalTime Method datetime ToLocalTime()
ToLongDateString Method string ToLongDateString()
ToLongTimeString Method string ToLongTimeString()
ToOADate Method double ToOADate()
ToSByte Method sbyte IConvertible.ToSByte(System.IFormatProvider provider)
ToShortDateString Method string ToShortDateString()
ToShortTimeString Method string ToShortTimeString()
ToSingle Method float IConvertible.ToSingle(System.IFormatProvider provider)
ToString Method string ToString(), string ToString(string format), string...
ToType Method System.Object IConvertible.ToType(type conversionType, System...
ToUInt16 Method uint16 IConvertible.ToUInt16(System.IFormatProvider provider)
ToUInt32 Method uint32 IConvertible.ToUInt32(System.IFormatProvider provider)
ToUInt64 Method uint64 IConvertible.ToUInt64(System.IFormatProvider provider)
ToUniversalTime Method datetime ToUniversalTime()
DisplayHint NoteProperty DisplayHintType DisplayHint=DateTime
Date Property datetime Date {get;}
Day Property int Day {get;}
DayOfWeek Property System.DayOfWeek DayOfWeek {get;}
DayOfYear Property int DayOfYear {get;}
Hour Property int Hour {get;}
Kind Property System.DateTimeKind Kind {get;}
Millisecond Property int Millisecond {get;}
Minute Property int Minute {get;}
Month Property int Month {get;}
Second Property int Second {get;}
Ticks Property long Ticks {get;}
TimeOfDay Property timespan TimeOfDay {get;}
Year Property int Year {get;}
DateTime ScriptProperty System.Object DateTime {get=if ((& { Set-StrictMode...
Jak widzisz jest to obiekt System.DateTime i ma kilkadziesiąt metod oraz kilka właściwości. Wykorzystując konkretne właściwości możemy np. wyświetlić dany dzień tygodnia czy rok. I tutaj ważna uwaga, w przypadku chęci wyświetlenia konkretnej właściwości czy metody w przypadku cmdletu musimy umieścić do w nawiasie. W przeciwnym wypadku zobaczymy komunikat o błędzie.
PS C:\Users\Admin> Get-Date.DayofWeek
Get-Date.DayofWeek : The term 'Get-Date.DayofWeek' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try a gain.
At line:1 char:1
+ Get-Date.DayofWeek
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-Date.DayofWeek:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Prawidłowo wygląda to następująco:
PS C:\Users\Admin> (Get-Date).DayofWeek
Wednesday
PS C:\Users\Admin> (Get-Date).Year
2023
Natomiast za pomocą metod możemy np. przenieść się w dowolny punkt w czasie (dodajemy 5 dni):
PS C:\Users\Admin> (Get-Date).AddDays(5)
poniedziałek, 16 października 2023 14:40:53
Nic nie stoi na przeszkodzie żebyśmy cofnęli się w czasie (cofamy się dwie godziny):
PS C:\Users\Admin> (Get-Date).AddHours(-2)
środa, 11 października 2023 12:41:16
Na zakończenie zróbmy jeszcze kilka innych przykładów.
Na początek pobierzemy litery dysków występujących w systemie. W tym celu posłużymy się poleceniem Get-Volumie z właściwością Driveletter.
PS C:\Users\Admin> (Get-Volume).DriveLetter
C
W moim przypadku będzie to tylko dysk C, natomiast u Ciebie oczywiście może być inaczej. Następny przykład dotyczył będzie adresacji IP. Do tego celu posłużę się cmdletem Get-NetIpAdress oraz właściwością Ipv4Address.
PS C:\Users\Admin> (Get-NetIPAddress).IPv4Address
169.254.30.35
172.31.128.1
169.254.216.122
169.254.194.4
192.168.178.242
127.0.0.1
Otrzymałem wszystkie adresy IP w wersji 4, które posiada mój komputer. Na zakończenie lekcji uruchamiamy kalkulator poleceniem calc.exe, następnie korzystając z metody kill() postaramy się go zamknąć. Aby nie zamknąć wszystkich procesów i nie namieszać w systemie musimy sprecyzować o który dokładnie nam chodzi, możemy to zrobić na kilka sposobów, podając różne parametry, ale najłatwiej chyba w tym przypadku odnaleźć konkretny proces po nazwie.
PS C:\Users\Admin> (Get-Process –Name calculatorApp).Kill() # W systemie Windows 11 kalkulator nazywa się CalculatorApp
Wygląda na to że się udało, aplikacja kalkulator została zamknięta.
Na zakończenie dodam jeszcze, że PowerShell nie ogranicza się tylko do wbudowanych typów. Wedle potrzeb możemy tworzyć własne obiekty. I nie jest to wcale jakieś szczególnie skomplikowane zadanie. Jednak temat zostawię na nieco inny wpis. Mam nadzieje, że temat obiektów ich właściwości i metod nieco się rozjaśnił, gdyż szczególnie w dalszym etapie nauki będzie dość istotny.