Mis keskkonnas mu skript jookseb

Iga Windowsi süsteemiülem peab oskama PowerShelli kasutada.  Kui ta seda ei oska, siis ei saa ta ennast Windowsi süsteemiülemaks nimetada.  Ja vähehaaval nad seda ka õpivad (kui nad juba ei oska).

Kõik on väga tore, kuni me teame, millises masinas me oma asju jooksutame.  Aga kui me oleme jõudnud juba sinnamaale, et koodi jooksutatakse automaatselt, siis läheb elu keerulisemaks.  Nimelt tuleb siis hakata tuvastama, et mis keskkonnas kood parasjagu jookseb.  Sest kui seda mitte teha, siis võib kood mitte töötada.

Vanasti oli lihtne, tuli vaid tuvastada Powershelli versioon.  Selleks oli kaks meetodit:

if ($PSVersionTable.PSVersion -lt "5.0") {
    throw "see on vale PowerShelli versioon"
}

#Requires -Version 5.0

Neist esimese puhul ei pea tingimata skripti tööd katkestama.

Windows 8-st alates hakkasid Powershelli moodulid kaasa tulema ka opsüsteemiga.  Samuti on vaja moodulite olemasolu kontrollida juhul, kui kasutada mõnd iselisatud funktsionaalsust.  Ka seda saab kahte moodi teha:

if (-not (get-module Hyper-V -ListAvailable)) {
    throw "Vajalik funktsioon puudu, katkestan"
}

#Requires -Modules Hyper-V

Vajadusel saab kontrollida ka mooduli versiooni:

if (-not (
    Get-Module Hyper-V -ListAvailable |
      Where-Object Version -EQ "2.0.0.0"
    )) {
      throw "Vajalik moodul puudu, katkestan"
    }

#Requires -Modules @{ModuleName="Hyper-V";ModuleVersion="2.0.0.0"}

Tasub tähele panna, et #Requires kontrollid töötavad ainult salvestatud skripti sees ning neid kontrollitakse juba skripti laadimisel.  See seab nende kasutamisele mõningad piirid.

Kui moodulite halduseks on oma koodihoidla, siis saab muidugi lihtsamalt:

#Requires -RunAsAdministrator
#Requires -Modules PowerShellGet
Find-Module userprofile -MinimumVersion 1.0 -Repository PSGallery |
    Install-Module -Force -Scope AllUsers

Get-InstalledModule | Update-Module

Aga vahel ei piisa ka mooduli olemasolu/versiooni kontrollist.  Näiteks on Windows 8.1-ga kaasas olevas moodulis (NetTCPIP) olemas käsk Test-NetConnection, mida Windows 8-ga kaasas olevas moodulis pole.  Aga mooduli versiooninumber on mõlemal sama.  Siis tuleb kontrollida konkreetse käsu olemasolu:

if (Get-Command Test-NetConnection -ErrorAction SilentlyContinue) {
    #olemas, võib tegutseda
} else {
    Write-Error "käsk puudu"
}

Get-Command telnet

Vahel oleks vaja hoopis teada, kas mõni opsüsteemi funktsioon on antud masinas olemas või puudu.  Windows Serveri haldusliidesed on funktsionaalsustest eraldi paigaldatavad ning võivad paikneda hoopis teises masinas.  Serveriga on asi lihtne.  Kui skripti jooksutavas masinas on ServerManager moodul (seda saab ka klient-OSile paigaldada, kui tõmmata omale RSAT)

if (-not (Get-WindowsFeature -Name RSAT-DNS-Server).Installed) {
    Install-WindowsFeature -Name RSAT-DNS-Server
}
#olemas, võib tegutseda

Klient-OSi puhul on see natuke keerulisem:

#Requires -Modules Dism
#Requires -RunAsAdministrator
if ((Get-WindowsOptionalFeature -Online -FeatureName telnet*).state -eq
    [Microsoft.Dism.Commands.FeatureState]::Disabled) {
      Enable-WindowsOptionalFeature -Online -FeatureName TelnetClient
    }

Nüüd jääb veel vaid üle kontrollida, et kas meil on käes server-OS või midagi muud:

#Requires -Modules CimCmdlets
if ((Get-CimInstance Win32_OperatingSystem).ProductType -eq 1) {
    "Workstation"
} else {
    "DC or Server"
}

#Requires -Modules Dism
#Requires -RunAsAdministrator
if ((Get-WindowsEdition -Online).Edition -like 'Server*') {
    "on server"
} else {
    "klient, vist"
}

Olen seni teadlikult vältinud OS versiooni kontrolli.  nagu ülaltpoolt näha, pole seda enamasti vaja.  Ent arvestades Windows 10 (ja nüüd kohe varsti ka Server 2016) väljalaske tsükliga, võib seda vaja minna:

if ([environment]::OSVersion.Version -ge "6.3") {
    "Windows 8.1 või värskem"
}

Õnnetuseks otsustas Microsoft antud viisile panna peale kontrolli: kui rakendus ise ei deklareeri, et ta tunneb uuemaid OS versioone, siis valetatakse talle versiooniks alati “6.2.9200” ehk siis Windows 8/Server 2012.  Lisaks on Windows 10 versiooninumbri algus kõigil väljalasetel sama, muutub ainult BuildNumber.  Seda aga saab kontrollida:

switch ((Get-CimInstance Win32_OperatingSystem).BuildNumber) {
    10240 {"Win10 RTM"}
    10586 {"Win10 1511"}
    14393 {"Win10/Svr16 1607"}
    15063 {"Win10 1703"}
    16299 {"Win10/Svr16 1709"}
default {"Insider build"}
}

Get-CimInstance kasutamine võimaldab teha kontrolli ka eemalt.  Samamoodi saab ka versiooninumbri kätte.  Tuleb lihtsalt arvestada, et CIM tagastab versiooninumbri kui stringi ja see tuleb ise versiooninumbriks teisendada, kui seda vaja peaks olema:

(Get-CimInstance Win32_OperatingSystem).Version -as [version]
Advertisements

One thought on “Mis keskkonnas mu skript jookseb

  1. Pingback: Powershelli tulevikust | Peetrikese kodu

Lisa kommentaar

Täida nõutavad väljad või kliki ikoonile, et sisse logida:

WordPress.com Logo

Sa kommenteerid kasutades oma WordPress.com kontot. Logi välja / Muuda )

Twitter picture

Sa kommenteerid kasutades oma Twitter kontot. Logi välja / Muuda )

Facebook photo

Sa kommenteerid kasutades oma Facebook kontot. Logi välja / Muuda )

Google+ photo

Sa kommenteerid kasutades oma Google+ kontot. Logi välja / Muuda )

Connecting to %s