IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

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ípade 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í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 0poč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ť.


 

Predchádzajúci článok
PowerShell - Typy výstupu
Všetky články v sekcii
PowerShell
Preskočiť článok
(neodporúčame)
PowerShell - Kolekcia objektov, II. časť
Článok pre vás napísal Vojtěch Kašný
Avatar
Užívateľské hodnotenie:
1 hlasov
Aktivity