Automatiseer taken met PowerShell PSake: Een stapsgewijze handleiding

Dus je hebt geleerd hoe je taken kunt automatiseren met een PowerShell-script. Dat is geweldig! Maar nu heb je een ongeorganiseerde puinhoop van scripts en modules met een mengelmoes van handmatige scriptuitvoeringen, geplande taken en meer. Het is tijd om wat orde in de chaos te brengen en de automatiseringsorkestratie-engine genaamd PowerShell PSake.

PSake is een orkestratie-engine geschreven als een PowerShell-module die orde toevoegt aan je scripts en je volledige controle geeft over wat wanneer en onder welke voorwaarden wordt uitgevoerd. Hoewel PSake een buildautomatiseringstool is en het primaire gebruiksscenario in buildscripts ligt (meestal uitgevoerd door een buildserver in releaseautomatiseringsscenario’s), wordt het over het algemeen over het hoofd gezien in alledaagse scriptingsscenario’s. Laten we dat veranderen.

In deze tutorial ga je leren hoe PSake werkt, samen met enkele geweldige voorbeelden die je vandaag nog kunt toepassen!

Vereisten

Deze tutorial is een stapsgewijze handleiding waarbij je wordt verwacht mee te doen. Als je precies wilt volgen wat er wordt behandeld, zorg er dan voor dat je het volgende hebt:

  • Windows PowerShell 3+. De tutorial maakt gebruik van Windows PowerShell v5.1
  • Het PSake-zipbestand van Github. Deze tutorial gebruikt versie 4.9.0.

Het instellen van de PSake-module

Als je het PSake-project van GitHub op je lokale machine hebt, moet je eerst een paar stappen doorlopen om het in te stellen.

  1. Pak het gedownloade PSake-zipbestand uit.
  2. Verplaats de src map naar de inhoud van het uitgepakte ZIP-bestand naar een pad onder $env:PSModulePath om ervoor te zorgen dat PowerShell op de hoogte is van de nieuwe module.
  3. Hernoem de src map naar PSake.
  4. Voer nu Get-Module PSake -ListAvailable uit om te bevestigen dat het wordt weergegeven. Als je geen foutmelding krijgt, ben je klaar om verder te gaan.

Gerelateerd: PowerShell-modules begrijpen en bouwen

Het maken van een eenvoudig PowerShell PSake-script

Om PSake te begrijpen, moet je iets bouwen. Laten we een eenvoudig PSake-script bouwen om te zien wat het kan doen.

  1. Maak een script met de naam psakefile.ps1 met een enkele taak. Een taak moet minimaal een naam en een actieblok hebben. De naam psakefile.ps1 is niet verplicht, maar het is de standaardnaam die door de engine wordt verwacht.

A PSake task in its basic form is very similar to a PowerShell function:
a container for one or more commands that, when performed together, achieve a certain goal. These commands go into a script block that is passed to the Action parameter. A task has many advantages over a function. You will learn about these advantages as you read along.

Hieronder staat een voorbeeld van een psakefile.ps1 met een vrij eenvoudige taak:

task HelloWorld -Action {
    Write-Host '*** Hello World ***' -ForegroundColor Yellow
}

2. Nu je het PSake-bestand hebt gebouwd, kun je het vanuit een PowerShell-console aanroepen met het Invoke-PSake commando en de taaknaam doorgeven als waarde aan de TaskList -parameter.

Invoke-PSake is de uitvoeringsengine voor PSake. Met dit commando worden taken uitgevoerd die gedefinieerd zijn in psakefile.ps1. Je geeft een taaknaam door, of een lijst van taken gescheiden door komma’s aan de TaskList-parameter. Als je meerdere taken uitvoert, zal elke taak worden uitgevoerd in de volgorde waarin je ze aan TaskList hebt doorgegeven, ongeacht hun locatie in psakefile.ps1.

Hieronder staat hoe je de HelloWorld-taak kunt triggeren:

Invoke-PSake -BuildFile C:\Work\psakefile.ps1 -TaskList 'HelloWorld'

Zolang je de naam psakefile.ps1 behoudt, en ervan uitgaande dat je de console hebt ingesteld op de map waar het zich bevindt, kun je de BuildFile-parameter en de bijbehorende waarde weglaten.

  1. Het uitvoeren van Invoke-PSake laat de PSake-uitvoer zien op de console. Wanneer je de taken in psakefile.ps1 uitvoert, zie je output die vergelijkbaar is met wat je hieronder ziet.
Psake script output

De output bestaat uit deze componenten:

  1. Details over de PSake-versie.
  2. De naam van elke buildtaak vlak voordat deze wordt uitgevoerd (PSake beschouwt elke taak als een build taak). In het voorbeeld: Executing HelloWorld in cyaan.
  3. Alle output die de taak heeft geproduceerd. In het voorbeeld: Hello World in geel.
  4. Succes/misluk bericht. In het voorbeeld: psake succeeded… in groen.
  5. Tijdsoverzicht (genaamd Build Time Report) met de duur van elke taak, plus de totale duur van het hele script.

SQL installeren met PSake

In het vorige gedeelte heb je niet veel meer gedaan dan een dummy PSake-script aanroepen. Bouw nu voort op die kennis en maak een PSake-script dat SQL installeert!

In dit voorbeeld ga je een PSake-script maken dat:

  1. Valideert vrije schijfruimte op een machine.
  2. Downloadt een SQL-ZIP-bestand van een lokale repository.
  3. Pakt het ZIP-bestand uit.
  4. Voert de installatie uit op station C of D (welke van de twee ook aanwezig is).

Laten we nu eens kijken hoe we PSake kunnen gebruiken voor deze taak.

Het Ontwerpen van de Bouwstenen

PSake draait om het orchestreren van taken. Elke taak moet een unieke naam hebben en idealiter moet deze één enkele atomaire bewerking uitvoeren, zoals een PowerShell-functie. Met dit concept kun je de onderstaande stappen beschrijven om een taak voor elk te bouwen.

  1. ValidateDiskSpace
  2. DownloadSql
  3. ExtractSql
  4. InstallSqlDriveC
  5. InstallSqlDriveD

Op dit punt bouw je eigenlijk nog geen code om iets te doen; je zet eenvoudigweg de taken in de steigers en maakt het PSake-bestand aan. Je zult de Write-Host-verwijzingen in de taken hieronder opmerken; je voegt later toe aan de taken.

Je moet altijd de Description-parameter gebruiken voor elke taak. De Description-parameter geeft meer informatie over elke taak bij zowel het uitvoeren van de taken als bij het bekijken van de code.

task ValidateDiskSpace -Description 'Validate Disk Free Space' -Action {
	
	Write-Host "`n   *** Checking disk free space ***`n" -ForegroundColor Yellow
	
}

task DownloadSql -Description 'Download SQL Setup' -Action {
	
	Write-Host "`n   *** Downloading SQL Setup from LAN ***`n" -ForegroundColor Yellow
	
}

task ExtractSql -Description 'Extract SQL Setup' -Action {
	
	Write-Host "`n   *** Extracting SQL Setup files ***`n" -ForegroundColor Yellow
	
}

task InstallSqlDriveC -Description 'Install SQL on C:' -Action {
	
	Write-Host "`n   *** Installing SQL Server on C drive ... please wait... ***`n" -ForegroundColor Yellow

}

task InstallSqlDriveD -Description 'Install SQL on D:' -Action {
	
	Write-Host "`n   *** Installing SQL Server on D drive ... please wait... ***`n" -ForegroundColor Yellow
	
}

Het Bepalen van de Uitvoeringsvolgorde van Taken

Je hebt nu een PSake-bestand dat een reeks taken bevat. Op dit punt kun je alle taken tegelijk uitvoeren of ervoor kiezen om slechts enkele ervan uit te voeren met het Invoke-PSake-commando.

U kunt enkele (of alle taken) aanroepen met Invoke-PSake en de TaskList parameter zoals u eerder deed in het eenvoudige voorbeeld. Als u meer dan één taak wilt aanroepen, maak dan een array en definieer de naam van elke taak als een item zoals hieronder weergegeven.

Invoke-PSake zal elke taak uitvoeren in de volgorde gedefinieerd in de array.

$taskList = @()

$taskList += 'ValidateDiskSpace'
$taskList += 'DownloadSql'
$taskList += 'ExtractSql'
$taskList += 'InstallSqlDriveC'
$taskList += 'InstallSqlDriveD'

Invoke-PSake -TaskList $taskList

Als u de bovenstaande code uitvoert, zou u een resultaat moeten krijgen zoals het volgende:

PSake script output

Het toevoegen van een Voorwaarde

Mogelijk moet u een bepaalde actie uitvoeren alleen als een bepaalde voorwaarde is voldaan. In het voorbeeld van het SQL-installatiescript van deze tutorial moet u bijvoorbeeld misschien testen of het volume waar u de installateur opslaat beschikbaar is voordat u de taak uitvoert om de genoemde installateur aan te roepen.

U kunt de PreCondition parameter gebruiken om een stuk code uit te voeren dat een boolean True of False retourneert, dat bepaalt of die taak al dan niet wordt uitgevoerd.

Let op het voorbeeld hieronder de variabelen $installSqlOn_C_Drive en $installSqlOn_D_Drive. Wanneer Invoke-PSake dit script aanroept, zullen deze variabelen een waarde True of False bevatten, afhankelijk of een C- of D-volume bestaat.

Op elke taak-regel kunt u vervolgens zien dat elke taak een PreCondition scriptblokparameter heeft die de waarde van die variabelen bevat. Op uitvoertijd zal ofwel de InstallSqlDriveC ofwel de InstallSqlDriveD taak worden uitgevoerd, afhankelijk van deze variabelen.

$installSqlOn_C_Drive = (Test-Path -Path 'C:') -and (-not (Test-Path -Path 'D:'))
$installSqlOn_D_Drive = (-not (Test-Path -Path 'C:')) -and (Test-Path -Path 'D:')

task InstallSqlDriveC -Description 'Install SQL on C:' -PreCondition { $installSqlOn_C_Drive } -Action {
	
	Write-Host "`n   *** Installing SQL Server on C drive ... please wait... ***`n" -ForegroundColor Yellow
	
}

task InstallSqlDriveD -Description 'Install SQL on D:' -PreCondition { $installSqlOn_D_Drive } -Action {
	
	Write-Host "`n   *** Installing SQL Server on D drive ... please wait... ***`n" -ForegroundColor Yellow
	
}

Taakparameters

Naast de Action en Description ondersteunt een taak ook deze parameters:

  • PreCondition – Scriptblok dat een booleaanse waarde retourneert. Bij False wordt de specifieke taak overgeslagen. (Een gebruiksvoorbeeld wordt hierboven getoond).
  • PostCondition Validatiestap. Een scriptblok dat een booleaanse waarde retourneert. False betekent dat validatie is mislukt en het hele script stopt.
  • PreAction – Een scriptblok om uit te voeren vóór de taak.
  • PostAction Een scriptblok om direct uit te voeren nadat de taak met succes is voltooid.
  • ContinueOnError Schakelparameter. Indien gebruikt, zullen eventuele fouten die zich tijdens de uitvoering van de taak voordoen, het hele script niet laten breken.
  • Depends Een naam van een taak (of een lijst met taaknamen) die moet worden uitgevoerd voordat de huidige taak wordt uitgevoerd. PSake zal deze informatie gebruiken om de taakafhankelijkheden in de juiste volgorde uit te voeren. Bijvoorbeeld, als taak A afhankelijk is van taak B, zal de PSake-engine B uitvoeren vóór A.

In eerste instantie klinkt het afhankelijkheidsmechanisme als een goed idee. Het helpt bij het instellen van taken in een logische volgorde. Echter, het gebruik van de Depends-parameter koppelt verschillende taken samen, waardoor het later moeilijk wordt om onafhankelijk te testen. Maar, aangezien de gebruiker expliciet de volgorde van taken kan instellen en deze volgorde kan doorgeven bij het oproepen van het PSake-bestand, kan het gebruik van de Depends-parameter volledig worden vermeden.

Laten we nu een gebruiksvoorbeeld bekijken voor enkele van deze taakparameters:

Het toevoegen van PreActie en PostVoorwaarde

Gebruik de taak InstallSqlDriveD van het bovenstaande voorbeeld als startpunt, misschien heb je een extra verzoek voor de installatie.

Misschien moet je de tijden registreren wanneer de installatie begint en eindigt. Je moet deze tijden registreren in twee omgevingsvariabelen genaamd SqlSetupStartDate en SqlSetupEndDate. Ten tweede, nadat de installatie is voltooid, moet je controleren of de map D:\TempSqlFiles niet bestaat.

Gelukkig voldoen de PSake-taakparameters PreActie, PostActie en PostVoorwaarde (respectievelijk) precies aan deze nieuwe vereisten. Hieronder volgt een voorbeeld van hoe dit kan worden gedaan:

task InstallSqlDriveD -Description 'Install SQL on D:' -PreAction {

     Write-Host '*** Writing SQL install start time to env. var. SqlSetupStartDate ***' -ForegroundColor Yellow
     $date = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
[Environment]::SetEnvironmentVariable('SqlSetupStartDate',$date,'Machine')

 } -PreCondition { 

     $installSqlOn_D_Drive

 } -Action {  
  
     Write-Host '*** Installing SQL Server on D drive... please wait... ***' -ForegroundColor Yellow 

} -PostAction {     

    Write-Host '*** Writing SQL install end time to env. var. SqlSetupEndDate ***' -ForegroundColor Yellow     
    $date = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
[Environment]::SetEnvironmentVariable('SqlSetupEndDate',$date,'Machine') 

} -PostCondition { 
    
Write-Host '*** Verifying temp files deleted ***' -ForegroundColor Yellow
     # als de map bestaat, geeft dit False terug, waardoor het hele script stopt
     (-not (Test-Path -Path 'D:\TempSqlFiles'))

 }

Het uitvoeren van PSake-scripts in Pester-tests

Waar je ook een PowerShell-script kunt aanroepen, kun je een PSake-bestand aanroepen. Als je infrastructuurtests bouwt met Pester, kun je PSake binnen tests aanroepen.

Gerelateerd: Het schrijven van Pester-tests voor PowerShell

Bijvoorbeeld, misschien heb je een Pester-test om te bevestigen dat het SQL-installatie-ZIP-bestand bestaat in een map nadat je de taak DownloadSql hebt uitgevoerd. In dat geval bouw je een eenvoudige Pester-test en roep je de taak DownloadSql binnen de test aan en controleer je meteen daarna op het ZIP-bestand.

Describe 'SQL install with PSake' {

    It 'Downloads Sql files' {

        $setup = 'C:\Downloads\SqlSetup.zip'

        if(Test-Path -Path $setup)
        {
            Remove-Item -Path $setup
        }

        # de enkele taak die hier wordt getest, is DownloadSql
        Invoke-PSake -BuildFile C:\Work\psakefile.ps1 -TaskList DownloadSql
        
        $setup | Should -Exist
    }
}

Het doorgeven van parameters aan taken

Wanneer je PSake begint te gebruiken, wil je misschien bepaalde taken parametriseren. Normaal gesproken geef je met PowerShell-functies en scripts verschillende genaamde parameters door aan de functie/script; PSake is anders.

Om parameters door te geven aan PSake-bestanden, kun je een Eigenschappen blok gebruiken dat sleutel/waarde-paren definieert, die PSake vervolgens beschikbaar maakt binnen elke taak in het bestand.

Zorg ervoor dat je het Eigenschappen blok bovenaan het PSake-bestand definieert. Alle PSake-operaties worden van boven naar beneden gelezen.

Bijvoorbeeld, om dynamische SqlYear en SqlVersion variabelen door te geven aan elke taak in het PSake-bestand, kun je ze als volgt definiëren.

Properties {
    $SqlYear = '2017'
    $SqlVersion = '14.0'
}

task -Name DownloadSql -Action {
    
    Write-Host "SQL version to install: SQL $SqlYear (version $SqlVersion)"

}

Wanneer je vervolgens het PSake-bestand aanroept met Invoke-PSake, zie je de volgende uitvoer. Let op dat de $SqlYear en $SqlVersion variabelen zijn uitgebreid met de waarden die zijn gedefinieerd in het Eigenschappen blok.

psake version 4.9.1
Copyright (c) 2010-2018 James Kovacs & Contributors

Executing DownloadSql
SQL version to install: SQL 2017 (version 14.0)

psake succeeded executing C:\Work\PSakefile.ps1

--------------------------------------------------
Build Time Report
--------------------------------------------------

Name        Duration
----        --------
DownloadSql 00:00:00
------      --------
Total:      00:00:00

Het gebruik van de Eigenschappen parameter

Als je liever parameters aan een taak doorgeeft via een traditionele parameter, kan PSake helpen. Je moet nog steeds het Eigenschappen blok bovenaan psakefile.ps1 behouden zoals in het bovenstaande voorbeeld, maar PSake laat je de waarden overschrijven.

Om dit te doen, definieer een hashtable met elk van de sleutel/waardeparen die je wilt overschrijven. Geef vervolgens de hashtable door aan de Eigenschappen parameter. De PSake-engine zal de waarden in de doorgegeven hashtable gebruiken boven die gespecificeerd in het Eigenschappen blok binnen het psakefile.ps1 script.

Let op de verschillen in syntax tussen het Eigenschappen blok en de Eigenschappen parameter. Op het Eigenschappen blok is elke regel een variabele en dus voorafgegaan door een dollarteken, terwijl de Eigenschappen parameter een hashtable is, dus elk item is een sleutel en geschreven zonder een voorafgaand $. Een ander verschil is dat de hashtable wordt voorafgegaan door het @-teken.

Hieronder zie je een voorbeeld van het gebruik van de Eigenschappen parameter.

$myNewProperties = @{
    SqlYear = '2019'
    SqlVersion = '15.0'
}

Invoke-PSake -TaskList DownloadSql -Properties $myNewProperties

PSake Taak Modularisatie: Taken als Bestanden

Op een gegeven moment zal je PSake-bestand waarschijnlijk exponentieel groeien, vooral als je grote automatiseringstaken moet orchestreren. Om ervoor te zorgen dat je al die taken kunt beheren, moet je je focussen op modularisatie of taken opsplitsen om de zaken gemakkelijker te beheren.

Gerelateerd: Hoe te overleven bij het refactoren van een PowerShell-script uit de hel

In het voorbeeld van deze tutorial werkte je met vijf taken:

  • ValidateDiskSpace
  • DownloadSql
  • ExtractSql
  • InstallSqlDriveC
  • InstallSqlDriveD

Elk van deze taken is gedefinieerd binnen een enkel pssakefile.ps1 script. Als je verwacht dat je in de loop van de tijd veel meer taken zult toevoegen, moet je die taken opsplitsen in afzonderlijke bestanden, waarbij elke taak binnen bijvoorbeeld ValidateDiskSpace.ps1, DownloadSql.ps1, InstallSqlDriveD.ps1, InstallSqlDriveD.ps1, enzovoort komt te staan.

Bijvoorbeeld InstallSqlDriveD.ps1 zal alleen deze code bevatten:

task InstallSqlDriveD -Description 'Install SQL on D:' -PreCondition { $installSqlOn_D_Drive } -Action {
	
	Write-Host "`n   *** Installing SQL Server on D drive ... please wait... ***`n" -ForegroundColor Yellow
	
}

Zodra de taken zijn verplaatst, importeer je de bestanden in psakefile.ps1 met behulp van de Include functie. Nadat dit is gedaan, wordt de inhoud van psakefile.ps1 teruggebracht tot deze code:

$installSqlOn_C_Drive = $true
$installSqlOn_D_Drive = $false

Include "$PSScriptRoot\ValidateDiskSpace.ps1"
Include "$PSScriptRoot\DownloadSql.ps1"
Include "$PSScriptRoot\ExtractSql.ps1"
Include "$PSScriptRoot\InstallSqlOnC.ps1"
Include "$PSScriptRoot\InstallSqlOnD.ps1"

Wanneer Invoke-PSake het psakefile.ps1 script triggert, weet Invoke-PSake niet of maakt het niet uit of de taken zich binnen het psake-bestand bevinden of zijn geïmporteerd door de Include methode.

Volgende stappen

PSake is een krachtige script-orchestrator die kan worden gebruikt voor vele doeleinden: software builds, CI/CD, pakketimplementaties, het maken van installatieprogramma’s en meer. De enige limiet is je verbeelding. Het wennen aan het bouwen van grote scripts met PSake dwingt je om te denken in taken (code bouwstenen). Het concept van taken maakt gebruik van de PowerShell-syntaxis, en door taken te gebruiken verrijk je je bestaande kennis van de opdrachtregel.

De code die je produceert met PSake wordt leesbaarder, onderhoudbaarder en gemakkelijker te testen. Na enige oefening zul je merken dat het opsplitsen van je stappen in verschillende taken ze gemakkelijker maakt om te scripten. De kleine hoeveelheid extra werk die het kost, betaalt zich ruimschoots terug op de middellange en lange termijn.

Waar zie je PSake passen in je werkprojecten?

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