7. diel - PowerShell - Kolekcia objektov
V predchádzajúcej lekcii, PowerShell - Typy výstupu , sme sa zoznámili s PowerShell výstupmi, naučili sa dané typy výstupu používať v praxi a tiež ako tieto výstupy presmerovať.
V dnešnej lekcii kurze PowerShell frameworku sa zoznámime s rôznymi typmi kolekciou PowerShellu.
Statické pole
(System.Array
)
Pole je základný typ kolekcia v PowerShellu a je deklarované pomocou
výrazu @()
. Toto pole môže obsahovať ako čísla, reťazce,
objekty tak aj ďalšie pole objektov. V tomto prípade sa už bavíme o
viacstranný poli.
Defaultne vie PowerShell automaticky určiť dátový typ
objektu, však niekedy môžeme chcieť iný dátový typ, než nám ponúka
PowerShell. V tomto prípade môžeme vynútiť dátový typ pomocou
[<datatype>]
.
Ako príklad môžeme uviesť pretypovanie reťazca ([string]
)
na pole ([array]
):
[array]$Var='tohle bude pole'.
Pole čísel možno deklarovať aj dynamicky pomocou rozsahu,
napr. $Arr=1..500
.
Pole môže byť deklarované:
- buď ručne, pomocou už spomínaného výrazu
@()
, napríklad$Pole=@()
V tomto prípade sa jedná o statické polia a prvky (či elementy) sa do tohto poľa pridávajú pomocou operátora+=
. - V tomto prípade sa jedná o statické polia a prvky (či elementy) sa do
tohto poľa pridávajú pomocou operátora
+=
. - pomocou príkazu, ktorý vracia pole objektov, napríklad
$Pole=Get-ChildItem C:
Tu sa tiež jedná o statické polia, však jeho veľkosť a obsah určuje výstup z príkazu, v tomto prípadeGet-ChildItem C:
. - Tu sa tiež jedná o statické polia, však jeho veľkosť a obsah určuje
výstup z príkazu, v tomto prípade
Get-ChildItem C:
. - pomocou vynútenia dátového typu
[array]
, napríklad[array]$Pole=Get-Date
Opäť sa jedná o statické polia, v tomto prípade bol tento typ údajov vynútený. - Opäť sa jedná o statické polia, v tomto prípade bol tento typ údajov vynútený.
Základné operácie s prvkami v statickom poli
Statické polia neumožňuje odobratie prvku z tohto poľa.
Prechádzanie prvkov v poli nám umožňujú príkazy cyklov
ForEach
a Foreach-Object
. Aký je medzi týmito
príkazmi rozdiel sa dozvieme v inej lekciu.
Pridanie ďalšieho prvku
Pridanie ďalšieho prvku do statického poľa sa vykonáva operátorom
+=
:
$Pole=@(1,2,3) $Pole+=4
Indexovanie prvkov
Každý prvok v poli je indexovaný číslom od 0
až
počet prvků -1
a sú indexované v takom poradí, v akom boli do
poľa pridané:
$Pole[0] #vypíše prvek na první pozici $Pole[0..2] #vypíše první až třetí prvek $Pole[0..$Pole.Count] #vypíše všechny prvky v poli (defaultní akce při zavolání proměnné $Pole)
Prechádzanie prvkov v poli
Na spracovanie prvkov v poli slúžia dva príkazy, a to ForEach
a ForEach-Object
:
ForEach ($i in $Pole){ Write-Output "--> pracuji s hodnotou '$i'" } # ForEach-Object: $Pole | ForEach-Object { Write-Output ("--> pracuji s hodnotou '{0}'" -f $_) }
Ochrana dátového typu v poli
Ochrana dátového typu v poli sa vykonáva požadovaným dátovým typom a
výrazom []
, napríklad výraz [int[]]
znamená, že
pole môže obsahovať iba prvky dátového typu int
(celé
číslo). Pokiaľ nie je určené inak, PowerShell nerieši, aké dátové typy
pole obsahuje. V poli teda môžu byť prvky rôznych dátových typov, ako je
znázornené na príklade nižšie:
$Pole=@(1,'text',(get-date))
Na tomto príklade môžeme vidieť, že pole obsahuje 3 prvky, kde každý
je iného dátového typu. Ak však chceme, aby v poli boli iba prvky určitého
typu údajov, napríklad iba pole čísel (int
), zabezpečíme to
týmto výrazom:
[int[]]$PoleInt=@(1,2,3)
Ak by sme sa predsa len pokúsili do toho poľa umiestniť prvok, ktorý nespĺňa dátový typ alebo PowerShell nebol schopný vykonať konverziu dátového typu, PowerShell zahlási chybu:
Windows PowerShell [int[]]$PoleInt=@(1,2,3,'text') Cannot convert value "text" to type "System.Int32". Error: "Input string was not in a correct format." At line:1 char:1 + [int[]]$PoleInt=@(1,2,3,'text') + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException + FullyQualifiedErrorId : RuntimeException
Ak však do poľa umiestnime prvok, ktorý je možné konvertovať,
PowerShell tento prvok skonvertuje na požadovaný typ údajov
[int]
a pridá ho do poľa. K tomu, čo sa deje na pozadí, opäť
použijeme príkaz Trace-Command
:
Windows PowerShell Trace-Command -Expression {[int[]]$PoleInt=@(1,2,3,'1')} -Name TypeConversion -PSHost DEBUG: TypeConversion Information: 0 : Converting "System.Object[]" to "System.Int32[]". DEBUG: TypeConversion Information: 0 : Converting "1" to "System.Int32". DEBUG: TypeConversion Information: 0 : Result type is assignable from value to convert's type DEBUG: TypeConversion Information: 0 : Converting "2" to "System.Int32". DEBUG: TypeConversion Information: 0 : Result type is assignable from value to convert's type DEBUG: TypeConversion Information: 0 : Converting "3" to "System.Int32". DEBUG: TypeConversion Information: 0 : Result type is assignable from value to convert's type DEBUG: TypeConversion Information: 0 : Converting "1" to "System.Int32". DEBUG: TypeConversion Information: 0 : Converting to integer.
Ochrana dátového typu v poli v praxi
Ako dobrý príklad, kedy využiť ochrany dátového typu, je napríklad vstupný parameter funkcie:
# Tato funkce otestuje port nebo pole portů oproti lokálnímu nebo vzdálenému počítači function Test-TcpPort { param ( [parameter(Mandatory)][int[]]$Port, $ComputerName=$env:COMPUTERNAME ) $Port | ForEach-Object { $PortToTest = $_ $obj = New-Object psobject -Property @{ ComputerName = $ComputerName Port = $PortToTest State = $null } try { [System.Net.Sockets.TcpClient]::new().Connect($ComputerName,$_) $obj.State = 'open' } catch { $obj.State = 'closed' } finally { Write-Output $obj } } }
Na tomto príklade prebehlo všetko v poriadku:
Windows PowerShell Test-TcpPort 3389,80,23 Port ComputerName State ---- ------------ ----- 3389 W0466418 open 80 W0466418 open 23 W0466418 closed
A tu môžeme vidieť ochranu dátového typu v akcii:
Windows PowerShell Test-TcpPort 3389,80,23,'test' Test-TcpPort : Cannot process argument transformation on parameter 'Port'. Cannot convert value "test" to type "System.Int32". Error: "Input string was not in a correct format." At line:1 char:14 + Test-TcpPort 3389,80, 23, 'test' + ~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidData: (:) [Test-TcpPort], ParameterBindingArgumentTransformationException + FullyQualifiedErrorId : ParameterArgumentTransformationError,Test-TcpPort
A príkaz vyššie ešte raz, tentokrát s ukážkou toho, ako sa PowerShell neúspešne snaží o konverziu dátového typu:
Windows PowerShell Trace-Command -Expression {Test-TcpPort 3389,80, 23, 'test'} -Name TypeConversion -PSHost DEBUG: TypeConversion Information: 0 : Converting "System.Object[]" to "System.Int32[]". DEBUG: TypeConversion Information: 0 : Converting "3389" to "System.Int32". DEBUG: TypeConversion Information: 0 : Result type is assignable from value to convert's type DEBUG: TypeConversion Information: 0 : Converting "80" to "System.Int32". DEBUG: TypeConversion Information: 0 : Result type is assignable from value to convert's type DEBUG: TypeConversion Information: 0 : Converting "23" to "System.Int32". DEBUG: TypeConversion Information: 0 : Result type is assignable from value to convert's type DEBUG: TypeConversion Information: 0 : Converting "test" to "System.Int32". DEBUG: TypeConversion Information: 0 : Converting to integer. DEBUG: TypeConversion Information: 0 : Exception converting to integer: "Input string was not in a correct format.". DEBUG: TypeConversion Information: 0 : Converting to integer passing through double. DEBUG: TypeConversion Information: 0 : Numeric Conversion through System.Double. DEBUG: TypeConversion Information: 0 : Exception converting to integer through double: "Input string was not in a correct format.". DEBUG: TypeConversion Information: 0 : Converting "256" to "System.Int32". DEBUG: TypeConversion Information: 0 : Result type is assignable from value to convert's type DEBUG: TypeConversion Information: 0 : Converting ref to boolean. DEBUG: TypeConversion Information: 0 : Converting ref to boolean. DEBUG: TypeConversion Information: 0 : Converting string to boolean. DEBUG: TypeConversion Information: 0 : Converting ref to boolean. DEBUG: TypeConversion Information: 0 : Converting ref to boolean. DEBUG: TypeConversion Information: 0 : Converting null to boolean. DEBUG: TypeConversion Information: 0 : Converting string to boolean. DEBUG: TypeConversion Information: 0 : Converting string to boolean. DEBUG: TypeConversion Information: 0 : Converting null to boolean. Test-TcpPort : Cannot process argument transformation on parameter 'Port'. Cannot convert value "test" to type "System.Int32". Error: "Input string was not in a correct format." At line:1 char:41 + Trace-Command -Expression {Test-TcpPort 3389,80, 23, 'test'} -Name Ty ... + ~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidData: (:) [Test-TcpPort], ParameterBindingArgumentTransformationException + FullyQualifiedErrorId : ParameterArgumentTransformationError,Test-TcpPort
V ďalšej lekcii, PowerShell - Kolekcia objektov, II. časť , sa zoznámime s PowerShell kolekciami a názorne si ukážeme, ako s každou z nich pracovať.