Skip to content

PowerShell 101

Perusteet

MissÀ ajetaan?

Docker

Jotta sinun on mahdollista tehdÀ tÀmÀn kurssin tehtÀviÀ, sinulla on oltava PowerShell kÀytössÀ. Jos teet skriptejÀ, jotka poistavat tiedostoja tai tekevÀt jotakin muuta vaarallista, on suositeltavaa ajaa PowerShelliÀ Docker-kontissa. TÀmÀn pitÀisi olla sinulle tuttua jo aiemmasta Bash-osiosta. Kontti noudetaan Docker Hubin sijasta Microsoft Artifact Registry: PowerShell-katalogista. Kontti rakentuu Ubuntun pÀÀlle, mutta siihen on asennettu PowerShell riippuvuuksineen, ja vakio CMD ei ole bash, vaan pwsh.

Tip

Jos haluat harjoitella Microsoft Windows -spesifisiÀ komentoja, kuten Get-Service, tarvitset Windows-ympÀristön. Docker luo Linux-kontteja. Emme kÀsittele Windows-komentoja tÀssÀ kurssissa, mutta voit kokeilla niitÀ omalla koneellasi, mikÀli sinulla on Windows-kone kÀytössÀsi.

Local Machine

On kovin tyypillistÀ, ettÀ Dockeria suositellaan lÀÀkkeeksi aivan kaikkeen. Tulet huomaamaan, ettÀ jos ajat kaiken koodin vÀliaikaisessa kontissa, koodin syntaksia vÀrittÀvÀ VS Code PowerShell Extension ei toimi. Kyseinen Extension, aivan kuten muiden kielten vastaavat, tarvitsevÀt pÀÀsyn kielen runtimeen, jotta ne voivat tarjota sinulle koodin tÀydennystÀ, syntaksivÀrittelyÀ ja muuta.

Helpoin tapa ratkaista tÀmÀ? Asenna PowerShell lokaalisti, olit sitten Windows-, macOS- tai Linux-kÀyttÀjÀ. Voit yhÀ ajaa vaaralliset tai epÀvarmat skriptit Docker-kontissa, mutta voit kirjoittaa ja testata skriptisi lokaalisti.

Dev Container

Voit yrittÀÀ best of both worlds-ratkaisua Visual Studio Coden Dev Containers -ominaisuuden avulla. TÀmÀ on kuitenkin edistyneempi aihe. Emme kÀsittele sitÀ tÀssÀ kurssissa.

MikÀ se on?

PowerShell on Microsoftin kehittÀmÀ skriptauskieli ja komentotulkki. Se on suunniteltu alunperin Windows-ympÀristöön, mutta nykyÀÀn se on saatavilla myös Linuxille ja macOS:lle. Jos tarkkoja ollaan, niin tuotteita on kaksi, joista vain toinen on saatavilla muille kuin Windowsille:

  • Ⓜ Windows PowerShell
    • Asentuu Windowsin mukana. Perustuu kaupalliseen .NET Frameworkiin. Tuorein versio on 5.1 eikĂ€ Microsoft enÀÀ kehitĂ€ sitĂ€.
    • Executable: powershell.exe
  • â“‚ïžđŸŽđŸ§ PowerShell
    • Asennetaan erikseen. Tuorein versio on 7.x ja Microsoft kehittÀÀ sitĂ€ aktiivisesti.
    • Executable: pwsh

Warning

Huomaa, ettÀ kaikkia moduuleita tai cmdlettejÀ ei ole saataville kaikille alustoille. Esimerkiksi moduulin Microsoft.PowerShell.Management komento Get-Service ei toimi Linuxissa. TÀmÀ johtuu .NET Frameworkin ja .NET Coren eroista. 1

EntÀpÀ .NET?

Dotnet (.NET) on kehitysympÀristö (engl. developer platform), jolla on useita tehtÀviÀ ja joka koostuu useista eri osista. Ekosysteemiin kuuluu esimerkiksi ajoympÀristö (engl. runtime envinronment) Common Language Runtime (CLR), joka on vastuussa koodin suorittamisesta Java-virtuaalikoneen tapaan. Suoritettava koodi on Common Intermediate Language (CIL) tavukoodia. Ekosysteemi sisÀltÀÀ nÀiden lisÀksi kirjastoja, kÀÀntÀjÀn, SDK ja muuta. Varsinaiset CIL-kieleksi kÀÀnnettÀvÀt dotnet-ohjelmointikielet ovat C# ja F#. PowerShell on sekÀ tulkki (komentokehote, CLI) ettÀ skriptauskieli, joka kÀyttÀÀ .NETin kirjastoja. SitÀ ei kÀÀnnetÀ, vaan sitÀ tulkataan dynaamisesti ajon aikana PowerShell runtimen toimesta. 2

Jos ylempi kappale meni aivan ohi, niin tÀrkeÀÀ on sisÀistÀÀ, ettÀ .NET kirjastoja voi kutsua PowerShellistÀ, koska se on .NET-ympÀristössÀ toimiva kieli. PowerShellin cmdletit ovat kÀÀnnettyjÀ .NET-kirjastojen kutsuja. KÀytÀnnössÀ seuraavat kaksi tekevÀt jossain mÀÀrin saman asian, joskin alempaa muotoa on luonteva kÀyttÀÀ vain silloin, kun sopivaa cmdletiÀ ei ole olemassa:

# PowerShell cmdlet
Get-Process

# .NET Library the cmdlet wraps
[System.Diagnostics.Process]::GetProcesses()

Info

Namespacen ensimmÀinen osa, esim. System, voidaan usein jÀttÀÀ pois. NÀin esimerkiksi [System.Math] on sama kuin [Math].

Dotnet-kirjastojen avulla voi saada C#:stÀ tuttuja toiminnallisuuksia työkalupakkiisi. EsimerkkinÀ tÀstÀ olkoot luvun korottaminen potenssiin, joka hoituu PowerShellissÀ nÀin:

PowerShell
$result = [Math]::Pow(10, 2)

Write-Host $result

Ja C#:ssÀ nÀin:

C#
using System;

class Program {
    static void Main() {
        double result = Math.Pow(10, 2);
        Console.WriteLine(result);
    }
}

Erot Bashiin

PowerShellissÀ kÀsitellÀÀn pÀÀasiassa objekteja. TÀmÀ tulee jatkumaan myöhemmin Python-osiossa: myös se kieli on rankasti objekteihin suuntautunut.

"A key difference with Bash is that it is mostly objects that you manipulate rather than plain text" 3

KÀytÀnnössÀ tÀmÀ tarkoittaa sitÀ, ettÀ esimerkiksi kokonaisluku on objekti, ja objektilla on metodeja. KÀrjistettynÀ BashissÀ kaikki on vain tekstiÀ, eli merkkijonoa, jota voidaan tulkita esimerkiksi lukuja aritmeettisissa operaatioissa (let tai $(( expression ))). PowerShellissÀ luku on luku, merkkijono on merkkijono ja esimerkiksi IP-osoite on IP-osoite. Kaikilla niillÀ on omat metodinsa. Jos putkitat yhden komennon tulosteen toisen komennon syötteeksi, niin kyseinen komentoketju (engl. command chain) sisÀltÀÀ useita eri objekteja listana. BashistÀ tuttu grep, awk tai sed parsiminen vaihtuu objektien kÀsittelyksi. Tulet tutustumaan tÀhÀn myöhemmin harjoitusten muodossa.

Tip

Voit siis ajaa one-liner komennon: $number = 10; $number.GetType(). Ruutuun tulostuu taulukkomuotoinen nÀkymÀ, jonka sisÀllöstÀ ja muodosta vastaa Out-Default. Huomaa, ettÀ komennossa kutsutaan numeron omaa metodia GetType(), joka palauttaa tiedon siitÀ, minkÀ tyyppinen objekti on kyseessÀ. TÀtÀ et voi BashissÀ tehdÀ.

EnsimmÀinen kontti

Alla olevan docker container run komento on Bash-osiosta tuttu, joskin kÀytÀmme eri imagea. Komento kÀynnistÀÀ PowerShellin Docker-kontissa.

Bash | Git Bash | PowerShell | CMD
docker container run --rm -it mcr.microsoft.com/powershell 
🍎 Apple Silicon -kĂ€yttĂ€jille

YllÀ mainittu image ei vÀlttÀmÀttÀ toimi macOS-koneella, jossa on Silicon-prosessi (M1, M2, ...). Voi toki olla, ettÀ tilanne on muuttunut sitten tÀmÀn ohjeen kirjoittamisen, mutta jos kyseinen image kaataa Terminaalin jatkuvasti, kokeile arm64:lle kÀÀnnettyÀ imagea, joka perustuu Microsoftin kehittÀmÀÀn Mariner-jakeluun (alias Azure Linux).

# macOS ARM64
docker container run --rm -it mcr.microsoft.com/powershell:mariner-2.0-arm64

Docker-komento ja sen parametrit (--rm ja -it) ovat sinulle jo tuttuja Bash-osiosta. Alla olevassa koodissa tulostetaan PowerShellin versiotiedot Docker-kontissa. Alempana nÀet tulosteen. Komento on ajettu samana pÀivÀnÀ sekÀ Ubuntu- ettÀ macOS-koneella, jÀlkimmÀisessÀ kÀyttÀen mariner-imagea.

PowerShell @ Docker
$PSVersionTable
stdout @ Docker
Name                           Value
----                           -----
PSVersion                      7.4.2
PSEdition                      Core
GitCommitId                    7.4.2
OS                             Ubuntu 22.04.4 LTS
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0
}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
stdout @ Docker
Name                           Value
----                           -----
PSVersion                      7.4.6
PSEdition                      Core
GitCommitId                    7.4.6
OS                             CBL-Mariner/Linux
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0
}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Komennot ja apu

Varsinaiset komennot ovat cmdlet-tyyppisiÀ. Ne koostuvat verbistÀ ja substantiivista. Alla esimerkki:

  • Verb-Noun: pseudoesimerkki
  • Get-Process: hakee prosessit
  • Get-Alias: hakee aliasit komennoilla (esim. dir on Get-ChildItem komennon alias)
  • Update-Help: pĂ€ivittÀÀ PowerShellin helpin, ladaten rutkasti esimerkkejĂ€ ja lisĂ€apua.

MistÀ tahansa komennosta saat helpin muutamalla eri tavalla. Alla esimerkkejÀ, joissa halutaan saada lisÀÀ tietoa Get-ChildItem-komennosta:

# Kenties alkuun haluat ajaa:
Update-Help

# Get-Noun muoto
Get-Help Get-ChildItem

# Huomaa, ettÀ se ei ole case-sensitiivinen
get-help get-childitem

# Output on helpompi lukea less-ohjelmassa
Get-Help Get-ChildItem | less

# Lyhyt muoto (alias)
help Get-ChildItem

# Kysymysmerkki
Get-ChildItem -?
Verb-Noun -parameter value -anotherparameter anothervalue -switch

Kyseinen Verb-Noun-cmdlet-pohjainen syntaksi on PowerShellin ydin. Esimerkiksi Get-Process hakee prosessit ja Stop-Process pysÀyttÀÀ prosessin.

Skripti

Aivan kuten Bashin kohdalla, myös PowerShellissÀ skripti on tiedosto, joka sisÀltÀÀ yhden tai useamman komennon. Aivan kuten Bash, PowerShell on myöskin tulkki, jossa toimii samat komennot kuin skriptitiedostoissa.

Kuva 1: Yksinkertainen for-silmukka PowerShellissÀ ilman erillistÀ skriptitiedostoa. Komento on ajettu kontissa.

SisÀltö

Skripti on tiedosto, joka sisÀltÀÀ yhden tai useamman komennon. TÀmÀ on sinulle Bashista tuttua, mutta PowerShellin kohdalla konvention mukainen tiedostopÀÀte on .ps1. Huomaa, ettÀ shebang ei ole tarpeen, jos tiedosto ajetaan nimenomaan PowerShellissÀ. Tiedoston ei myöskÀÀn tarvitse olla executable eli chmod +x ei ole tarpeen.

hello.ps1
Write-Host "Hello, World!"

Suorituspolitiikka (Ⓜ Win)

On tÀrkeÀÀ huomata, ettÀ jos ajat PowerShelliÀ Windows-ympÀristössÀ, sinun tulee ottaa huomioon execution policy. Kyseinen asetus sÀÀtÀÀ sitÀ, missÀ tapauksissa skriptejÀ saa suorittaa. Tavallisessa Windows Home/Pro -ympÀristössÀ execution policy on Restricted, joka tarkoittaa, ettÀ mitÀÀn skriptejÀ ei saa ajaa. Yleisesti suositeltu asetus on RemoteSigned.

Jos et ole aikaisemmin tehnyt mitÀÀn PowerShell-skriptien ajoon liittyviÀ toimenpiteitÀ, suorita seuraava komento:

PowerShell in Windows
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Tip

Jos ajat PowerShelliÀ Docker-kontissa tai muutoin Linuxissa, sinun ei tarvitse huolehtia tÀstÀ: policy on vakiona Unrestricted, eikÀ RemoteSigned ole edes tuettu.

Tietoturva-offtopic

RemoteSigned ei vÀlttÀmÀttÀ toimi aivan kuten sen arvaisi toimivan. Se, onko tiedosto InternetistÀ ladattu vai ei, mÀÀrittyy Zone.Identifier -attribuutin perusteella. TÀmÀ ongelma on kuitenkin helppo kiertÀÀ: poista attribuutti tiedostosta. Jos kokeilet ladata Invoke-RestMethod-komennolla skriptin, saatat yllÀttyÀ, kun sillÀ ei olekaan koko Zone.IdentifieriÀ asetettuna, vaikka voisi kuvitella. Myös koko policy on helposti kierrÀvissÀ.

Execution Policy ei ole siis sinÀnsÀ vahva turvamekanismi. Se lÀhinnÀ ehkÀisee kÀyttÀjÀÀ ajamasta skriptejÀ huomaamattaan.

Tiedoston luominen

Tiedoston voi luoda millÀ tahansa tekstieditorilla, mutta on suositeltavaa kÀyttÀÀ Visual Studio Codea. TÀmÀn kÀyttöön tutustutaan lÀsnÀtunneilla.

Skriptin ajaminen

Skriptin voi ajaa monella tapaa. Tyypillinen tapa on relatiivinen polku. Koska me olemme samassa hakemistossa kuin skripti, relatiivinen polku on yksintaisesti ./<tiedostonimi>:

# Relatiivinen polku
./hello.ps1

Absoluuttista polkua kÀyttÀen:

# Linux
/root/hello.ps1

# Windows
C:\Users\user\hello.ps1

Kyseisen binÀÀrin argumenttina:

# PowerShell Core
pwsh ./hello.ps1

# Windows PowerShell
powershell.exe ./hello.ps1

TehtÀvÀt

TehtÀvÀ: PowerShell Hello World

Luo skriptitiedosto hello.ps1, joka tulostaa tekstin "Hello World".

Varmista, ettÀ saat sen ajettua ympÀristössÀ, jossa koet kehittÀmisen mieluisaksi. Saat kÀyttÀÀ fyysistÀ konetta, virtuaalikonetta, Dockeria tai vastaavaa.

Suositus: Docker

TehtÀvÀ: PowerShell informaatiohaku

Toimi kuten aiemmassa Bash-tiedonhakutehtÀvÀssÀ. Muodosta itsellesi hyödyllinen katalogi lÀhteistÀ. Alla muutama suositus, mistÀ aloittaa etsintÀ:

  1. PowerShell Documentation. Virallinen dokumentaatio. Varmista, ettÀ seuraat oikean version dokumentaatiota.
  2. Markus Fleschutzin PowerShell repo. SisÀltÀÀ sekÀ cheat sheetin ettÀ satoja PowerShell-skriptejÀ.
  3. Learn PowerShell in Y Minutes. Cheat Sheet -tyylinen opas, josta selviÀÀ ydinasiat.
  4. KAMK Finna. Hakusanalla "PowerShell" löytyy esimerkiksi Jonathan Hassellin kirja "Learning PowerShell" vuodelta 2017.

Myös Bashin kohdalla mainitut kirjalÀhteet eli KAMK Finna, Humble Bundlen ja O'Reillyn kirjasto ovat toimivia paikkoja etsiÀ tietoa - jÀlkimmÀiset kaksi ovat toki maksullisia. Erityismaininnan arvoinen maksullinen kirja on Don Jones ja Jeffrey Hicksin Learn PowerShell Scripting in a Month of Lunches 2nd ed. (Manning).

LĂ€hteet


  1. Microsoft. Differences between Windows PowerShell 5.1 and PowerShell 7.x. https://learn.microsoft.com/en-us/powershell/scripting/whats-new/differences-from-windows-powershell 

  2. Microsoft. Introduction to .NET. https://learn.microsoft.com/en-us/dotnet/core/introduction 

  3. Schandevijl et. al. 2025. Learning PowerShell in Y Minutes. https://learnxinyminutes.com/powershell/