PowerShell-funktioner

Detta inlägg är del 12 av 13 i serien Lär dig PowerShell

I det här avsnittet av serien Lär dig PowerShell undersöker vi PowerShell-funktioner. I förra avsnittet behandlade vi PowerShell-skript där vi började skapa lösningar och lösa problem med hjälp av PowerShell. PowerShell-skript är bra och många spenderar ganska mycket tid i detta skede när de lär sig PowerShell. Med hjälp av skript kan du hålla saker och ting ganska enkla och kan hjälpa dig att snabbt automatisera uppgifter. När du blir bättre och börjar skriva mer PowerShell kommer du att behöva se till att skapa PowerShell-funktioner!

Video

Om du föredrar videoformat framför skriftlig dokumentation diskuterar jag det här ämnet i följande TechThoughts-video:

När du ska skriva en PowerShell-funktion

I slutändan är ett PowerShell-script en uppsättning kod som utför en uppgift. Det är också vad en PowerShell-funktion gör! Så varför skulle du välja att skriva en funktion jämfört med ett skript? Vi kommer att dyka ner i några anledningar nedan. Generellt sett är dock ett skript något för dig. När du vill börja dela din kod, eller låta dina lagkamrater använda den, vill du börja använda några av de möjligheter som funktioner erbjuder. Det finns ingen bestämd gräns. För en snabb uppgift som kommer att köras en gång på din arbetsstation kan ett skript vara vettigt. Om du skriver något PowerShell som andra kan komma att använda, eller som du kan komma att använda mer än en gång, är en funktion troligen bättre.

  • Enkla syften – en funktion används vanligtvis för att utföra en smal uppgift och ”göra en sak, och göra det bra”. Detta gör att funktioner i hög grad kan återanvändas. Om du till exempel skriver en loggningsfunktion kan du sedan använda den loggningsfunktionen i PowerShell med andra funktioner eller skript.
  • Hjälp – funktioner stöder hjälpbaserade kommentarer. Detta gör att dina användare kan göra saker som att skriva Get-Help och räkna ut hur de ska använda din funktion.
  • Parametrar – stöd för enkla och avancerade parameterdeklarationer och kontroll gör att din funktion kan vara dynamisk och ta emot olika former av användarinmatning.
  • Testable – funktioner kan testas och mockas, vilket avsevärt förbättrar kvaliteten på koden.

Anatomi av en PowerShell-funktion

Här är den grundläggande layouten och ordningen av en PowerShell-funktion. Vi kommer att dyka ner i var och en av dessa sektioner nedan och utforska dem i detalj.

# 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 { }}

Funktionshjälp

När du inkluderar hjälp i början av din funktion kommer den att visas när Get-Help körs mot din funktion. Detta är en kraftfull funktion när andra utforskar din kod. Om du tar dig tid att skriva en bra synopsis och beskrivning i kombination med solida exempel hjälper du andra att förstå vad din funktion är till för och hur den ska användas.

Alla hjälpfält är valfria och du kan lägga till eller ta bort dem efter eget tycke och smak. Jag rekommenderar att du inkluderar åtminstone fälten nedan som ett minimum.

<#.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


När du skriver en bra funktion och ger den ett namn som Get-AllFileInformation, ser den ut som och kommer att agera som en cmdlet. Men det är en viktig skillnad att en PowerShell-funktion inte är en cmdlet. Cmdlets skrivs och kompileras i C# och din PowerShell-funktion skrivs i PowerShell.

CmdletBinding är ett attribut för funktioner som aktiverar funktioner som gör att de fungerar mer som kompilerade cmdlets. Om du lägger till detta i början av din funktion får din funktion många ytterligare möjligheter, till exempel:

  • Write-Verbose – låt användarna använda växeln -Verbose för att se vad din funktion gör medan den gör det.
  • ShouldProcess – om din funktion kommer att göra en ändring i ett system som innebär en hög risk, kanske du vill att användaren ska bekräfta åtgärden.
  • PositionalBinding – gör det möjligt att köra din funktion utan att explicit ange varje parameternamn. Värdena kan härledas genom den ordning i vilken de tillhandahålls din funktion

parametrar

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

Parametrar tjänar till att ge användaren ett sätt att dynamiskt interagera med din funktion. Du kan ta emot olika former av inmatning och utföra en mängd olika kontroller och valideringar för att se till att du får rätt sorts information.

Du kan hålla dig mycket grundläggande och bara deklarera namnen på dina parametrar. Alternativt kan du bli mycket specifik när det gäller vad som krävs för dina parametrar:

  • Om parametern är obligatorisk
  • Positionen för en parameter (ordningen)
  • Parametertypen (string/int/bool/etc)
  • Sätt standardvärden
  • Inputvalidering
  • Parameteruppsättningar
  • Mycket mer

Det här inlägget kan inte täcka alla tänkbara parameterkonfigurationer. Även efter att ha skrivit PowerShell i flera år tycker jag att det är svårt att memorera alla parameterinställningar och syntax. Vet att parameterdeklarationer är ditt sätt att ta emot input till din funktion. Du kan ge dem många detaljer och kontroller eller bara hålla dem enkla beroende på dina behov. Lägg parameterlänkarna längst ner i det här inlägget som bokmärken. Än idag besöker jag dem ofta!

Begin Process End

Dessa tre nyckelord är faser som du kan deklarera inom din funktion.

  • Begin initialiserar vissa steg i början
  • Process bearbetar varje objekt som tas emot
  • End kan utföra rensning.

Detta är särskilt användbart om du vill att din funktion ska stödja behandling av indata från pipeline.

Detta kan vara svårt att förstå i teorin så här är ett exempel som visar hur det används.

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'

När du kör koden ovan noterar du att Begin körs en gång, liksom End. Process körs för varje objekt som skickas in i den och Process har tillgång till det aktuella objektet i pipeline.

Funktionslogik

Logiken i en PowerShell-funktion skiljer sig inte från logiken i ett skript. Det är här du skriver kärnlogiken som utför den uppgift som din funktion är avsedd för. Detta behandlades i avsnitt 1-10 av den här kursen. Du kan också se ett fullständigt liveexempel i avsnittet PowerShell Scripts.

Funktionens retur

Inte alla funktioner returnerar något när de körs. Om din funktion kommer att returnera något kan du valfritt använda return. Tänk på att när du använder return kommer alla ytterligare åtgärder i funktionen att stoppas och funktionen avslutas.

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

I exemplet ovan innehåller den här enkla funktionen två parametrar av typen heltal. Logiken i funktionen lägger ihop de två talen och returnerar heltalet till användaren.

Din första PowerShell-funktion

Ta en titt på PowerShell-funktionen nedan. Observera att layouten följer det som vi tidigare har behandlat. Notera också att hjälpavsnittet ger en stor mängd detaljer om funktionens syfte och användning.

<#.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

Då själva logiken i den här funktionen är ganska enkel kan det vara frestande att lämna den som ett skript. Observera dock att detta gör en specifik sak, och gör det bra. Du kan nu införliva den här funktionen i annan avancerad logik, i stället för att behöva referera till eller importera ett skript. Andra användare i din miljö kan också börja använda den här funktionen när de blir bekanta med den.

Funktionsomfång

Som de flesta språk har PowerShell scopingregler för variabler. När en variabel befinner sig inom en funktion kan du inte längre ”se” dess värde. Här är ett exempel på detta beteende:

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

Funktionen beter sig som förväntat och multiplicerar korrekt ett tal med två. I konsolen kan du dock försöka se vad värdet på $total är. Det kommer du inte att kunna göra. Detta beror på att $total är scoped till funktionen och inte till din aktiva konsolsession.

Detta kan vara förvirrande för personer som är nya i PowerShell och kan göra det svårare att skriva funktioner. Det finns ett par strategier för att hantera detta.

Du kan skriva majoriteten av din logik i ett format av skripttyp och testa variabler under tiden. När du är säker på att logiken fungerar som avsett kan du sedan linda in logiken i en funktion.

Alternativt kan du använda Write-Host, Write-Output eller ännu hellre Write-Debug för att se vad som händer med variablerna i funktionen!

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

Notera att vi med debug-switchen får tillgång till värdet inne i $total för att se till att vår logik gör det som vi avser.

Avslutande exempel

Här är ett större avslutande exempel med två PowerShell-funktioner som gör att du kan surfa på den populära webbplatsen reddit med hjälp av PowerShell!

Besök GitHub gist-länken nedan för att få tillgång till koden och ladda den i din konsol.

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

När du utforskar dessa funktioner försök att besvara följande frågor:

  • Om de två funktionerna, vilken är den primära funktionen?
  • Är det här standard- eller avancerade funktioner?
  • Vilken av funktionerna kommer att ha stöd för pipeline input?

Additional Reading

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

Series Navigation << PowerShell ScriptsManage Cloud with PowerShell >>