Skriptid ja häälestus

Iga skript vajab mingeid seadistusi. On see siis server kellega ühendust võtta või autentimisinfo või info mida korjata. Ning alati tekib see probleem, et mis peaks saama skripti sisse kirjutatud ja mida oleks vaja sagedamini muuta.

Esimese hooga tundub et milles küsimus. Kirjutame muutujad kõik skripti alguses ühte blokki kokku ja muudame kui vaja. Aga siis pead Sa sama skripti jooksutama korraga paljudes serverites. Ja siis tuleb seda aastate jooksul muuta: parandada vigu või kohendada funktsionaalsust. Ja siis on alati üks jama nende muutujatega. Alati peab mäletama et teises serveris on need teistsugused. Ja see tähendab et skripti ei saa lihtsalt automaatikaga üle kirjutada, kui uuem versioon valmis saab. Ning uude serverisse ei saa skripti võtta vanast, vaid peab mäletama, et muutujad tuleb ära muuta.

Interaktiivse skripti puhul (mida käivitab inimene) on asi lihtne: teed muutujatest käsurea parameetrid ja skripti käivitamisel annad need ette. Ja harvemini varieeruvatele parameetritele saab anda vaikeväärtused. Aga kui skripti tuleb jooksutada automaatselt? Task Scheduler (või cron) võimaldab parameetrid ka lisada, aga see ei ole just väga mugav, eriti kui vahel oleks vaja neid muuta.

Siis võiks ju proovida luua teise skripti mis sisaldaks esimesele vajalikke väärtusi. Aga siis on Sul ühe skripti asemel hallata kaks tükki. Ja see teine skript oleks ikka käivituv kood, mis võiks olla käivitajale kättesaadav ainult lugemisõigustes (või siis signeeritud).

Selle asemel võiks kasutada keskkonna muutujad:

$PSEmailServer = $env:MailServer

# muudame väärtust
[Environment]::SetEnvironmentVariable(
  'MailServer',
  'my.mail.server',
  [EnvironmentVariableTarget]::User
)

Ainsaks probleemiks on, et iga keskkonnamuutuja on üks string (ja keegi peab need väärtustama ka, või vähemalt mäletama et enne skripti käivitamist tuleb muutujad väärtustada). Keerulisema häälestuse salvestamiseks läheb neid muutujaid päris palju. Ning lisaks võivad keskkonnamuutujad hakata skriptide vahel sassi minema, kui just väga hoolikalt muutujate nimede peale ei mõtle.

Sedalaadi ülesandeks sobivad paremini häälestusfailid. Ja PowerShell oskab erinevaid struktuurseid andmefaile lugeda. Seega ei pea häälestusfail olema lihtsalt tekstridade kogumik (või .ini fail). Selle asemel saab kasutada XML, JSON või PowerShell Data file (.psd1) vormingut. Ja enamasti on need failid ka inimese jaoks loetavad.

Näiteks saab seda teha sarnaselt:

#Requires -Version 3.0
param (
  $LocalConfig = $(
    Join-Path -Path $PSScriptRoot -ChildPath (
      (Get-Item -Path $PSCommandPath).BaseName + '.config'
    )
  ),
  $WebConfig = 'https://web.site/data.config'
)

# XML config
$conf1 = [xml](Get-Content -Path $LocalConfig)
$conf2 = Invoke-RestMethod -Uri $WebConfig

# JSON
$conf1 = Get-Content -Path $LocalConfig | ConvertFrom-Json
$conf2 = Invoke-RestMethod -Uri $WebConfig

# PSD1
$conf2 = (Invoke-WebRequest -Uri $WebConfig).Content |
  Invoke-Expression
$ScriptBlock = [ScriptBlock]::Create(
  (Get-Content -Path $LocalConfig) -join [environment]::NewLine
)
$conf1 = $ScriptBlock.Invoke()
#Requires -Version 5.0
$conf1 = Import-PowerShellDataFile -Path $LocalConfig

Ja juba on võimalik kood ja häälestusinfo ilusti teineteisest lahku viia. Ning vajadusel tegeleda häälestuse keskse haldusega.

Kui nüüd tahta et paljud skriptid oskaksid samamoodi häälestust lugeda ja et kohe oleks olemas ka võimalus häälestust salvestada, siis tasuks kogu sellege tegelev kood viia eraldi moodulisse. Lisaks annaks see võimaluse, et meil on oma vaikehäälestus, mida saaks masina- või kasutajapõhiselt üle kirjutada. Ja et häälestus võiks olla ka kuskil mujal, kui failides.

Enne kui hakkad omale sellist moodulit kirjutama, vaata ehk sobib mõni alltoodutest:

  • Configuration – on mõeldud kasutamiseks ainult moodulitest. Töötab .psd1 failidega ja võimaldab häälestust laadida ja salvestada erinevatesse asukohtadesse (mooduli kaust, $env:LOCALAPPDATA, $env:APPDATA, $env:ProgramData).
  • PSFramework – muuhulgas pakub ka häälestuse seadistamist, salvestamist ja laadimist väga erinevatest asukohtadest (sealhulgas registrist või kasutaja määratud JSON failist/ veebiteenusest). Häälestuse süsteem on laiendatav ka selles osas, et kui leida/kirjutada vahendaja, saab häälestust hoida ka näiteks andmebaasis. Ja häälestust tarbiv rakendus ei pea kogu seda keerukust teadma.
  • PSConfig – võimaldab häälestust laadida .csv, .json või tekstifailist (kasutades ConvertFrom-StringData käsku). Või siis keskkonnamuutujatest.

Selliseid mooduleid on veel, aga need tunduvat rahuldavat ka kõige nõudlikuma tarbija vajadusi.

Powershell spikri kirjutamine

Powershelli spikri kasutamisest sai mõnda aega tagasi kirjutatud. Nüüd vaataks, kuidas selle spikri sisu loomise ja muutmisega on.

Powershelli spikri süsteem kasutab info hoidmiseks XML-vormingut, mis on isegi dokumenteeritud. Ent sellega ümberkäimine on suhteliselt ebamugav (isegi kui omada selleks sobivaid tööriistu) ning see peab olema samas masinas, kus spikrit lugeda tahetakse. Seetõttu on spikri sisu dünaamiline muutmine/uuendamine natuke keeruline.

Teiseks on skriptidele spikri kirjutamisel võimalik kasutada XML-vormingu asemel hoopis skripti sisse käivat kommentaaripõhist spikrit. Muidugi saab kommentaaripõhisest spikrist alati viidata ka välisele (XML-põhisele) spikrile.

Kolmandaks on moodulite spikris niinimetatud about-teemad, mida hoitakse tavaliste tekstifailide kujul.

Powershell 3.0 lisas spikrisüsteemile veel Online-spikri ja spikri värskendamise toe. Aga see teeb elu veelgi ebamugavamaks, kuna nüüd tuleb hallata nelja erinevat vormingut:

  1. tekstifailid
  2. XML-vormingus spikker
  3. veebisait online-spikriga
  4. veebisait, kust saab muudetud spikri sisu alla laadida (ja sellega koos alla laetava spikri fail).

Õnneks paistab tunneli otsast valgust. Powershelli moodul platyPS pakub võimalust tuua kõik ülalmainitud spikri vormingud kokku ühe ja sama allika peale ning muuta spikri sisu samast allikast kättesaadavaks kõigis ülaltoodud vormingutes.

platyPS pakub võimalust hoida spikri sisu Markdown-vormingus, mis on inimloetav ja lihtsasti muudetav mistahes tekstiredaktoriga. Paljud veebisaidid oskavad Markdown-vormingut automaatselt näidata HTMLi kujul. Seega on Online-spikker sellega valmis.

Järgmine samm on XML-vorming. platyPS sisaldab käsku New-ExternalHelp, millega saab Markdown-spikri teemad teisendada XML-vormingusse. Ja ühtlasi pakkida ka uuendatava spikri failiks, mida saab veebisaiti üles laadida.

Kui Sa leiad, et Markdown on koodist eraldi ning jääb seetõttu tähelepanuta, siis oskab platyPS teisendada kommentaaripõhise spikri Markdown-vormingusse. Nii et siis tuleb lihtsalt aeg-ajalt värskendada oma Markdown spikri teemasid ja need seejärel kättesaadavaks teha. Kommentaarid ise on alati koodiga koos ja seega kohe kättesaadavad koodi arendajale.

Powershell 6 plaanib kogu spikrisüsteemi viia XML-vormingult üle Markdown vormingusse. Juba praegu on Powershell 6.1-s lisatud käsk ConvertFrom-Markdown, mis loeb Markdown-vormingut ja muudab selle Powershelli käsurealt kasutatavaks.

Suuremates projektides tekib vajadus hoida dokumentatsioon (ja spikker) koodist lahus, kuna dokumenteerimisega võivad tegeleda teised inimesed. Ka sellisel juhul on Markdown-vorming hea. Ilus näide selle kohta on Microsofti dokumentatsiooni sait docs.microsoft.com. Kogu selle sisu on tegelikult Github’is üleval ja kaastööks kättesaadav.