Lekce 3 - PowerShell - Datové typy a práce s objekty
V předchozí lekci, PowerShell - Syntaxe, příkazy a roura (pipeline), jsme si ukázali syntaxi příkazů a použití roury.
V dnešní lekci kurzu PowerShell frameworku se seznámíme se základními datovými typy a objekty PowerShellu.
Datové typy PowerShellu
Datový typ definuje v programování druh nebo význam hodnot, kterých smí nabývat proměnná nebo konstanta.
zdroj: Wikipedia
Jelikož je PowerShell postaven na .NET Frameworku (PowerShell 7 na .NET Core), využívá standardní datové typy. To je například:
- řetězec (string),
- číslo (int32, int64)
- nebo třeba hash tabulka (hash table).
PowerShell má však i své vlastní typy jako například PSCustom objekt (PSCustomObject), který má v PowerShellu široké využití a tomuto se dnes budeme věnovat nejvíce.
Vynucení datového typu se provádí v PowerShellu při
přiřazování hodnoty proměnné pomocí []
závorek a jménem
datového typu, například [string]$Var=10
.
Obecně platí, že v PowerShellu není třeba určovat datový typ, protože je přiřazuje automaticky. Pokud je potřeba, PowerShell umí na pozadí provést automatickou konverzi datového typu, pokud je to však možné.
Každý PowerShell objekt má k dispozici metodu
.GetType()
, která zobrazí informace o daném objektu a jeho
datový typ. Použitím příkazu Select-Object *
zobrazíme
všechny vlastnosti objektu.
Než začneme pracovat s objektem, měli bychom vědět s jakým datovým
typem pracujeme. Každý datový typ má totiž jiné metody a vlastnosti. Nemá
tedy smysl na datovém typu [int]
volat metodu
.ToUpper()
. Pokud bychom to i přesto zkusili, dostaneme tento
error:
Method invocation failed because [System.Int32] does not contain a method named 'toupper'.
Error nám říká, že metoda pro tento datový typ neexistuje, proč by taky existovala.
Přístup k metodám a vlastnostem datového typu v PowerShellu provádíme
pomocí tečkové notace .
. Vezměme si například datový typ
textového řetězce (string). V minulých lekcích jsme si představili
příkaz Get-Member
, který teď využijeme:
Windows PowerShell $VarString="testovací řetězec" $VarString | Get-Member TypeName: System.String Name MemberType Definition ---- ---------- ---------- PadLeft Method string PadLeft(int totalWidth), string PadLeft(int totalWidth, char paddingChar) PadRight Method string PadRight(int totalWidth), string PadRight(int totalWidth, char paddingChar) Remove Method string Remove(int startIndex, int count), string Remove(int startIndex) Replace Method string Replace(char oldChar, char newChar), string Replace(string oldValue, string newValue) Substring Method string Substring(int startIndex), string Substring(int startIndex, int length) ToBoolean Method bool IConvertible.ToBoolean(System.IFormatProvider provider) Length Property int Length {get;} ...
Výstup z příkazu Get-Member
výše byl
zkrácen z důvodu velkého počtu metod, výstup je tedy mnohem delší.
Na výstupu příkazu Get-Member
vidíme:
- datový typ daného objektu:
TypeName: System.String
- pro každý member vidíme tři sloupce:
- název metody nebo vlastnosti (Name), například
Replace
- typ (MemberType), v tomto případě to bude metoda
(
Method
) či vlastnost (Property
) - definice (Definition), která určuje datový typ výstup
dané metody. Např. výstup v datovém typu
string
, pak následuje název metody a dále její argumenty. Metoda s argumenty může vypadat taktoReplace(char oldChar, char newChar)
.
- název metody nebo vlastnosti (Name), například
Metodu Replace()
si předvedeme na následujícím
příkladu:
$test='toto je test' $test.Replace('toto','tohle') tohle je test
Apostrofy '
se používají pro definici
statického řetězce, například
$var1='toto je statický řetězec'
.
Uvozovky "
se používají v případě:
- expandování proměnné -
$Name='Vojtěch'; $var2="jmenuji se $Name"
- či dílčího příkazu (subexpression) -
$var3="jmenuji se $(Read-Host 'Jak se jmenuješ?')"
PSCustomObject
PSCustomObject
je zvláštní datový typ PowerShellu, který je
využíván pro tvorbu vlastních objektů s vlastními metodami a vlastnostmi.
Dalo by se říct, že je to náhražka třídy.
Tvorba objektu
PSCustomObject lze v PowerShellu vytvořit několika způsoby:
1. Pomocí příkazu Select-Object
:
(Get-Service fax | Select-Object name,status).GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True False PSCustomObject System.Object
2. Pomocí příkazu New-Object psobject
:
$obj = New-Object psobject $obj.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True False PSCustomObject System.Object
3. Pomocí třídy [PSCustomObject]
a její metody
::new()
:
$obj=[PSCustomObject]::new()
Metody a vlastnosti tříd nejsou volány tečkovou notací
.
, nýbrž ::
.
Přidání memberů do objektu
Do jakéhokoliv objektu typu PSCustomObject můžeme přiřadit metodu
ScriptMethod
nebo vlastnost NoteProperty
pomocí
příkazu Add-Member
:
$obj | Add-Member -MemberType NoteProperty -Name 'Name' -Value 'Vojtěch' $obj | Add-Member -MemberType ScriptMethod -Name NameToUpper -Value {$this.'Name'.ToUpper()} $obj | Get-Member TypeName: System.Management.Automation.PSCustomObject Name MemberType Definition ---- ---------- ---------- Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetType Method type GetType() ToString Method string ToString() Name NoteProperty string Name=Vojtěch NameToUpper ScriptMethod System.Object NameToUpper();
Pokud chceme aktualizovat či přepsat hodnotu již existujícího membera v
objektu PSCustom, u příkazu Add-Member
musíme použít argument
-Force
, který daný member odebere a vytvoří jej znovu s novými
hodnotami. Bez argumentu -Force
nám PowerShell vrátí
následující error:
$obj | Add-Member -MemberType NoteProperty -Name 'Name' -Value 'Vojtěch' Add-Member : Cannot add a member with the name "Name" because a member with that name already exists. To overwrite the member anyway, add the Force parameter to your command. At line:2 char:8 + $obj | Add-Member -MemberType NoteProperty -Name 'Name' -Value 'Vojtě ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (@{Name=Vojtěch}:PSObject) [Add-Member], InvalidOperationException + FullyQualifiedErrorId : MemberAlreadyExists,Microsoft.PowerShell.Commands.AddMemberCommand
Účelem WMI (Windows Management Instrumentation) je definovat vlastní sadu specifikací nezávislých na prostředí, které umožňují sdílení informací o správě mezi aplikacemi pro správu.
zdroj: Wikipedia
K čemu nám takový objekt může sloužit v reálném životě si názorně předvedeme na kousku kódu s využitím WMI:
# načtení WMI dat z třídy win32_OperatingSystem $OperatingSystem = Get-WmiObject win32_OperatingSystem # načtení WMI dat z třídy win32_ComputerSystem $ComputerSystem = Get-WmiObject win32_ComputerSystem $ComputerInfo = New-Object psobject $ComputerInfo | Add-Member -MemberType NoteProperty -Name ComputerName -Value $ComputerSystem.Name $ComputerInfo | Add-Member -MemberType NoteProperty -Name MemoryGB -Value ($ComputerSystem.TotalPhysicalMemory/1GB -as [int]) $ComputerInfo | Add-Member -MemberType NoteProperty -Name CpuCount -Value $ComputerSystem.NumberOfProcessors $ComputerInfo | Add-Member -MemberType NoteProperty -Name OperatingSystem -Value $OperatingSystem.Caption $ComputerInfo | Add-Member -MemberType NoteProperty -Name OperatingSystemInstallDate -Value ($OperatingSystem.ConvertToDateTime($OperatingSystem.InstallDate)) $ComputerInfo | Add-Member -MemberType NoteProperty -Name LastBootupTime -Value ($OperatingSystem.ConvertToDateTime($OperatingSystem.LastBootUpTime)) $ComputerInfo | Add-Member -MemberType ScriptMethod -Name GetUptime -Value {(Get-Date) - $OperatingSystem.ConvertToDateTime($OperatingSystem.LastBootUpTime)}
Vlastnosti našeho objektu nyní vypadají následovně:
$ComputerInfo ComputerName : PC046418 MemoryGB : 16 CpuCount : 1 OperatingSystem : Microsoft Windows 10 Pro OperatingSystemInstallDate : 8/29/2019 12:41:44 PM LastBootupTime : 8/11/2020 7:08:31 AM
Metoda GetUptime()
nám vrátí uptime počítače v datovém
typu [TimeSpan]
. Uptime je dynamicky aktualizován při každém
zavolání metody GetUptime()
:
$ComputerInfo.GetUptime() Days : 1 Hours : 12 Minutes : 21 Seconds : 29 Milliseconds : 482 Ticks : 1308894828649 TotalDays : 1.5149245701956 TotalHours : 36.3581896846944 TotalMinutes : 2181.49138108167 TotalSeconds : 130889.4828649 TotalMilliseconds : 130889482.8649
Takovýto kousek kódu nám stačí napsat pouze jednou a stačí jej poté přidat třeba do PowerShell profilu. Při každém spuštění PowerShellu pak již máme tento objekt připraven v naší session.
Co jsou profily, jak se s nimi pracuje a jak je vlastně uvést do provozu si povíme jindy
V další lekci, PowerShell - Profily, se seznámíme s PowerShell profily.