PowerShell-basisbegrippen: Aangepaste objecten

Windows PowerShell is een opdrachtshell-omgeving die objectgeoriënteerde scripting ondersteunt op basis van het Microsoft .NET Framework. Het hart ervan is de PowerShell cmdlet, een lichtgewicht opdracht die een specifieke actie uitvoert en daarbij een .NET object retourneert. Met PowerShell kunt u cmdlets gebruiken om toegang te krijgen tot een verscheidenheid van systemen en talrijke taken uit te voeren op die systemen. De cmdlets alleen zijn echter niet altijd voldoende om bepaalde acties uit te voeren. Voor die acties moet je vaak je eigen objecten maken op basis van de .NET classes. Een type .NET object dat je kunt bouwen is het custom object. Met een aangepast object kunt u de typen gegevens definiëren die aan dat object worden toegewezen en de acties die het kan uitvoeren. Nadat u hebt begrepen hoe u een aangepast object kunt bouwen, beschikt u over een krachtig hulpmiddel voor het bouwen van scripts die het reeds aanzienlijke bereik van PowerShell kunnen uitbreiden.

Merk op dat het .NET Framework en objectgeoriënteerd programmeren complexe onderwerpen zijn, die hier ver buiten het bestek vallen. Om de objectgeoriënteerde aard van PowerShell ten volle te waarderen, kan het helpen om ten minste een basiskennis van deze concepten te hebben. Voor meer informatie over het .NET Framework, zie het MSDN-artikel “Overview of the .NET Framework.” Zie voor een inleiding in objectgeoriënteerd programmeren het MSDN-artikel “Objectgeoriënteerd programmeren (C# en Visual Basic).”

Een aangepast object maken

Om een aangepast object in PowerShell te maken, moet u eerst het cmdlet New-Object gebruiken om het oorspronkelijke object te maken. Met dit cmdlet kunt u .NET- of COM-objecten maken van een reeks klassen. Een aangepast object is een speciaal type .NET-object dat is gebaseerd op de .NET-klasse Object of PSObject. Er is geen verschil tussen de twee bij het maken van het initiële object. Over het algemeen wordt echter de voorkeur gegeven aan de PSObject-klasse vanwege problemen die zich kunnen voordoen bij het toevoegen van eigenschappen aan een object dat is gebaseerd op de Object-klasse, dus laten we PSObject gebruiken.

Om een object te maken dat is gebaseerd op de PSObject-klasse, moet je het cmdlet New-Object gebruiken met de parameter -TypeName en de PSObject-klasse specificeren als de waarde van de parameter, zoals dit:

$system = New-Object -TypeName PSObject

Wanneer je deze opdracht uitvoert, wordt een PSCustomObject-object gegenereerd en toegewezen aan de $system-variabele. Meestal zal je het object willen toewijzen aan een variabele zodat je gemakkelijk kan werken met de leden van dat object. De leden zijn de componenten waaruit een object is opgebouwd, zoals eigenschappen, methoden, alias-eigenschappen en ledenverzamelingen.

Wanneer u werkt met objecten in PowerShell, zijn de twee soorten leden die u waarschijnlijk zult gebruiken, eigenschappen en methoden. Een eigenschap beschrijft een specifiek aspect van het object. Een van de leden van de klasse FileInfo .NET is bijvoorbeeld de eigenschap Length, die de grootte van een bestand in bytes aangeeft. Indien u een FileInfo-object maakt op basis van die klasse, kunt u de eigenschap Length gebruiken om toegang te krijgen tot de grootte van het bestand dat aan dat object is gekoppeld. Een methode voert een actie uit met betrekking tot het object. De klasse FileInfo bevat bijvoorbeeld ook de methode Delete, die u kunt gebruiken om het bestand te verwijderen dat door het object wordt gerepresenteerd.

Het gemakkelijk kunnen identificeren van de leden van een object maakt het eenvoudiger om met dat object te werken. Om een lijst op te vragen van de leden waaruit een object is opgebouwd, kunt u het cmdlet Get-Member gebruiken. Om bijvoorbeeld de leden van het nieuwe object te bekijken dat is toegewezen aan de variabele $system, kunt u de variabele $system naar het cmdlet Get-Member leiden:

$system | Get-Member

Zoals Figuur 1 laat zien, is het object dat u hebt gemaakt gebaseerd op de klasse System.Management.Automation.PSCustomObject, die slechts een klein aantal leden bevat, die alle methoden zijn. Maar daarom wordt het een aangepast object genoemd – u kunt het aanpassen door uw eigen leden toe te voegen.

Figuur 1: De ledenlijst van het nieuwe object

Voordat ik u laat zien hoe u leden kunt toevoegen, wil ik nog even toevoegen dat, net als veel .NET-klassen, de klasse PSCustomObject ook een aantal verborgen leden van verschillende typen bevat, zoals memberset en codeproperty. Je kan deze leden bekijken door de -Force parameter op te nemen wanneer je het Get-Member cmdlet aanroept. Hoewel een bespreking van verborgen leden hier buiten het bestek valt, kan het nuttig zijn om op een gegeven moment de verborgen leden te verkennen die beschikbaar zijn voor de PSCustomObject klasse en andere .NET klassen om volledig gebruik te maken van uw PowerShell objecten.

Eigenschappen toevoegen aan een aangepast object

Een aangepast object is slechts zo nuttig als de leden die aan het object zijn gekoppeld. U kunt verschillende soorten leden aan een aangepast object toevoegen. In dit voorbeeld voegt u de leden NoteProperty en ScriptMethod toe. Een NoteProperty lid is vergelijkbaar met een gewone eigenschap, en een ScriptMethod lid is vergelijkbaar met een gewone methode. U kunt geen gewone eigenschap of methode toevoegen aan een aangepast object, daarom gaat u NoteProperty en ScriptMethod gebruiken. (Voor informatie over de ondersteunde leden in een aangepast object, zie het PowerShell TechNet-onderwerp “Add-Member.”)

Laten we beginnen met het toevoegen van een paar NoteProperty-leden aan het $system-object. Om de leden toe te voegen, kunt u het cmdlet Add-Member gebruiken om de namen en waarden van de eigenschap te definiëren. Stel bijvoorbeeld dat je note properties wilt toevoegen op basis van gegevens die zijn opgehaald via de Windows Management Instrumentation (WMI) mogelijkheden die in PowerShell zijn ingebouwd. (WMI biedt een infrastructuur voor het beheren van gegevens en bewerkingen in Windows OS’en). Het WMI-objectmodel omvat talrijke klassen die een breed scala van beheeroperaties ondersteunen. De Win32_OperatingSystem-klasse biedt bijvoorbeeld toegang tot informatie zoals de naam van het besturingssysteem dat op een computer is geïnstalleerd en het laatste servicepack dat op dat besturingssysteem is toegepast.

Om een WMI-object te maken, gebruikt u het cmdlet Get-WmiObject en geeft u de gewenste klasse op. Om bijvoorbeeld een Win32_OperatingSystem WMI object te maken en het toe te wijzen aan de $os variabele, zou je de code gebruiken:

$os = Get-WmiObject Win32_OperatingSystem

In dit geval haal je systeeminformatie op van de lokale computer, maar het mooie van WMI is dat het ook toegang heeft tot Windows computers op afstand en deze kan beheren.

Je kunt dan de $os variabele gebruiken om toegang te krijgen tot de informatie die door dat object wordt geretourneerd. Door een object op deze manier aan een variabele toe te wijzen, worden de gegevens op dat moment vergrendeld. Indien bijvoorbeeld een nieuw service pack wordt toegepast op het OS nadat je de $os variabele hebt aangemaakt, zal de CSDVersion eigenschap van het object de wijziging niet weergeven omdat het object was aangemaakt op basis van de oorspronkelijke gegevens.

Na het definiëren van de $os variabele, moet je twee Add-Member commando’s specificeren. Elk commando heeft vier parameters:

  • -InputObject. Je gebruikt de -InputObject parameter om het object te identificeren dat de nieuwe noot-eigenschappen ontvangt. In dit geval moet u het $system object specificeren.
  • -MemberType. De parameter -MemberType duidt het type aan van het te creëren lid, dus moet u NoteProperty.
  • -Name specificeren. U gebruikt de -Name parameter om de naam van het nieuwe lid te specificeren. In dit voorbeeld noemen we het eerste lid OperatingSystem en het tweede lid ServicePack.
  • -Value. Deze parameter specificeert de waarde van het lid. Voor de eerste note eigenschap moet u $os.Caption specificeren om de naam van het OS terug te geven. Voor de tweede note property moet u $os.CSDVersion specificeren om het laatste service pack terug te geven dat op het OS is toegepast.

Hier ziet het er uit als de twee Add-Member commando’s:

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

Merk op dat ik elk Add-Member commando in twee regels heb opgedeeld. Aan het eind van elke eerste regel heb ik een back tick (`) toegevoegd, zodat de PowerShell processor weet dat hij door moet gaan naar de volgende regel voor het volledige commando.

Nadat u de Add-Member-opdrachten hebt uitgevoerd, kunt u de $system-variabele oproepen om de inhoud ervan te bekijken:

$system

Figuur 2 toont voorbeeldresultaten.

Figuur 2: Inhoud van de $system-variabele

U kunt de $system-variabele ook gebruiken om afzonderlijke leden op te roepen. Specificeer gewoon de naam van de variabele, gevolgd door een punt, en dan de naam van het lid. De volgende opdracht geeft bijvoorbeeld de huidige waarde van de eigenschap Notitie OperatingSystem:

$system.OperatingSystem

Een voordeel van het maken van een aangepast object is dat het u in staat stelt notitie-eigenschappen te maken die zijn gebaseerd op gegevens die afkomstig zijn van verschillende bronnen, evenals een notitie-eigenschap waarvan de waarde een specifieke tekenreeks is. Kijk bijvoorbeeld eens naar de code in Listing 1, die drie nieuwe notitie-eigenschappen toevoegt aan het object $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 meeste elementen in Listing 1 zag je in het vorige voorbeeld. Merk echter op dat de code een instantie aanmaakt van de Win32_PhysicalMemory klasse, die wordt toegewezen aan de $mem variabele, en een instantie van de Win32_DiskDrive klasse, die wordt toegewezen aan de $disk variabele. Twee van de toegevoegde notitie-eigenschappen gebruiken deze nieuwe WMI-objecten als gegevensbronnen.

De eerste Add-Member opdracht haalt gegevens op uit de eigenschap $mem.Capacity, die de capaciteit van het geheugen op het doelsysteem verschaft. In dit geval is de -Value parameter echter een beetje complexer dan je zag in het vorige voorbeeld. Eerst specificeert het commando “{0:N2}” gevolgd door -f, wat een .NET constructie is voor het formatteren van het uitgevoerde getal. In principe specificeert dit dat een getal met twee decimalen moet worden teruggegeven. De opmaakinstructies worden gevolgd door een korte uitdrukking ($mem.Capacity/1GB) die de waarde Capaciteit deelt door 1GB. De waarde Capacity geeft de grootte van het geheugen in bytes. PowerShell maakt het gemakkelijk om bytes om te zetten in gigabytes door simpelweg te delen door 1GB. Tot slot tagt het commando de string ‘ GB’ (inclusief de spatie) in de uitvoer en sluit het geheel in tussen haakjes.

Het tweede Add-Member commando volgt dezelfde logica om de grootte van de harde schijf van de computer terug te geven. Het gebruikt de eigenschap $disk.Size om de grootte in bytes terug te geven, en converteert die dan naar gigabytes.

Het derde Add-Member commando voegt een eigenschap toe met de naam Owner en kent er de stringwaarde janetp aan toe. In dit geval kan “eigenaar” van alles betekenen-de primaire gebruiker, de laatste gebruiker, de beheerder, of welke betekenis je maar aan de eigenschap wilt geven. Ik heb het hier alleen opgenomen om te laten zien dat je een notitie-eigenschap kunt toevoegen waarvan de waarde een eenvoudige string is.

Nadat je de drie leden aan het aangepaste object hebt toegevoegd, kun je opnieuw de $system variabele oproepen. Het resultaat is zoals weergegeven in Afbeelding 3.

Figuur 3: Eigenschappen voor notities toegevoegd met de Add-Member Cmdlet

U hebt nu een enkel object dat gegevens bevat die zijn afgeleid van drie verschillende WMI-objecten. Het object bevat ook de eigenschap Owner, die is gebaseerd op een tekenreekswaarde. U kunt die note property oproepen zoals u elk ander lid zou oproepen:

$system.Owner

Zoals u zou verwachten, retourneert het commando de waarde janetp. Je kunt die waarde echter veranderen in een andere door een nieuwe waarde aan de eigenschap toe te wijzen, zoals dit:

$system.Owner = "rogert"

In dit geval is de waarde rogert toegewezen aan de eigenschap Owner note. Als u nu die notitie-eigenschap oproept, wordt de nieuwe waarde geretourneerd.

Zoals bij veel van de taken die u in PowerShell kunt uitvoeren, zijn er verschillende manieren om een lid aan een aangepast object toe te voegen. Met PowerShell 3.0 kunt u bijvoorbeeld een hash-tabel maken en de hash doorgeven aan de opdracht New-Object. De code in Listing 2 maakt dezelfde vijf notitie-eigenschappen, maar gebruikt een hash-tabel om de namen en waarden van de leden door te geven.

$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

Deze code maakt eerst een hash-tabel die vijf eigenschap/waarde-paren definieert, die elk overeenkomen met de notitie-eigenschappen. Zoals de code laat zien, moet je de property/value paren scheiden met puntkomma’s. Je moet ook de set van vijf property/value paren tussen accolades zetten en de accolades vooraf laten gaan door het at (@) symbool. Tenslotte moet je de hashtabel toewijzen aan de variabele $info.

Na het definiëren van de hashtabel, gebruikt de code het cmdlet New-Object om een object te maken op basis van de klasse PSObject en wijst dit toe aan de variabele $system. Alleen deze keer bevat het commando de -Property parameter, die de $info variabele als waarde neemt.

Ten slotte roept de code de $system variabele aan, die resultaten geeft zoals in Figuur 4. Merk de volgorde op waarin de eigenschappen aan het object zijn toegevoegd. Een van de problemen met het gebruik van een hashtabel om noteigenschappen toe te voegen is dat je hun volgorde niet kan controleren. Om de volgorde te bepalen, moet u het cmdlet Add-Member gebruiken om elk lid toe te voegen.

Figuur 4: Notitie-eigenschappen gemaakt met de hashtabel

Methoden toevoegen aan een aangepast object

Nu u hebt gezien hoe eenvoudig het is om eigenschappen toe te voegen, toegang te krijgen tot hun waarden en deze waarden te wijzigen, gaan we verder met methoden. Deze worden een beetje ingewikkelder omdat methodes iets moeten doen, en je moet dat iets definiëren als deel van de waarde van de methode.

De code in Listing 3 maakt bijvoorbeeld een methode die de huidige datum en tijd ophaalt en retourneert in zowel hun oorspronkelijke formaat als in gecoördineerde universele tijd (UTC) waarden.

$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

Om de code leesbaar te houden, kun je de waarde van de methode toewijzen aan een variabele (bijv. $method). Die waarde bevat de uitdrukkingen die nodig zijn om de datum en tijd informatie terug te geven. Je moet de waarde echter definiëren als een scriptblok om ze te kunnen doorgeven aan de opdracht Add-Member. Daartoe sluit je de inhoud van de waarde in tussen gekrulde haakjes. PowerShell wijst dan de waarde in zijn huidige vorm toe aan de variabele als een ScriptBlock-object.

In Listing 3 bevat de waarde van de methode twee expressies. De eerste expressie geeft de huidige datum en tijd, en de tweede expressie geeft de UTC-versie. Je begint de eerste expressie door het cmdlet Get-Date te gebruiken om de huidige datum en tijd op te halen, die je toewijst aan de variabele $a. Merk op dat wanneer je het cmdlet Get-Date aanroept, je de parameter -Format moet toevoegen, samen met de waarde F. Dit vertelt PowerShell om de tijdstempel weer te geven in een volledige datum- en tijdnotatie, zoals in Monday, August 19, 2013 12:28:25 PM. Vervolgens voegt u de tekenreeks “Local: ” (inclusief de spatie) aan de variabele waarde om de huidige datum en tijd samen met dat label te retourneren.

In de tweede expressie begin je opnieuw met het Get-Date cmdlet om de huidige datum en tijd te retourneren, die je toewijst aan de $b variabele. Vervolgens gebruik je de methode ToUniversalTime van de variabele om de datum en tijd als een UTC-waarde terug te geven, waarna je de eigenschap DateTime specificeert om het juiste formaat terug te geven.

Als je op dit punt de variabele $method zou oproepen, zou deze de twee expressies als tekenreeksen teruggeven, precies zoals ze waren getypt. Omdat je de variabele waarde als een scriptblok gedefinieerd hebt, worden de commando’s niet verwerkt wanneer ze aan de $method variabele worden toegewezen. In plaats daarvan wordt de variabele $method aangemaakt als een ScriptBlock object, wat je kunt bevestigen door de methode GetType te gebruiken om het type van de variabele te zien:

$method.GetType()

Om met het scriptblok te werken, moet je de methode toevoegen als een lid van het object $system nadat je de variabele $method hebt gedefinieerd. Hiertoe maak je een Add-Member commando dat ScriptMethod specificeert als het type, GetUTC als de naam, en de $method variabele als de waarde.

Nadat je de code in Listing 3 hebt uitgevoerd, kun je de variabele $system gebruiken om de methode GetUTC aan te roepen op vrijwel dezelfde manier als je de eigenschappen hebt aangeroepen:

$system.GetUTC()

Merk echter op dat wanneer je de scriptmethode aanroept, je de haakjes moet invoegen, net zoals je dat voor elke andere methode doet, zelfs als je geen argumenten doorgeeft. De methode zou nu resultaten moeten opleveren die vergelijkbaar zijn met die in Figuur 5, maar dan met de datum en tijd waarop u de methode hebt aangeroepen.

Figuur 5: Voorbeeldresultaten van de methode GetUTC()

In het echte leven zult u waarschijnlijk methoden willen maken die meer kracht bevatten. Het $system-object zou bijvoorbeeld WMI-beheertaken kunnen opnemen in zijn scriptmethoden. Als je dat doet, moet je de methode volledig testen om er zeker van te zijn dat je commando’s precies doen wat ze moeten doen. PowerShell en WMI zijn krachtige hulpmiddelen, dus ze moeten met zorg worden gebruikt bij het beheren van Windows-computers.

Aangepaste objecten toevoegen aan een array

Aangepaste objecten zijn niet beperkt tot op zichzelf staande objecten die u een keer gebruikt en vervolgens weggooit. Je kunt deze objecten toevoegen aan een object array, en dan de objecten benaderen via die array. Bijvoorbeeld, stel dat je informatie wilt manipuleren die je van meerdere computers hebt opgehaald. Die informatie kan details bevatten over het beschikbare geheugen en logische schijven op die systemen. U wilt op een zinvolle manier met deze gegevens kunnen werken in PowerShell. Vanwege de objectgeoriënteerde aard van PowerShell is het onderbrengen van die informatie in objecten vaak de eenvoudigste manier om met die gegevens te werken.

Laten we eens kijken naar een voorbeeld van hoe u dit zou kunnen doen. Voor deze discussie is de aanpak die wordt gebruikt om de informatie over de verschillende computers te verzamelen, onbelangrijk. U zou bijvoorbeeld een foreach-lus in PowerShell kunnen opzetten die WMI gebruikt om de informatie van de verschillende werkstations op te halen. Welke methode u ook gebruikt, ga er kortheidshalve van uit dat u de informatie hebt verzameld in een door komma’s gescheiden tekstbestand dat de gegevens bevat die worden weergegeven in afbeelding 6.

Figuur 6: Verzamelde WMI-gegevens

Het tekstbestand bevat een header-rij en een rij voor de logische stations van elk systeem. De eerste rij gegevens bevat bijvoorbeeld details over de logische schijf C op computer ws01. De logische schijf heeft een capaciteit van 500 GB, met 225 GB vrije ruimte. Het systeem heeft ook 4 GB geheugen. De tweede rij geeft aan dat dezelfde computer ook de logische schijf D bevat, die dezelfde capaciteit heeft als de C-schijf, maar met 320 GB vrije ruimte.

Het doel is om van elke rij gegevens een eigen aangepast object te maken, en die objecten vervolgens toe te voegen aan een array. U kunt dan actie ondernemen op de objecten in de array door de gegevens door te sluizen naar andere PowerShell-opdrachten. De code in Listing 4 definieert een lege array, importeert de gegevens uit het tekstbestand en gebruikt vervolgens een foreach-lus om de objecten te maken en aan de array toe te voegen.

$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}

Zoals je kunt zien, is de eerste stap het maken van de lege array (@()) en deze toewijzen aan de $SystemInfo-variabele. Uiteindelijk zul je de aangepaste objecten aan deze array toevoegen.

Daarna gebruik je het cmdlet Import-CSV om de gegevens te importeren in de variabele $SourceData. Voor deze oefening wordt het tekstbestand SourceData.txt genoemd en opgeslagen in de map C:\DataFiles. Het cmdlet Import-CSV haalt elke rij op als zijn eigen object en slaat het op in $SourceData. Op dit punt zou je die variabele kunnen gebruiken om toegang te krijgen tot de data, maar je zou geen controle hebben over de leden in het object, noch zou je in staat zijn om leden toe te voegen.

De volgende stap is dan om een foreach loop te maken waarmee je een aangepast object kunt maken voor elke rij in het tekstbestand. De foreach-conditie ($source in $SourceData) specificeert dat elke rij in $SourceData moet worden toegewezen aan de variabele $source terwijl de code door de foreach-lus heenloopt. De logica die in het foreach-scriptblok is gedefinieerd (tussen accolades), wordt dan voor elke rij één keer uitgevoerd, waarbij tijdens elke iteratie een ander $source-object wordt toegepast. (Voor meer informatie over het maken van een foreach-lus, zie het PowerShell TechNet-onderwerp about_ForEach.)

Laten we het foreach-scriptblok eens van dichterbij bekijken. Het eerste commando maakt het initiële object en slaat het op in de $system variabele, zoals je in eerdere voorbeelden hebt gezien. Vervolgens wordt de $system variabele doorgestuurd naar een Add-Member commando om de eerste note property te maken. Dit is een lichtjes verschillend formaat dan eerder gebruikt. In plaats van de -InputObject parameter in het Add-Member commando op te nemen, wordt gewoon $system naar het commando gepijpt. Dit bereikt dezelfde resultaten die je zag in de eerdere voorbeelden van Add-Member commando’s. Ik heb deze aanpak hier alleen gekozen om nog een manier te demonstreren waarop je met PowerShell leden kunt toevoegen.

Voor de waarde van de Add-Member-opdracht gebruik je de variabele $source om de eigenschap Computer op te roepen, die overeenkomt met het veld Computer in de brongegevens. De tweede Add-Member opdracht werkt op dezelfde manier, behalve dat hij gegevens ophaalt van de eigenschap DeviceID. Merk op dat de eigenschap Memory niet is opgenomen. Wanneer u een aangepast object maakt, kunt u specifieke eigenschappen weglaten of ze in een andere volgorde zetten.

De derde Add-Member opdracht werkt op vrijwel dezelfde manier als de eerste twee, behalve dat deze toegang heeft tot de eigenschap DriveSize. Omdat u misschien met deze gegevens wilt werken als een numerieke waarde in plaats van een tekenreeks, converteert het commando de gegevens expliciet naar een getal. Dit wordt bereikt door de naam van de eigenschap vooraf te laten gaan door om aan te geven dat u het gegevenstypeint wilt, en vervolgens de hele eigenschapsexpressie tussen haakjes te plaatsen. Het creëert een berekend element dat de FreeSpace-waarde aftrekt van de DriveSize-waarde om de hoeveelheid gebruikte ruimte te bepalen. Ook hier wordt de naam van de eigenschap voorafgegaan door en de hele uitdrukking wordt tussen haakjes gezet. De mogelijkheid om een berekende eigenschap te maken is een van de belangrijkste redenen waarom je misschien aangepaste objecten zou willen maken.

De laatste Add-Member opdracht werkt net als de derde, behalve dat het gegevens ophaalt van de FreeSpace eigenschap.

De laatste opdracht in het foreach scriptblok voegt het huidige $system object toe aan de $SystemInfo array. Merk op dat de += operator wordt gebruikt om ervoor te zorgen dat het nieuwe $system object bij elke iteratie van de lus wordt toegevoegd, zonder dat er iets wordt overschreven.

Nadat je de code in Listing 4 hebt uitgevoerd, kun je de variabele aanroepen om de inhoud te bekijken. Figuur 7 toont een gedeeltelijke lijst van de gegevens die nu zijn opgeslagen in de $SystemInfo-array.

Figuur 7: Gegevens opgeslagen in de $SystemInfo-array

In het bijzonder toont het de gegevens voor de eerste zeven objecten in de array, wat overeenkomt met de eerste zeven rijen gegevens in het oorspronkelijke tekstbestand. Elke groepering vertegenwoordigt een van de objecten die aan de $SystemInfo array zijn toegevoegd. U kunt controleren of u een object-array hebt gemaakt door de methode GetType te gebruiken om het type van de variabele op te halen:

$SystemInfo.GetType()

Als deze opdracht een BaseType van System.Array teruggeeft, is de variabele $SystemInfo inderdaad een object-array die aangepaste objecten kan bevatten. Je kan die variabele dan gebruiken om de gegevens te manipuleren zoals je goeddunkt. U kunt de variabele bijvoorbeeld naar een Sort-Object opdracht leiden om de gegevens in aflopende volgorde te sorteren, gebaseerd op de FreeSpace waarden:

$SystemInfo | Sort FreeSpace -Descending

In dit geval gebruikt de opdracht de Sort alias om te verwijzen naar het Sort-Object cmdlet en bevat de FreeSpace eigenschap en de -Descending parameter. Zoals u kunt zien in Figuur 8, worden de objecten nu gerangschikt op basis van de FreeSpace waarden, met de grootste hoeveelheid vrije ruimte bovenaan. Nogmaals, dit is slechts een gedeeltelijke lijst.

Figuur 8: Gegevens gesorteerd op de hoeveelheid vrije ruimte

U kunt de gegevens ook sorteren op basis van meerdere kolommen. U kunt de gegevens bijvoorbeeld eerst sorteren op de eigenschap Computer en dan op de eigenschap Vrije ruimte, in aflopende volgorde:

$SystemInfo | Sort Computer, FreeSpace -Descending

Zoals u zou verwachten, zijn de resultaten nu heel anders, zoals figuur 9 laat zien.

Figuur 9: Gegevens gesorteerd op Computernaam en Vrije Ruimte in aflopende volgorde

Eén van de gevolgen van het sorteren van de kolommen op deze manier is dat zowel de Computerwaarden als de Vrije Ruimte-waarden in aflopende volgorde worden gesorteerd. Met het Sort-Object cmdlet kunt u niet eenvoudig de ene kolom in oplopende volgorde sorteren en de andere in aflopende volgorde. Indien je de parameter -Descending specificeert, worden alle gegevens in die volgorde gesorteerd. U kunt deze beperking echter omzeilen door expressies te maken voor elke eigenschap die aangeven hoe die waarden moeten worden gesorteerd. De volgende opdracht sorteert bijvoorbeeld eerst op de eigenschap Computer in oplopende volgorde, en vervolgens op de eigenschap FreeSpace in aflopende volgorde:

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

De eerste uitdrukking Sort-Object stelt de eigenschap Expression in op Computer en de eigenschap Descending op $false. De tweede uitdrukking stelt de eigenschap Expression in op FreeSpace en de eigenschap Descending op $true. (De variabelen $true en $false zijn ingebouwde systeemvariabelen die de Booleaanse waarden true en false geven, respectievelijk 1 en 0). Vervolgens moet je elke uitdrukking tussen accolades plaatsen en elke accolade vooraf laten gaan door het symbool at (@). Nu worden de gegevens in de gewenste volgorde gesorteerd, zoals getoond in Figuur 10.

Figuur 10: Gegevens gesorteerd op de computernaam in oplopende volgorde en de hoeveelheid vrije ruimte in aflopende volgorde

Dit lijkt misschien overdreven op het gebied van sorteren, maar het geeft wel aan hoe flexibel het is om met objecten in een matrix te werken. En je bent zeker niet beperkt tot het Sort-Object cmdlet. De volgende opdracht bijvoorbeeld stuurt de variabele $SystemInfo naar het cmdlet Where-Object:

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

In dit geval gebruikt de opdracht het alias Where om te verwijzen naar het cmdlet Where-Object. Bovendien wordt gespecificeerd dat de DriveSize-waarde groter moet zijn dan 250 om in de resultaten te worden opgenomen. (In PowerShell wordt -gt gebruikt voor de operator groter dan.) De resultaten die aan deze criteria voldoen, worden doorgestuurd naar het Sort-Object cmdlet, zodat de gegevens in de juiste volgorde worden weergegeven.

U kunt de gesorteerde gegevens zelfs doorleiden naar een Select-Object commando, zoals dit:

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

Dit commando gebruikt het Select-Object cmdlet (waarnaar wordt verwezen met de Select alias) om alleen de eerste vijf rijen van de resultatenset te retourneren. Zoals u ziet, hebt u, wanneer u eenmaal aangepaste objecten aan de $SystemInfo-array hebt toegevoegd, een groot aantal opties om met die objecten te werken.

Haal het meeste uit uw aangepaste objecten

Het maken van aangepaste objecten in PowerShell is voor het grootste deel een vrij eenvoudig proces. Als het al ingewikkeld is, komt dat meestal door de waarde-expressies die u definieert voor uw noteigenschappen of scriptmethoden. De expressies in deze voorbeelden zijn relatief eenvoudig in vergelijking met de soorten expressies die u in PowerShell kunt maken. Toch zou wat u hier hebt gezien u de basis moeten verschaffen die u nodig hebt voor het maken van aangepaste objecten. Wanneer ze effectief worden gebruikt, kunnen ze een krachtig onderdeel vormen van uw PowerShell-scripts, of u nu afzonderlijke objecten maakt, ze toevoegt aan een array of ze op een andere manier gebruikt. U kunt bijvoorbeeld aangepaste objecten maken in uw PowerShell-profiel, zodat ze beschikbaar zijn telkens wanneer u een nieuwe sessie start. Hoe u aangepaste objecten in uw scripts gebruikt, mag u zelf bepalen. Weet alleen dat het aangepaste object een effectief, flexibel hulpmiddel is dat aan veel van uw scriptbehoeften kan voldoen.

Voor aanvullende informatie over het maken van aangepaste objecten in Windows PowerShell, zie Bill Stewart’s “Creating Custom Objects in Windows PowerShell.”

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.