Beheers de PowerShell WhatIf-parameter

“Ik test niet altijd mijn scripts, maar als ik het doe, doe ik het in productie”

Lieg niet. Je hebt het al eerder gedaan. We hebben het allemaal op een gegeven moment gedaan. Het hoeft echter niet riskant te zijn wanneer je PowerShell-scripts in productie uitvoert. Onthoud gewoon om de ingebouwde PowerShell WhatIf-parameter te gebruiken!

Zou het niet fijn zijn om te weten wat die PowerShell-opdracht zou doen voordat hij wijzigingen aanbrengt in je omgeving? Stel je voor dat je aan je opdracht zou kunnen vragen: “Wat zou je doen als je zou worden uitgevoerd?” Je kunt de WhatIf-parameter gebruiken.

Alle gecompileerde PowerShell-cmdlets bevatten een parameter genaamd WhatIf. Deze parameter helpt je te evalueren of een opdracht zal werken zoals je verwacht of dat het een nucleaire meltdown zal starten.

De handige WhatIf-parameter is niet alleen beschikbaar bij alle ingebouwde cmdlets, maar ook bij je scripts en geavanceerde functies! Als je code dingen in je omgeving zal veranderen, heb je het voordeel van een fail-safe mechanisme als je ervoor kiest om het te implementeren.

Vereisten

Dit artikel gaat een stapsgewijze handleiding zijn. Als je wilt meedoen tijdens deze reis, moet je een paar dingen op hun plaats hebben.

Merk op dat ik in dit artikel Visual Studio Code 1.38 (augustus 2019) zal gebruiken op een Windows 10-machine.

De WhatIf PowerShell-parameter: Gedefinieerd

In een notendop is de WhatIf-parameter een ingebouwde schakelparameter die beschikbaar is bij alle geavanceerde functies en cmdlets (door het toevoegen van het PowerShell-woord CmdletBinding aan scripts en functies). Wanneer gebruikt, geeft de opdracht het verwachte effect van de opdracht weer op de console, maar voert de opdracht feitelijk niet uit.

Alle cmdlets en geavanceerde functies hebben de WhatIf-parameter beschikbaar. In dit artikel zullen we deze parameter demonstreren met behulp van de Get-Service, Stop-Service en New-Item cmdlets.

Controleren op ondersteuning voor Powershell WhatIf

Als je niet zeker weet of een bepaalde opdracht WhatIf ondersteunt, zijn er twee snelle manieren om dit te controleren.

Met Get-Command

Je kunt de opdracht Get-Command gebruiken om opdrachtmetadata te bekijken door de Syntax-parameter te gebruiken zoals hieronder getoond. Als je een verwijzing naar -WhatIf ziet, wordt WhatIf ondersteund.

Get-Command <CommandName> -Syntax

Met Tab-completie

Je kunt ook controleren of de WhatIf-parameter wordt ondersteund door tab-completie te gebruiken. Typ eenvoudig de opdracht die je wilt controleren in een PowerShell-console gevolgd door een spatie, streepje, ‘Wh’ en de tab-toets.

Als WhatIf verschijnt, weet je dat de opdracht de WhatIf-parameter heeft.

PS> <CommandName> -Wh[tab]

Het gebruik van de PowerShell WhatIf-parameter met Cmdlets

Er zijn veel verschillende manieren waarop je gebruik kunt maken van de WhatIf-parameter. In deze sectie leer je hoe je onmiddellijk de WhatIf-parameter kunt gebruiken met ingebouwde cmdlets.

Bestand maken

Net als alle cmdlets heeft de New-Item-cmdlet een WhatIf-parameter. In dit voorbeeld gebruik je de New-Item-cmdlet om een bestand met de naam nieuwbestand1.txt te maken in dezelfde werkmap.

Als je de onderstaande opdracht zou uitvoeren, zou het het bestand met de naam nieuwbestand.txt maken.

PS51> New-Item -ItemType File -Path .\newfile1.txt

Maar wat als deze opdracht een bestand maakt dat mogelijk problemen kan veroorzaken als het niet succesvol wordt gemaakt? Geen probleem. Je kunt de WhatIf-parameter toevoegen aan het einde.

New-Item -ItemType File -Path .\newfile1.txt -WhatIf

Service stoppen

Je kunt ook de WhatIf-parameter gebruiken met de Stop-Service-cmdlet. In dit voorbeeld krijg je een lijst van de eerste vijf services en stop je ze met het Stop-Service-commando. Maar eigenlijk niet.

In plaats daarvan zie je alleen een uitvoerbericht op de PowerShell-console dat je laat weten welke services de Stop-Service-cmdlet zou hebben gestopt.

PS51> (Get-Service)[0..4] | Stop-Service -WhatIf

Powershell WhatIf-gedrag wereldwijd wijzigen

Op dit punt moet je weten dat het gebruik van de WhatIf-parameter bij een cmdlet of geavanceerde functie alleen de operatie simuleert. Je beïnvloedt WhatIf-gedrag op het commandoniveau.

De WhatIf gedrag kan ook worden ingesteld op een hoger niveau dat van invloed is op alle opdrachten door de automatische variabele $WhatIfPreference te manipuleren.

De $WhatIfPreference variabele is boolean. Het kan alleen True of False zijn. Standaard staat het op False wat betekent dat de ondersteuning voor WhatIf is uitgeschakeld voor alle opdrachten, tenzij overschreven op het niveau van de opdracht. Als het is ingesteld op True, zullen alle opdrachten die het ondersteunen, of ze nu expliciet de WhatIf parameter gebruiken of niet, in “WhatIf-modus” zijn.

U kunt dit testen door de waarde van $WhatIfPreference te veranderen naar True via $WhatIfPreference = $true. U kunt hieronder zien dat New-Item zonder de WhatIf parameter nu werkt alsof de parameter was doorgegeven.

PS51> $WhatIfPreference = $true

Als u $WhatIfPreference heeft gewijzigd naar True, vergeet dan niet om het terug te veranderen naar False via $WhatIfPreference = $false.

In dit gedeelte hebt u geleerd hoe u WhatIf ondersteuning kunt gebruiken met bestaande cmdlets. In de volgende actie leert u hoe u WhatIf ondersteuning kunt opbouwen in uw aangepaste scripts en functies.

Het implementeren van Powershell WhatIf ondersteuning in functies

Voor je probeert WhatIf-ondersteuning te implementeren in je scripts, is het essentieel om te weten dat er een verkeerde en juiste manier is om dit te doen. In de volgende secties zul je zien wat die zijn.

Het verkeerd doen: Het Wiel niet opnieuw uitvinden

Het is niet ongebruikelijk dat scriptontwikkelaars het wiel opnieuw uitvinden en hun eigen WhatIf-ondersteuning implementeren met wat if/then-logica. Hieronder zie je een voorbeeld.

Merk op dat de ontwikkelaar zijn eigen WhatIf-schakelparameter heeft gedefinieerd. Vervolgens gebruikten ze de waarde van die parameter om een if/then-constructie te gebruiken om de logica af te handelen wanneer de WhatIf-parameter al dan niet werd gebruikt.

Function Remove-LogFile {
    param (
        [Parameter(Mandatory)]
        [string]$name,

        [switch]$WhatIf
    )
    
    if ($WhatIf.IsPresent) { # WhatIf-schakelaar staat aan.
        Write-Host "WhatIf: I will remove the log file ""$name""" -ForegroundColor Yellow
    } else {
        # WhatIf-schakelaar staat uit.
        Write-Host "Delete log file ""$name""" -ForegroundColor Green
    }
}

Wanneer de bovenstaande functie wordt uitgevoerd met de WhatIf-parameter zoals hieronder getoond, lijkt het erop dat het zijn werk heeft gedaan. De functie heeft eigenlijk niets verwijderd en een bericht naar de console geretourneerd.

PS51> Remove-LogFile -name log.txt -WhatIf

Als het werkt, wat is er dan mis met deze methode? Omdat je de ingebouwde mogelijkheden van een geavanceerde functie negeert. Je zult deze functionaliteit in elke functie moeten opnemen die je maakt in plaats van je alleen te richten op wat de opdracht zal doen wanneer deze is uitgeschakeld.

In plaats daarvan, heruitvind het wiel niet en gebruik het SupportsShouldProcess trefwoord in combinatie met de $PSCmdlet.ShouldProcess(). Dat komt eraan.

Het juiste doen: Gebruik maken van SupportsShouldProcess

Alle functies die het [CmdletBinding()] trefwoord gebruiken, maken ze “geavanceerd”. Dit trefwoord voegt verschillende mogelijkheden toe aan de functie, inclusief ondersteuning voor WhatIf.

Alle geavanceerde functies ondersteunen de functionaliteit van WhatIf, maar het is aan jou om er gebruik van te maken. Om dit te doen, moet je eerst het SupportsShouldProcess trefwoord gebruiken tussen de haakjes van [CmdletBinding()], zoals hieronder getoond.

[CmdletBinding(SupportsShouldProcess)]

De functie staat nu toe dat je de ShouldProcess()-methode belt op de $PSCmdlet functievariabele om te bepalen of de WhatIf-parameter aan de functie is doorgegeven of niet. Als de WhatIf-parameter wordt gebruikt, retourneert ShouldProcess() False. Anders zal het altijd True retourneren.

Function Remove-LogFile {
     [cmdletbinding(SupportsShouldProcess)]
     param (
         [Parameter(Mandatory)]
         [string]$name
     )
     if ($PSCmdlet.ShouldProcess($name)) {
         ## De -WhatIf parameter werd NIET gebruikt. De functie moet normaal verwerken.
         Write-Host ("Delete log file " + $name) -ForegroundColor Green
     } else {
         ## De -WhatIf parameter werd gebruikt. De functie mag NIET verwerken.
     }
 }
WHATIF PARAMETER USED SHOULDPROCESS() RESULT
True False
False True

Nu kunt u hieronder zien wanneer Remove-LogFile wordt uitgevoerd met de WhatIf-parameter; het vertoont hetzelfde gedrag als ingebouwde cmdlets.

PS51> Remove-LogFile -name log.txt -WhatIf

Samenvatting

In dit artikel hebt u kennisgemaakt met de PowerShell WhatIf-parameter. U zou nu moeten begrijpen hoe het werkt en welke voordelen het kan bieden.

U zou ook moeten weten dat u de volgende keer dat u een failsafe nodig hebt voor uw PowerShell-functies, niet opnieuw het wiel hoeft uit te vinden. Maak in plaats daarvan gebruik van de bestaande PowerShell-ondersteuning voor WhatIf!

Verder lezen

Source:
https://adamtheautomator.com/powershell-whatif/