PowerShell Functies

Dit item is deel 12 van 13 in de serie Learn PowerShell

In deze aflevering van de Learn PowerShell serie gaan we in op PowerShell functies. In de vorige aflevering hebben we PowerShell scripts behandeld waar we begonnen met het maken van oplossingen en het oplossen van problemen met behulp van PowerShell. PowerShell scripts zijn geweldig en veel mensen besteden veel tijd in deze fase van het leren van PowerShell. Scripts laten je toe om dingen vrij eenvoudig te houden, en kunnen je helpen om snel taken te automatiseren. Naarmate je beter wordt en meer PowerShell begint te schrijven, zul je PowerShell-functies moeten gaan maken!

Video

Als u de voorkeur geeft aan video boven geschreven documentatie, bespreek ik dit onderwerp in de volgende TechThoughts-video:

Wanneer u een PowerShell-functie moet schrijven

Eindelijk is een PowerShell-script een set code waarmee een taak wordt uitgevoerd. Dat is wat een PowerShell-functie ook doet! Dus, waarom zou je ervoor kiezen om een functie te schrijven in plaats van een script? We zullen hieronder in een paar redenen duiken. Over het algemeen is een script echter iets voor jou. Wanneer u uw code wilt delen of uw teamgenoten ermee wilt laten werken, wilt u gebruik gaan maken van de mogelijkheden die functies bieden. Er is geen vaste lijn. Voor een snelle taak die maar één keer op je werkstation wordt uitgevoerd, kan een script zinvol zijn. Als je PowerShell schrijft die anderen kunnen gebruiken, of die je meer dan eens kunt gebruiken, is een functie waarschijnlijk beter.

  • Eenmalig – een functie wordt meestal gebruikt om een beperkte taak uit te voeren en “één ding te doen, en het goed te doen”. Dit maakt functies zeer herbruikbaar. Als je bijvoorbeeld een logboekfunctie schrijft, kun je die PowerShell-logboekfunctie met andere functies of scripts gebruiken.
  • Help – functies ondersteunen commentaar op basis van hulp. Hierdoor kunnen uw gebruikers dingen doen zoals Get-Help typen en uitzoeken hoe uw functie te gebruiken.
  • Parameters – ondersteuning voor eenvoudige en geavanceerde parameters declaraties en controle maakt het mogelijk uw functie dynamisch te laten zijn en verschillende vormen van gebruikersinvoer te nemen.
  • Testable – functies kunnen worden getest en mocked, wat de kwaliteit van de code sterk verbetert.

Anatomie van een PowerShell-functie

Hier volgt de basisindeling en volgorde van een PowerShell-functie. We zullen hieronder in elk van deze secties duiken en ze in detail onderzoeken.

# function help - (optional but strongly encouraged)# function name# CmdletBinding - (optional)# parameters - (optional)# function logic (optional Begin / Process / End)# return - (optional)function Verb-Noun { param ( ) begin { } process { } end { }}

Functie Help

Wanneer u boven aan uw functie help toevoegt, wordt deze weergegeven wanneer Get-Help wordt uitgevoerd tegen uw functie. Dit is een krachtige mogelijkheid wanneer anderen je code aan het onderzoeken zijn. Als je de tijd neemt om een goede Synopsis en Description te maken, gecombineerd met goede voorbeelden, zullen anderen begrijpen waar je functie voor is, en hoe je hem moet gebruiken.

Alle help-velden zijn optioneel en je kunt ze naar eigen inzicht toevoegen of verwijderen. Ik raad je aan ten minste de onderstaande velden op te nemen.

<#.SYNOPSIS Short description.DESCRIPTION Long description.EXAMPLE C:\PS> Example of how to use this cmdlet.EXAMPLE C:\PS> Another example of how to use this cmdlet.PARAMETER InputObject Specifies the object to be processed. You can also pipe the objects to this command..OUTPUTS Output from this cmdlet (if any).NOTES General notes.COMPONENT The component this cmdlet belongs to#>

CmdletBinding


Wanneer je een geweldige functie schrijft en deze een naam geeft als Get-AllFileInformation, ziet deze eruit als een cmdlet en zal deze zich ook zo gedragen. Maar het is een belangrijk onderscheid dat een PowerShell-functie geen cmdlet is. Cmdlet’s zijn geschreven en gecompileerd in C# en je PowerShell functie is geschreven in PowerShell.

CmdletBinding is een attribuut van functies dat mogelijkheden biedt om ze meer te laten werken als gecompileerde cmdlets. Door dit aan de top van je functie toe te voegen, krijg je veel extra mogelijkheden, zoals:

  • Write-Verbose – laat gebruikers de -Verbose switch gebruiken om te zien wat je functie doet terwijl hij bezig is.
  • ShouldProcess – als je functie een wijziging aanbrengt in een systeem dat een hoog risico inhoudt, wil je misschien dat de gebruiker de actie bevestigt.
  • PositionalBinding – maakt het mogelijk uw functie uit te voeren zonder expliciet elke parameternaam op te geven. De waarden kunnen worden afgeleid uit de volgorde waarin ze aan uw functie worden verstrekt

parameters

param ( $City, $Units = 'USCS', $Language = 'en', $Short)

Parameters dienen om de gebruiker een manier te bieden voor dynamische interactie met uw functie. Je kunt verschillende vormen van invoer gebruiken en een breed scala aan controles en validaties uitvoeren om er zeker van te zijn dat je de juiste informatie krijgt.

Je kunt heel eenvoudig blijven en alleen de namen van je parameters opgeven. Maar je kunt ook heel specifiek aangeven wat er voor je parameters nodig is:

  • Of de parameter verplicht is
  • De positie van een parameter (de volgorde)
  • Het parametertype (string/int/bool/etc)
  • Het instellen van standaardwaarden
  • Invoervalidatie
  • Parametersets
  • Veel meer

Deze post kan niet elke mogelijke parameterconfiguratie behandelen. Zelfs na jaren PowerShell te hebben geschreven vind ik het moeilijk om alle parameterinstellingen en syntaxis te onthouden. Weet dat parameter declaraties je manier zijn om input in je functie te krijgen. Je kunt ze voorzien van veel details en controles, of ze gewoon eenvoudig houden, afhankelijk van je behoeften. Maak een bladwijzer van de parameter links onderaan deze post. Zelfs nu nog bezoek ik ze vaak!

Begin Process End

Deze drie sleutelwoorden zijn fasen die je in je functie kunt aangeven.

  • Begin initialiseert een aantal stappen aan het begin
  • Process verwerkt elk object zoals het wordt ontvangen
  • End kan opruimen uitvoeren.

Dit is vooral nuttig als je wilt dat je functie de verwerking van invoer uit de pijplijn ondersteunt.

Dit kan in theorie moeilijk te begrijpen zijn, dus hier is een voorbeeld dat het gebruik ervan demonstreert.

function Get-PipelineBeginEnd { param ( $SomeInput ) begin { "Begin: The input is $SomeInput" } process { "The value is: $_" } end { "End: The input is $SomeInput" }}#Get-PipelineBeginEnd1, 2, 3 | Get-PipelineBeginEnd -SomeInput 'Test'

Wanneer je de bovenstaande code uitvoert, zie je dat Begin één keer wordt uitgevoerd, net als End. Process wordt uitgevoerd voor elk item dat wordt doorgegeven en Process heeft toegang tot het huidige object in de pijplijn.

Functielogica

De logica in een PowerShell-functie is niet anders dan die van een script. Dit is waar je de kernlogica schrijft die de taak uitvoert waarvoor je functie is bedoeld. Dit werd behandeld in afleveringen 1-10 van deze cursus. U kunt ook een volledig live voorbeeld zien in de PowerShell Scripts aflevering.

Functie retourneren

Niet alle functies retourneren iets wanneer ze worden uitgevoerd. Als je functie iets teruggeeft, kun je optioneel return gebruiken. Houd er rekening mee dat bij het gebruik van return alle verdere acties in de functie worden gestopt en de functie wordt beëindigd.

function Get-Total { param ( $Number1, $Number2 ) $total = $Number1 + $Number2 return $total}Get-Total -Number1 2 -Number2 2

In het bovenstaande voorbeeld bevat deze eenvoudige functie twee parameters van het type integer. De logica van de functie telt de twee getallen bij elkaar op en geeft het gehele getal aan de gebruiker terug.

Je eerste PowerShell-functie

Kijk eens naar de PowerShell-functie hieronder. Merk op dat de lay-out overeenkomt met wat we eerder hebben behandeld. Merk ook op dat de helpsectie veel details geeft over het doel en het gebruik van de functie.

<#.SYNOPSIS Returns your public IP address..DESCRIPTION Queries the ipify Public IP Address API and returns your public IP..EXAMPLE Get-PublicIP Returns the public IP..OUTPUTS System.String.NOTES https://github.com/rdegges/ipify-api#>function Get-PublicIP { $uri = 'https://api.ipify.org' try { $invokeRestMethodSplat = @{ Uri = $uri ErrorAction = 'Stop' } $publicIP = Invoke-RestMethod @invokeRestMethodSplat } catch { Write-Error $_ } return $publicIP}#Get-PublicIP

Aangezien de eigenlijke logica van deze functie vrij eenvoudig is, is het wellicht verleidelijk om deze functie als script te laten staan. Merk echter op dat dit een specifiek ding doet, en het doet het goed. Je zou deze functie nu kunnen integreren in andere geavanceerde logica, in plaats van te moeten verwijzen naar een script of het te importeren. Andere gebruikers in je omgeving kunnen deze functie ook gaan gebruiken als ze er eenmaal vertrouwd mee zijn.

Functie Scope

Net als de meeste talen heeft PowerShell scoping regels voor variabelen. Wanneer een variabele zich in een functie bevindt, kun je de waarde ervan niet meer “zien”. Hier is een voorbeeld van dit gedrag:

function Get-NumberTimesTwo { param ( $Number ) $total = $Number * 2 return $total}#Get-NumberTimesTwoGet-NumberTimesTwo -Number 2

De functie gedraagt zich zoals verwacht en zal een getal correct met twee vermenigvuldigen. Probeer echter in je console te zien wat de waarde van $totaal is. Dat zal niet lukken. Dit komt omdat $total is gescoped naar de functie, en niet je actieve console sessie.

Dit kan verwarrend zijn voor mensen die nieuw zijn met PowerShell en kan het schrijven van functies moeilijker maken. Er zijn een paar strategieën om hiermee om te gaan.

Je zou het grootste deel van je logica in een script-formaat kunnen schrijven, waarbij je de variabelen test terwijl je bezig bent. Als je er zeker van bent dat de logica werkt zoals bedoeld, kun je de logica in een functie wikkelen.

Aternatief kun je gebruik maken van Write-Host, Write-Output, of nog beter Write-Debug om te zien wat er met je variabelen in je functie gebeurt!

function Get-NumberTimesTwo { param ( $Number ) $total = $Number * 2 Write-Debug $total return $total}#Get-NumberTimesTwoGet-NumberTimesTwo -Number 2 -Debug

Met de debug-schakelaar krijgen we toegang tot de waarde in $total om er zeker van te zijn dat onze logica doet wat we bedoelen.

Afsluitend voorbeeld

Hier volgt een groter afsluitend voorbeeld van twee PowerShell-functies waarmee je met PowerShell op de populaire website reddit kunt surfen!

Bezoek de GitHub gist-link hieronder om toegang tot de code te krijgen en deze in je console te laden.

https://gist.github.com/techthoughts2/cd2b720c9b291510cbd643e6ca73e05f

Probeer tijdens het verkennen van deze functies de volgende vragen te beantwoorden:

  • Van de twee functies, welke is de primaire functie?
  • Zijn dit standaard- of geavanceerde functies?
  • Welke functie gaat pijplijninvoer ondersteunen?

Additional Reading

  • Functions
  • Parameters
  • Functions Advanced
  • Functions Advanced Parameters
  • PowerShell Approved Verbs
  • CmdletBindingAttribute

Series Navigation << PowerShell ScriptsManage Cloud with PowerShell >>