PowerShell-grundlæggende oplysninger: Brugerdefinerede objekter

Windows PowerShell er et kommando-shell-miljø, der understøtter objektorienteret scripting baseret på Microsoft .NET Framework. Hjertet er PowerShell-cmdletten, en letvægtskommando, der udfører en bestemt handling og i den forbindelse returnerer et .NET-objekt. Med PowerShell kan du bruge cmdlets til at få adgang til en række forskellige systemer og udføre mange opgaver på disse systemer. Men cmdlets alene er ikke altid nok til at udføre visse handlinger. Til disse handlinger skal du ofte oprette dine egne objekter baseret på .NET-klasserne. En type .NET-objekt, du kan oprette, er det brugerdefinerede objekt. Med et brugerdefineret objekt kan du definere de datatyper, der er tildelt det pågældende objekt, og de handlinger, det kan udføre. Når du har forstået, hvordan du opbygger et brugerdefineret objekt, har du et effektivt værktøj til at opbygge scripts, der kan udvide PowerShells allerede betydelige rækkevidde.

Bemærk, at .NET Framework og objektorienteret programmering er komplekse emner, der ligger langt uden for rammerne her. For fuldt ud at forstå PowerShells objektorienterede karakter kan det være en hjælp at have i det mindste en grundlæggende forståelse af disse begreber. Du kan finde flere oplysninger om .NET Framework i MSDN-artiklen “Overview of the .NET Framework” (oversigt over .NET Framework). Du kan finde en introduktion til objektorienteret programmering i MSDN-artiklen “Object-Oriented Programming (C# and Visual Basic).”

Skabelse af et brugerdefineret objekt

For at oprette et brugerdefineret objekt i PowerShell skal du først bruge cmdletten New-Object til at oprette det oprindelige objekt. Med denne cmdlet kan du oprette .NET- eller COM-objekter fra et udvalg af klasser. Et brugerdefineret objekt er en særlig type .NET-objekt, der er baseret på enten Object- eller PSObject .NET-klassen. Der er ingen forskel på de to, når du opretter det oprindelige objekt. PSObject-klassen foretrækkes dog generelt på grund af de problemer, der kan opstå, når der tilføjes egenskaber til et objekt baseret på Object-klassen, så lad os bruge PSObject.

For at oprette et objekt baseret på PSObject-klassen skal du bruge cmdletten New-Object med parameteren -TypeName og angive PSObject-klassen som parameterens værdi, som her:

$system = New-Object -TypeName PSObject

Når du kører denne kommando, genererer den et PSCustomObject-objekt og tildeler det til variablen $system. Oftest ønsker du at tildele objektet til en variabel, så du nemt kan arbejde med objektets medlemmer. Medlemmerne er de komponenter, der udgør et objekt, f.eks. egenskaber, metoder, aliasegenskaber og medlemssæt.

Når du arbejder med objekter i PowerShell, er de to medlemstyper, du sandsynligvis vil bruge, egenskaber og metoder. En egenskab beskriver et bestemt aspekt af objektet. Et af medlemmerne i FileInfo .NET-klassen FileInfo .NET-klassen er f.eks. egenskaben Length, som angiver en filstørrelse i bytes. Hvis du opretter et FileInfo-objekt baseret på denne klasse, kan du bruge egenskaben Length til at få adgang til størrelsen af den fil, der er knyttet til dette objekt. En metode udfører en handling i forbindelse med objektet. F.eks. indeholder FileInfo-klassen også metoden Delete, som du kan bruge til at slette den fil, der er repræsenteret af objektet.

Det er nemmere at arbejde med et objekt, hvis du nemt kan identificere dets medlemmer. Hvis du vil have en liste over de medlemmer, som et objekt består af, kan du bruge cmdletten Get-Member. Hvis du f.eks. vil se medlemmerne af det nye objekt, der blev tildelt variablen $system, kan du sende variablen $system via pipe til cmdletten Get-Member:

$system | Get-Member

Som det fremgår af figur 1, er det objekt, du har oprettet, baseret på klassen System.Management.Automation.PSCustomObject, som kun indeholder et lille antal medlemmer, der alle er metoder. Men det er derfor, det kaldes et brugerdefineret objekt – du kan tilpasse det ved at tilføje dine egne medlemmer.

Figur 1: Det nye objekts liste over medlemmer

Hvor jeg viser dig, hvordan du tilføjer medlemmer, vil jeg lige tilføje, at PSCustomObject-klassen, ligesom mange .NET-klasser, også indeholder en række skjulte medlemmer af forskellige typer, f.eks. memberset og codeproperty. Du kan få vist disse medlemmer ved at medtage parameteren -Force, når du kalder cmdletten Get-Member. Selv om en diskussion af skjulte medlemmer ligger uden for rammerne her, kan du på et tidspunkt finde det nyttigt at udforske de skjulte medlemmer, der er tilgængelige for PSCustomObject-klassen og andre .NET-klasser, for at få fuldt udbytte af dine PowerShell-objekter.

Tilføjelse af egenskaber til et brugerdefineret objekt

Et brugerdefineret objekt er kun så nyttigt som de medlemmer, der er knyttet til objektet. Du kan tilføje flere forskellige typer medlemmer til et brugerdefineret objekt. I dette eksempel skal du tilføje medlemmerne NoteProperty og ScriptMethod. Et NoteProperty-medlem svarer til en almindelig egenskab, og et ScriptMethod-medlem svarer meget til en almindelig metode. Du kan ikke tilføje en almindelig egenskab eller metode til et brugerdefineret objekt, og det er derfor, at du bruger NoteProperty og ScriptMethod. (Du kan finde oplysninger om de understøttede medlemmer i et brugerdefineret objekt i PowerShell TechNet-emnet “Add-Member.”)

Lad os starte med at tilføje et par NoteProperty-medlemmer til objektet $system. Hvis du vil tilføje medlemmerne, kan du bruge cmdletten Add-Member til at definere egenskabens navne og værdier. Lad os f.eks. antage, at du vil tilføje noteegenskaber baseret på data hentet via WMI-funktionerne (Windows Management Instrumentation), der er indbygget i PowerShell. (WMI leverer en infrastruktur til styring af data og operationer i Windows OS’er). WMI-objektmodellen omfatter adskillige klasser, der understøtter en lang række forvaltningsoperationer. Klassen Win32_OperatingSystem giver f.eks. adgang til oplysninger som navnet på det operativsystem, der er installeret på en computer, og den seneste service pack, der er anvendt på det pågældende operativsystem.

For at oprette et WMI-objekt skal du bruge cmdletten Get-WmiObject og angive den ønskede klasse. Hvis du f.eks. vil oprette et Win32_OperatingSystem WMI-objekt og tildele det til variablen $os, skal du bruge koden:

$os = Get-WmiObject Win32_OperatingSystem

I dette tilfælde henter du systemoplysninger fra den lokale computer, men det smukke ved WMI er, at det også kan få adgang til og administrere eksterne Windows-computere.

Du kan derefter bruge variablen $os til at få adgang til de oplysninger, der returneres af dette objekt. Ved at tildele et objekt til en variabel på denne måde låses dataene på det pågældende tidspunkt. Hvis der f.eks. anvendes en ny service pack på operativsystemet, efter at du har oprettet $os-variablen, vil objektets CSDVersion-egenskab ikke afspejle ændringen, fordi objektet var blevet oprettet på grundlag af de oprindelige data.

Når du har defineret $os-variablen, skal du angive to Add-Member-kommandoer. Hver kommando vil tage fire parametre:

  • -InputObject. Du bruger parameteren -InputObject til at identificere det objekt, der modtager de nye nodeegenskaber. I dette tilfælde skal du angive objektet $system.
  • -MemberType. Parameteren -MemberType angiver den type medlem, der skal oprettes, så du skal angive NoteProperty.
  • -Name. Du bruger parameteren -Name til at angive navnet på det nye medlem. I dette eksempel giver vi det første medlem navnet OperatingSystem og det andet medlem navnet ServicePack.
  • -Value. Denne parameter angiver medlemmets værdi. For den første notejendom skal du angive $os.Caption for at returnere navnet på OS. For den anden note-egenskab skal du angive $os.CSDVersion for at returnere den seneste servicepack, der er anvendt på OS’et.

Der er, hvordan de to Add-Member-kommandoer ser ud:

Add-Member -InputObject $system -MemberType NoteProperty ` -Name OperatingSystem -Value $os.CaptionAdd-Member -InputObject $system -MemberType NoteProperty ` -Name ServicePack -Value $os.CSDVersion

Bemærk, at jeg har opdelt hver Add-Member-kommando i to linjer. I slutningen af hver første linje har jeg inkluderet et bagkryds (`), så PowerShell-processoren ved, at den skal fortsætte til den næste linje for at få den komplette kommando.

Når du har kørt Add-Member-kommandoerne, kan du kalde $system-variablen for at få vist dens indhold:

$system

Figur 2 viser et eksempel på resultaterne.

Figur 2: Indholdet af $system-variablen

Du kan også bruge $system-variablen til at kalde individuelle medlemmer. Du skal blot angive variablens navn efterfulgt af et punktum og derefter navnet på medlemmet. Følgende kommando returnerer f.eks. den aktuelle værdi af noteegenskaben OperatingSystem:

$system.OperatingSystem

En af fordelene ved at oprette et brugerdefineret objekt er, at du kan oprette noteegenskaber baseret på data, der kommer fra forskellige kilder, samt en noteegenskab, hvis værdi er en bestemt streng. Tag f.eks. et kig på koden i Listing 1, som tilføjer tre nye noteegenskaber til objektet $system.

$mem = Get-WmiObject Win32_PhysicalMemory$disk = Get-WmiObject Win32_DiskDriveAdd-Member -InputObject $system -MemberType NoteProperty ` -Name PhysicalMemory ` -Value (("{0:N2}" -f ($mem.Capacity/1GB)) + ' GB')Add-Member -InputObject $system -MemberType NoteProperty ` -Name DiskSize ` -Value (("{0:N2}" -f ($disk.Size/1GB)) + ' GB')Add-Member -InputObject $system -MemberType NoteProperty ` -Name Owner -Value "janetp"

De fleste af elementerne i Listing 1 så du i det foregående eksempel. Bemærk dog, at koden opretter en instans af Win32_PhysicalMemory-klassen, som tildeles variablen $mem, og en instans af Win32_DiskDrive-klassen, som tildeles variablen $disk. To af de tilføjede noteegenskaber bruger disse nye WMI-objekter som datakilder.

Den første Add-Member-kommando henter data fra egenskaben $mem.Capacity, som angiver hukommelsens kapacitet på målsystemet. I dette tilfælde er parameteren -Value imidlertid lidt mere kompleks, end du så i det foregående eksempel. For det første angiver kommandoen “{0:N2}” efterfulgt af -f, som er en .NET-konstruktion til formatering af det uddata tal, der udskrives. I bund og grund angiver dette, at et tal skal returneres med to decimaler. Formateringsinstruktionerne efterfølges af et kort udtryk ($mem.Capacity/1GB), der dividerer Capacity-værdien med 1 GB. Capacity-værdien angiver hukommelsens størrelse i bytes. PowerShell gør det nemt at konvertere bytes til gigabyte ved blot at dividere med 1 GB. Til sidst markerer kommandoen strengen ‘ GB’ (inklusive mellemrum) på output og omslutter det hele i parenteser.

Den anden Add-Member-kommando følger samme logik for at returnere størrelsen på computerens harddisk. Den bruger egenskaben $disk.Size til at returnere størrelsen i bytes og konverterer den derefter til gigabytes.

Den tredje Add-Member-kommando tilføjer en note-egenskab ved navn Owner og tildeler den strengværdien janetp. I dette tilfælde kan “ejer” betyde hvad som helst – den primære bruger, den sidste bruger, administratoren, eller hvilken betydning du ønsker at pålægge egenskaben. Jeg har kun medtaget det her for at demonstrere, at du kan tilføje en noteegenskab, hvis værdi er en simpel streng.

Når du har tilføjet de tre medlemmer til det brugerdefinerede objekt, kan du igen kalde variablen $system. Den vil returnere resultater som dem, der er vist i figur 3.

Figur 3: Noteegenskaber tilføjet med Add-Member-cmdletten

Du har nu et enkelt objekt, der indeholder data, der stammer fra tre forskellige WMI-objekter. Objektet indeholder også egenskaben Owner, som er baseret på en strengværdi. Du kan kalde denne notejendom, som du ville kalde ethvert andet medlem:

$system.Owner

Som du kan forvente, returnerer kommandoen værdien janetp. Du kan dog ændre denne værdi til en anden ved at tildele en ny værdi til egenskaben, som her:

$system.Owner = "rogert"

I dette tilfælde er værdien rogert blevet tildelt egenskaben Owner note. Hvis du kalder denne noteegenskab nu, returnerer den den nye værdi.

Som med mange af de opgaver, du kan udføre i PowerShell, er der en række forskellige måder at tilføje et medlem til et brugerdefineret objekt på. Med PowerShell 3.0 kan du f.eks. oprette en hash-tabel og sende hash’en til kommandoen New-Object. Koden i Listing 2 opretter de samme fem noteegenskaber, men bruger en hashtabel til at videregive medlemsnavne og -værdier.

$info = @{ "OperatingSystem" = $os.Caption; "ServicePack" = $os.CSDVersion; "PhysicalMemory" = (("{0:N2}" -f ($mem.Capacity/1GB)) + ' GB'); "DiskSize" = (("{0:N2}" -f ($disk.Size/1GB)) + ' GB'); "Owner" = 'janetp'}$system = New-Object -TypeName PSObject -Property $info$system

Denne kode opretter først en hashtabel, der definerer fem egenskabs-/værdipar, som hver især svarer til noteegenskaberne. Som det fremgår af koden, skal du adskille egenskabs/værdi-parrene med semikoloner. Du skal også omslutte sættet af fem egenskabs-/værdipar i parenteser og sætte symbolet at (@) foran den åbne parentes. Endelig skal du tildele hashtabellen til variablen $info.

Når hashtabellen er defineret, bruger koden cmdletten New-Object til at oprette et objekt baseret på PSObject-klassen og tildeler det til variablen $system. Kun denne gang indeholder kommandoen parameteren -Property, som tager variablen $info som værdi.

Sluttelig kalder koden variablen $system, som returnerer resultater som i figur 4. Bemærk den rækkefølge, i hvilken egenskaberne er blevet tilføjet til objektet. Et af problemerne ved at bruge en hashtabel til at tilføje noteegenskaber er, at du ikke kan styre deres rækkefølge. Hvis du vil styre rækkefølgen, skal du bruge cmdletten Add-Member til at tilføje hvert enkelt medlem.

Figur 4: Noteegenskaber oprettet med hashtabellen

Tilføjelse af metoder til et brugerdefineret objekt

Nu da du har set, hvor nemt det er at tilføje egenskaber, få adgang til deres værdier og ændre disse værdier, skal vi gå videre til metoder. Disse bliver lidt mere komplicerede, fordi metoder skal gøre noget, og du skal definere dette noget som en del af metodens værdi.

Koden i Listing 3 opretter f.eks. en metode, der henter den aktuelle dato og det aktuelle klokkeslæt og returnerer dem både i deres oprindelige format og som UTC-værdier (Coordinated Universal Time).

$method ={ $a = Get-Date -Format F; "Local: " + $a; $b = Get-Date; "UTC: " + $b.ToUniversalTime().DateTime}Add-Member -InputObject $system -MemberType ScriptMethod ` -Name GetUTC -Value $method

For at holde koden læsbar kan du tildele metodens værdi til en variabel (f.eks. $method). Denne værdi indeholder de udtryk, der er nødvendige for at returnere dato- og tidsoplysningerne. Du skal dog definere værdien som en scriptblok for at kunne sende den ind i kommandoen Tilføj medlem. For at gøre dette skal du omslutte værdien indhold i krøllede parenteser. PowerShell tildeler derefter værdien i sin nuværende form til variablen som et ScriptBlock-objekt.

I Listing 3 indeholder metodens værdi to udtryk. Det første udtryk returnerer den aktuelle dato og det aktuelle klokkeslæt, og det andet udtryk returnerer UTC-versionen. Du starter det første udtryk ved at bruge cmdletten Get-Date til at hente den aktuelle dato og det aktuelle klokkeslæt, som du tildeler variablen $a. Bemærk, at når du kalder cmdletten Get-Date, skal du medtage parameteren -Format sammen med værdien F. Dette fortæller PowerShell, at tidsstemplet skal vises i et fuldt dato- og klokkeslætformat, som i mandag den 19. august 2013 kl. 12:28:25 PM. Derefter tilføjer du strengen “Local: ” (inklusive mellemrum) til variabelværdien for at returnere den aktuelle dato og klokkeslæt sammen med denne etiket.

I det andet udtryk starter du igen med cmdletten Get-Date for at returnere den aktuelle dato og det aktuelle klokkeslæt, som du tildeler variablen $b. Derefter bruger du variablens ToUniversalTime-metode til at returnere dato og klokkeslæt som en UTC-værdi og angiver derefter DateTime-egenskaben for at returnere det korrekte format.

Hvis du kalder variablen $method på dette tidspunkt, vil den returnere de to udtryk som strenge, præcis som de blev indtastet. Fordi du har defineret variabelværdien som en scriptblok, behandles kommandoerne ikke, når de tildeles variablen $method. I stedet oprettes variablen $method som et ScriptBlock-objekt, hvilket du kan bekræfte ved at bruge GetType-metoden for at se variablens type:

$method.GetType()

For at arbejde med scriptblokken skal du tilføje metoden som et medlem af objektet $system, efter at du har defineret variablen $method. Det gør du ved at oprette en Add-Member-kommando, der angiver ScriptMethod som type, GetUTC som navn og variablen $method som værdi.

Når du har kørt koden i Listing 3, kan du bruge variablen $system til at kalde GetUTC-metoden på stort set samme måde, som du kaldte egenskaberne:

$system.GetUTC()

Bemærk dog, at når du kalder scriptmetoden, skal du medtage parenteserne, ligesom du gør for enhver anden metode, også selvom du ikke afgiver argumenter. Metoden bør nu returnere resultater svarende til dem i figur 5, men med den dato og det tidspunkt, hvor du kaldte metoden.

Figur 5: Eksempel på resultater fra GetUTC()-metoden

I det virkelige liv vil du sandsynligvis gerne oprette metoder, der har mere slagkraftighed. F.eks. kan objektet $system inkorporere WMI-håndteringsopgaver i sine scriptmetoder. Hvis du gør det, skal du teste metoden fuldt ud for at sikre dig, at dine kommandoer gør præcis, hvad de skal gøre. PowerShell og WMI er begge kraftige værktøjer, så de skal bruges med omhu, når du administrerer Windows-computere.

Tilføjelse af brugerdefinerede objekter til et array

Brugerdefinerede objekter er ikke begrænset til enkeltstående objekter, som du bruger én gang og smider til side. Du kan tilføje disse objekter til et objektarray og derefter få adgang til objekterne via dette array. Antag f.eks. at du ønsker at manipulere oplysninger, som du henter fra flere computere. Disse oplysninger kan omfatte oplysninger om den hukommelse og de logiske drev, der er tilgængelige på disse systemer. Du ønsker at kunne arbejde med disse oplysninger på en meningsfuld måde i PowerShell. På grund af PowerShells objektorienterede karakter er det ofte den enkleste måde at arbejde med disse data på at placere disse oplysninger i objekter.

Lad os se på et eksempel på, hvordan du kan gøre dette. I forbindelse med denne diskussion er den metode, der anvendes til at indsamle oplysninger om de forskellige computere, uvæsentlig. Du kan f.eks. oprette en foreach-loop i PowerShell, der bruger WMI til at hente oplysningerne fra de forskellige arbejdsstationer. Uanset hvilken metode der anvendes, antager vi for at gøre det kortfattet, at du har indsamlet oplysningerne i en kommasepareret tekstfil, der indeholder de data, der er vist i figur 6.

Figur 6: Indsamlede WMI-data

Tekstfilen indeholder en overskriftsrække og en række for de enkelte systemers logiske drev. Den første datarække indeholder f.eks. oplysninger om det logiske drev C på computeren ws01. Det logiske drev har en kapacitet på 500 GB med 225 GB ledig plads. Systemet har også 4 GB hukommelse. Den anden række angiver, at den samme computer også indeholder det logiske D-drev, som har samme kapacitet som C-drevet, men med 320 GB ledig plads.

Målet er at omdanne hver datarække til sit eget brugerdefinerede objekt og derefter tilføje disse objekter til et array. Du kan derefter foretage handlinger på objekterne i arrayet ved at sende dataene via rørledninger til andre PowerShell-kommandoer. Koden i Listing 4 definerer et tomt array, importerer dataene fra tekstfilen og bruger derefter en foreach-sløjfe til at oprette objekterne og føje dem til arrayet.

$SystemInfo = @()$SourceData = Import-CSV C:\DataFiles\SourceData.txtforeach ($source in $SourceData){ $system = New-Object -TypeName PSObject $system | Add-Member -Type NoteProperty ` -Name Computer -Value $source.Computer $system | Add-Member -Type NoteProperty ` -Name DeviceID -Value $source.DeviceID $system | Add-Member -Type NoteProperty ` -Name DriveSize -Value ($source.DriveSize) $system | Add-Member -Type NoteProperty ` -Name UsedSpace ` -Value ($source.DriveSize - $Source.FreeSpace) $system | Add-Member -Type NoteProperty ` -Name FreeSpace -Value ($source.FreeSpace) $SystemInfo += $system}

Som du kan se, er det første trin at oprette det tomme array (@()) og tildele det til variablen $SystemInfo. Til sidst tilføjer du de brugerdefinerede objekter til dette array.

Næste trin er at bruge cmdletten Import-CSV til at importere dataene til variablen $SourceData. I denne øvelse hedder tekstfilen SourceData.txt og gemmes i mappen C:\DataFiles. Cmdletten Import-CSV henter hver række som sit eget objekt og gemmer den i $SourceData. På dette tidspunkt kunne du bruge denne variabel til at få adgang til dataene, men du ville ikke have nogen kontrol over de medlemmer, der indgår i objektet, og du ville heller ikke kunne tilføje medlemmer.

Det næste skridt er derfor at oprette en foreach-loop, så du kan oprette et brugerdefineret objekt for hver række i tekstfilen. Foreach-betingelsen ($source i $SourceData) angiver, at hver række i $SourceData skal tildeles variablen $source, efterhånden som koden iterererer gennem foreach-loopet. Den logik, der er defineret i foreach-scriptblokken (omsluttet af krøllede parenteser), kører derefter én gang for hver række, og der anvendes et andet $source-objekt ved hver gentagelse. (Du kan finde flere oplysninger om oprettelse af en foreach-loop i PowerShell TechNet-emnet about_ForEach.)

Lad os se nærmere på foreach-scriptblokken. Den første kommando opretter det oprindelige objekt og gemmer det i variablen $system, som du så i de tidligere eksempler. Dernæst bliver $system-variablen ledt til en Add-Member-kommando for at oprette den første note-egenskab. Dette er et lidt anderledes format end det tidligere anvendte. I stedet for at inkludere parameteren -InputObject i Add-Member-kommandoen, skal du blot sende $system via rørledning til kommandoen. Herved opnås de samme resultater, som du så i de tidligere eksempler på Add-Member-kommandoer. Jeg har valgt denne fremgangsmåde her blot for at demonstrere endnu en måde, hvorpå PowerShell giver dig mulighed for at tilføje medlemmer.

For Add-Member-kommandoens værdi bruger du variablen $source til at kalde egenskaben Computer, som svarer til Computer-feltet i kildedataene. Den anden Add-Member-kommando fungerer på samme måde, bortset fra at den henter data fra egenskaben DeviceID. Bemærk, at egenskaben Memory ikke er medtaget. Når du opretter et brugerdefineret objekt, kan du udelade bestemte egenskaber eller placere dem i en anden rækkefølge.

Den tredje Add-Member-kommando fungerer stort set på samme måde som de to første, bortset fra at den har adgang til DriveSize-egenskaben. Da du måske ønsker at arbejde med disse data som en numerisk værdi i stedet for en streng, konverterer kommandoen udtrykkeligt dataene til et tal. Dette opnås ved at sætte et punkt foran egenskabsnavnet for at angive, at du ønsker datatypenint, og derefter omslutte hele egenskabsudtrykket i parentes.

Den fjerde Add-Member-kommando gør noget lidt anderledes. Den opretter et beregnet medlem, der trækker FreeSpace-værdien fra DriveSize-værdien for at bestemme mængden af brugt plads. Igen indledes egenskabsnavnet med , og hele udtrykket er omsluttet af parenteser. At kunne oprette en beregnet egenskab er en af hovedårsagerne til, at du måske ønsker at oprette brugerdefinerede objekter.

Den sidste Add-Member-kommando fungerer ligesom den tredje, bortset fra at den henter data fra FreeSpace-egenskaben.

Den sidste kommando i foreach-scriptblokken tilføjer det aktuelle $system-objekt til $SystemInfo-arrayet. Bemærk, at operatoren += bruges til at sikre, at det nye $system-objekt tilføjes ved hver gentagelse af sløjfen, uden at noget bliver overskrevet.

Når du har kørt koden i Listing 4, kan du kalde variablen for at se dens indhold. Figur 7 viser en delvis liste over de data, der nu er gemt i arrayet $SystemInfo.

Figur 7: Data gemt i arrayet $SystemInfo

Specifikt viser den dataene for de første syv objekter i arrayet, hvilket svarer til de første syv rækker data i den oprindelige tekstfil. Hver gruppering repræsenterer et af de objekter, der er tilføjet til arrayet $SystemInfo. Du kan kontrollere, at du har oprettet et objektarray ved at bruge GetType-metoden til at hente variablens type:

$SystemInfo.GetType()

Hvis denne kommando returnerer BaseType på System.Array, er variablen $SystemInfo faktisk et objektarray, der kan indeholde brugerdefinerede objekter. Du kan derefter bruge denne variabel til at manipulere dataene på den måde, du ønsker. Du kan f.eks. sende variablen via pipe til en Sort-Object-kommando for at sortere dataene i faldende rækkefølge baseret på FreeSpace-værdierne:

$SystemInfo | Sort FreeSpace -Descending

I dette tilfælde bruger kommandoen aliaset Sort til at henvise til Sort-Object-cmdletten og indeholder FreeSpace-egenskaben og parameteren -Descending. Som du kan se i figur 8, vises objekterne nu på listen i henhold til FreeSpace-værdierne, med den højeste mængde ledig plads først på listen. Igen er dette kun en del af listen.

Figur 8: Data sorteret efter mængden af ledig plads

Du kan også sortere dataene på baggrund af flere kolonner. Du kan f.eks. sortere dataene først efter egenskaben Computer og derefter efter egenskaben FreeSpace i faldende rækkefølge:

$SystemInfo | Sort Computer, FreeSpace -Descending

Som du kan forvente, er resultaterne nu meget anderledes, som det fremgår af figur 9.

Figur 9: Data sorteret efter computernavn og mængden af ledig plads i faldende rækkefølge

En af konsekvenserne af at sortere kolonnerne på denne måde er, at Computer-værdierne såvel som FreeSpace-værdierne er sorteret i faldende rækkefølge. Med cmdletten Sort-Object kan du ikke nemt sortere en kolonne i stigende rækkefølge og en anden kolonne i faldende rækkefølge. Hvis du angiver parameteren -Descending, bliver alle data sorteret i denne rækkefølge. Du kan dog omgå denne begrænsning ved at oprette udtryk for hver egenskab, der angiver, hvordan disse værdier skal sorteres. Følgende kommando sorterer f.eks. først efter Computer-egenskaben i stigende rækkefølge og derefter efter FreeSpace-egenskaben i faldende rækkefølge:

$SystemInfo | Sort ` @{Expression="Computer"; Descending=$false}, @{Expression="FreeSpace"; Descending=$true}

Det første Sort-Object-udtryk indstiller Expression-egenskaben til Computer og Descending-egenskaben til $false. Det andet udtryk indstiller Expression-egenskaben til FreeSpace og Descending-egenskaben til $true. (Variablerne $true og $false er indbyggede systemvariabler, der giver de boolske værdier 1 og 0 som henholdsvis sand og falsk). Du skal derefter omslutte hvert udtryk i krøllede parenteser og sætte symbolet at (@) foran hver åbne parentes. Nu bliver dataene sorteret i den ønskede rækkefølge, som vist i figur 10.

Figur 10: Data sorteret efter computernavn i stigende rækkefølge og mængden af ledig plads i faldende rækkefølge

Dette kan virke som overkill i forbindelse med sortering, men det peger på den fleksibilitet, der er ved at arbejde med objekter i et array. Og du er bestemt ikke begrænset til cmdletten Sort-Object. I følgende kommando sendes f.eks. variablen $SystemInfo via rørledning til cmdletten Where-Object:

$SystemInfo | Where DriveSize -gt 250 | Sort FreeSpace -Descending

I dette tilfælde bruger kommandoen aliaset Where til at henvise til cmdletten Where-Object. Desuden angiver den, at DriveSize-værdien skal være større end 250 for at blive medtaget i resultaterne. (I PowerShell bruges -gt til operatoren større end.) De resultater, der opfylder disse kriterier, ledes til cmdletten Sort-Object, så dataene vises i den rigtige rækkefølge.

Du kan endda lede de sorterede data til en Select-Object-kommando, som her:

$SystemInfo | Where DriveSize -gt 250 | Sort FreeSpace -Descending | Select -First 5

Denne kommando bruger cmdletten Select-Object (refereret af aliaset Select) til kun at returnere de første fem rækker i resultatsættet. Som du kan se, har du en række forskellige muligheder for at arbejde med disse objekter, når du først har tilføjet brugerdefinerede objekter til arrayet $SystemInfo.

Få mest muligt ud af dine brugerdefinerede objekter

For det meste er det en ret ligetil proces at oprette brugerdefinerede objekter i PowerShell. Hvis der er nogen kompleksitet involveret, kommer det generelt fra de værdiudtryk, du definerer for dine noteegenskaber eller scriptmetoder. Udtrykkene i disse eksempler er relativt enkle sammenlignet med de typer af udtryk, du kan oprette i PowerShell. Alligevel burde det, du har set her, give dig det fundament, du har brug for til at oprette brugerdefinerede objekter. Når de bruges effektivt, kan de være en effektiv komponent i dine PowerShell-scripts, uanset om du opretter individuelle objekter, tilføjer dem til et array eller bruger dem på en anden måde. Du kan f.eks. oprette brugerdefinerede objekter i din PowerShell-profil, så de er tilgængelige, hver gang du starter en ny session. Det er op til dig, hvordan du bruger brugerdefinerede objekter i dine scripts. Du skal blot vide, at det brugerdefinerede objekt er et effektivt og fleksibelt værktøj, der kan opfylde mange af dine scriptingbehov.

For yderligere oplysninger om oprettelse af brugerdefinerede objekter i Windows PowerShell henvises til Bill Stewarts “Creating Custom Objects in Windows PowerShell.”

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.