detsember 20, 2015

PowerShelli koorimas I













Blogi omapära ja häda on tema ajakajalisus. See, mida mõtlesid eile ja ütlesid eile,
jääb kivisse raiutuna internetti aastakümneteks.
Eile ma arvasin PowerShelli (PS) kohta üsna halvasti, põhinedes selle keele v1. pealiskaudsel kiirtutvusel aastaid tagasi. (vist 2008).
See oli aeg, kui Windows XP-sid oli väga palju. PowerShell nende kastide jaoks automaatselt ei toiminud, PS rakendamine organisatsioonis oleks tähendanud lisapingutusi. PS oli siis veel toores, Alates v2. on PS rakenduskõlbulik.
Serveritega sai ka vanaviisi õiendada - GUI - graafilise kasutajaliidese - toel ja vajadusel kaugelt RDT -ga (Remote Desktop) asju sättides...
Ühesõnaga, mugavustsoonis sai edasi elada. Pealekauba MS toetas ja toetab jätkuvalt GUI põhist administreerivat mõtteviisi.
Ka MS siseselt tundub jätkuvalt eksisteerivat usulõhe, sest PS looja Jeffrey Snoveri manifest
(vt. Monad Manifesto koos järelmõtetetega 2011)  eksisteerib juba aastast 2002, PS v1 sai valmis 2006, PS v2 2009  ja alles viimasel ajal on hakatud rääkima (konkurendi Linux mõjul?) ühest peamisest paradigma nihkest - DSC-st (Desired State Configuration-st, Linux-ite Puppeti mõjul). Ühesõnaga, administraator paneb konfifailides paika, millisena ta tahab oma lambaid näha ja lambad ise sätivad ennast vastavaks administraatori nõuetega.
Elu ise teeb MS mõtteviisis aga korrektiive, sest ettevõtted tahavad toime saada vähema arvu patsiga poistega, samal ajal, kui arvutite ja serverite hulk kasvab ...
Nii on MS enda sees läinud käibele termin windowsi "defenestreerimine"...

Aga näiteks ka minu vana tööandja Alma sees lastakse vanaviisi edasi ja need inimesed, kes oleksid olnud võimelised neid asju ellu viima ... koondati ära. Pärast vastavate tegelaste istutamist juhtivatele kohtadele äkitselt "dünaamiliseks" muutunud kollektiiv on seejärel saanud maha veel mitme pereheitmisega.
Tõsi, selle dünaamilisuse taha peidab ennast tõsiasi, et kogu dünaamika vaid lõpututes pereheitmistes seisnebki.
Aga jumal sellega. Riigi (eriti meie riigi) asutuste puhul ei ole hea idee liialt süveneda nende hingellu või tahta mingeid muutusi. Kui midagi toimib, keeratakse see xxxxx, ei ole mingit garantiid organisatsiooni maabuva loodusõnnetuse eest. Hästi toimimine / töötamine ei ole mingi argument. ...

Praegu vaatlen ma PowerShelli arendaja vaatepunktist ja jälle tuleks oma hoiakuid revideerida -  PowerShell võiks olla igale C# arendajale töövahend.
Mõlemad põhinevad .NET -l, mõlemate ellukutsumise põhjuseks on see raamistik, seetõttu lähemal vaatlusel on üks keel teise "dialekt".

 Kõik need tõsiasjad oleksid jäänud mul aga täiesti tähelepanuta, kui poleks olnud vajadust läbi sirvida skriptivate keelte loomaaed ülevaate saamiseks ning .bat keel oli ainukene, mida ma tundsin windows -st (VBS ja JavaScriptil põhinev JS on tegelikult paremad variandid kasutamiseks).
Jõudsin lõplikule järeldusele (vt. Sekeldaja "Pakkfailide feilimisest" I & II), et .bat keel on programmeerimiskeelte seas vaieldamatult üks kipakamaid ja meeleheide (mingi skriptimisvahend võiks MS-l ju siiski ka toimida) sundis veel kord üle vaatama PS-i.
Ja veelkordne üllatus (suurima üllatuse printsiip MS maailmas!):
PowerShell on täiesti kõlbulik programmeerimiskeel!
Äkki on PS operatsioonisüsteemide kesti (shells) programmeerivate keelte seas ehk isegi üks parimatest?
Viimane asjaolu on seotud PowerShelli suhtelise noorusega ja õnneks sellega, et selle keele loojad on midagi ikkagi õppinud eelnevate keelte vigadest ...eriti ehk  muidugi  DOS.

Aga aitab filosoofilisest grafomaaniast:

Küülikuagust alla

1. Monadoloogia ja võtmetekstid:
Leibnizil on üks tähtis filosoofiline teos - vt.
Omab väga vähe pistmist Powershelliga, v.a. võtmesõna monaad.
Otsing Monad Powershell viib aga olulise võtmetekstini:
Järgnev on aga PS olulisim võtmetekst:
2. Võtmeisikud:

2.1 . Jeffrey Snover













http://jsnover.com

2.2 BRUCE PAYETTE





2.3 MUFTI















Raamatu "Power Shell in action" kaanepilt kujutab muftit - vaimulikku, kelle ütlused ühe või teise asja kohta on siduvad usujüngritele.
Võtke seda pilti tõsiselt ja ärge raisake esialgu liiga palju aega muude tekstide peale, kui 
“PowerShell in action”

3.  Ajalugu

/ üks kulunud tsitaat ütleb, et kõik, kes koolis ei õpi ajalugu, on määratud kursust kordama ... /
PowerShell (edaspidi PS)  ei ole olnud oodatud tegelane MS nukuteatris. Pigem nagu kõrvaltegelane, noorim vend vene muinasjuttudest.
Aga nagu vene muinasjutuski saab ta vist päranduseks ... terve MS impeeriumi, sest uued serverid enam muid vahendeid peale PS administreerimisel ei tunnista (nano).
2002 augustis, pärast umbes aastast tegevust Windowsi kesta arendamisel, ilmus "Monad Manifesto".
Seejärel järgnes arendusprojekt, kus võtmeisikud asusid USA-s (Seattle), programmeerijad töötasid Indias. Pärast 18 kuu pikust ponnistamist alustati projektiga sisuliselt uuesti.
Probleemiks oli seisulik suhtumine Indias - Snover vajas enese kõrvale inimesi, kes ütelnuks, et nemad teavad paremini, kuidas mõnda asja teha, mitte Yes, Sir tüüpi käsutäitjaid.
PS loomist segas ka suurel määral MS Longhorn projekti põrumine. Ja nii edasi ...
Kuid nov. 2006 ilmus PS v1
aug. 2009 PS v2.
7 aastat manifestist kuni esimeste viljadeni on programeerimise maailmas küllaltki pikk aeg.
Snoveri rolliks oli öelda välja ebameeldiv tõde, et mõte sellest, et GUI võiks täielikult asendada käsurea interpretaatorit oli viga.
Lisaksin, et üks ärilisemalt õnnestunumaid vigu üldse, kui lugeda MS ja Apple edulugusid.
Ja nüüd äkki - ei kõlba?!

 4. Miks PS? Miks mitte GUI?

Kuigi kuulun ametilt nende inimeste hulka, kes peaksid hirmsasti armastama käsurida, ei ole see siiski nii. Must/helesinine ekraan käsurea promptiga ei tekita ei Linux-is ega DOS-s / nüüd siis PS-s erilist vaimustust, kui just ei ole vaja.
Kunagi ammu Füüsika Instituudis läks elu DOS-s tunduvalt lihtsamaks sellise huvitava programmi, nagu Norton Commander tulekuga. Tänaseni kasutan - kasvõi Linuxis nime all mc.
Ka Windowsi või mac-iga õiendamine on GUI-d kasutades ÜHE arvuti korral tunduvalt lihtsam, kuigi siin on ka piirid - väga keeruliste programmide puhul võib mingi käsurea võimalus olla tunduvalt lihtsam, kui ei tea kust kohast üles otsida mingi menüürida ja kusagile kastikesse sisse klõpsida linnukene.
Kui aga arvuteid on näiteks terve arvutiklassi jagu?
Hiirega klõpsimist on väga raske automatiseerida. PS võimaldab endiselt kasutada graafilisi kasutajaliideseid, aga iga liigutus selles liideses kajastub vastava käsuna PS-s ja seda tegevust saab automatiseerida.
Arvutiadministraatori kõige suuremad mured ei ole aga hiireklõpsu / käsurea võimalik kokkuhoid.
Mõnikord võib mingi tegevus minna valesti. Sel juhul aga tekib küsimus sellest, MIS võis minna valesti ja sellest peaks jääma jälg.
Käsurea tegevused on isedokumenteerivad ja tulemused saab salvestada.
Hiireklõpsu korral ekraanile ilmuv veateade on aga järgmine hetk haihtunud.
Mõned vead, tõsi, jõuavad Windowsi "Event logi". Sealt nende väljaotsimine on üsna tüütu.

Varem või hiljem jõuab iga ettevõte vajaduseni oma arvutialaseid nõudeid süstematiseerida ja dokumenteerida.
Hiireklõpsupõhises arvutimajanduses on see keerukas, nõudes sisuliselt topelttööd - teed kusagil klõpsu ja märgid kirja, kus see klõps tehti ja mis asjaoludel.
Korralike skriptide kasutamisel on olukord vähemalt ideaalis hallatav.
...

5. Aga miks PowerShell ?

Algselt tegeles ka Windowsi uut käsukesta arendav meeskond põhiliselt Unix kesta ümbertõstmisega Windows keskkonda. Tulemus ei olnud rahuldav,
Unixi kestad ei sobinud Windows API-dega ümberkäimiseks.
Ühes Snoveri presentatsiooni väidab viimane, et 4000000 $ kulus ära ideele Windows keskkonnas käima saada Unixi kest (ksh oli eeskujuks).
Seejärel kulus 60000 $ ideele arendada välja käsud WMI-ga ümberkäimiseks. Ja siis, ühel jõulupuhkuse ajal kirjutas Snover PowerShelli prototüübi.
Seejärel Monaadi manifesti. Palju edasi PS arendusele on kulunud, jääb saladuseks, aga sellest hetkest hakkasid asjad soovitavas suunas liikuma...
Ja nüüd, 2015 oleme siis niikaugel, et Windows arvutile saab ette kirjutada, mis konfiguratsiooni peab see saavutama...

VBS ja JScript aga olid süsteemiadministraatori jaoks samuti liiga kohmakad, kuigi olid (ja on tänini) kasutusel.
Aga ikkagi, miks Unix sh ei sobinud?
Näiteks:
A:
oskavad UNIX programmid edastada järgmisele konveierilülile vaid struktueerimata teksti- või baidivoogu.
Kes ei tea - konveier (pipe) võimaldab ühe programmi väljundit suunata teise programmi sisendiks. Konveieri leiutamine ise oli kindlasti suurepärane idee ja ajaproovile igati vastu pidanud.
Ainult et selle realiseerimine Unixi kestas ei ole olnud kõige õnnestunum.
Windows enda cmd-kestast ei maksa siin rääkidagi.
konveieri kahe programmi vahelises ühenduses kasutatakse informatsiooni edastamiseks struktueerimata teksti, mida iga käsu sisendis tuleb uuesti läbi sõeluda (parse).
Snoveril on selle kohta termin "prayer based parsing", "palveta ja sõelu".
Parem oleks ehk süüa, palvetada ja armastada tühja tähja sõelumise asemel?
Et Unixis nii palju kasutatakse konveierit, on osalt tingitud sellest, et Unixi töövahendid ei tee alati seda, mis nõutud.
Ühes töövahendis on peaaegu alati koos 3 tegevust - objektide kokkukorjamine, objektide töötlemine ning seejärel tulemuste väljastamine tekstina.
Kuid midagi ei toimi nii, nagu tahetakse, tuleb kasutada konveierit ja pooleliolev töö edastada järgmisele lülile, mis sellest tekstist võiks jälle üritada kätte saada infot objektide kohta.
Alati see ei õnnestu, administraator peab täpselt teadma ja ette andma näiteks veeru numbri, kus peidab ennast käsu ls puhul faili suurus ...
Näide - siin prindime välja faili nime ja suuruse. Maagilised numbrid on 9 ja 5.
ls -l | awk '{print $9 "   " $5 }'

PS asendas selle parandamiseks tekstilise sisendi/väljundi objektidega..
Programmi muutujad on tegelikult .NET / WMI ... objektid, mis on PS enda objektideks ümber lõigatud / adapteeritud objektide kogumid.
Alles konveieri lõppfaasis vormindatakse tulemid.

B: UNIX (aga ka DOS) kestade töövahendite nimetamises-käitlemises puudub süsteem.

Põgus tutvus Unixiga näitab, et kesta kasutaja peab meeles pidama rohkesti mnemoonilisi kahe-kolmetähelisi lühendeid (sed, awk, ls, rm. cp, mv...), mis on sellised peamiselt ajaloolistel põhjustel....
Vist ei mõtle väga välja loogikat lühendi grep desifreerimiseks?
PS asendas selle segadiku pisut parema tegusõna-nimisõna süsteemis käsustikuga.
Käsklusi on endiselt palju, aga selles on nüüd mingi süsteemi alged.
Kui objekte on vaja kokku koguda, siis algab käsk tegusõnaga get:
Get-Eventlog näiteks ...

PS skriptide tegemisel tuleks lähtuda kahest stiilist. Lihtsates testskriptides või PS käsureal toimetades, mis ei ole ette nähtud pikaajaliseks korduvaks kasutuseks, neis kasutage aliaseid (Unix stiil, mida lühem, seda uhkem).
Kui aga skriptist tõotab tulla midagi, mida saab ka edaspidi kasutada, kirjutage oma tekst üles pikemas ja loetavamas kirjaviisis, loopides igal juhul välja iseenda poolt defineeritud aliased j.m.s...
mis ei pruugi olla arusaadavad neile, kes peavad neid skripte käitama / lugema. Siis sobib suurepäraselt tegusõna-nimisõna süsteem.
Isegi omadefineeritud skriptide -funktsioonide jaoks võiks üritada kasutada sellist nimetamissüsteemi.

C: Käskude (cmdlet PS-s) parameetrite käitlemine ei ole Unixis ega DOS-s olnud ühtne.
Eriti hull anarhia valitseb bat keele käskude parameetrite käitlemisel, kus pole isegi kunagi selge, kus algab üks parameeter ja lõpeb teine, või koguni kus lõpeb üks käsk ja algab teine...
...
D ---Z  ja nii edasi ...

PS parandas neid varasemate OS kestade skriptimiskeelte puudusi märkimisväärselt. Objektorienteeritus,  kus käskude sisendid ja väljundid on objektid või objektide kogumid on nendest muutustest kõige olulisem.

 6. PS alustused

Minul (hetkel) käsutuses olev üks uunikumarvuti sisaldas XP, seetõttu ma siin ei juhata sisse ja pole  väga uurinud uusimaid vidinaid ja vilesid. Alustuseks ehk ei olegi see vajalik ja kui PS skripte on vaja käivitada-kasutada väga mitmekesises arvutipargis, võib harjumus kasutada PS moodsaimat versiooni lausa segada. Miinimum PS õppimisel on siiski PS v2, täpselt see, mida eeldab evangeelne "Windows Power Shell in action".

6A.  PS versioon

Tippige W7 vasakul allnurgas oleval käsureale real sisse powershell / või käivitage mingil muul viisil PS. XP puhul on vaja teha lisaprotseduure, ajapuudusel jätan detailid välja, W 8.0/8.1 ja 10 ning igasuguste serverite variantide puhul käivitusvariandid erinevad...
Tähetõstuprobleemid W-s puuduvad, aga süsteemsuse mõttes formaadin edaspidi oma näited viisakamaks, et skriptimise puhul asjad kenamad välja näeksid. Tegelikult ei ole vahet, kuidas tippida, ka PowerShell, POWERshell viivad sihile.
$psversiontable peab ütlema numbri, mis peab olema  >=2.0
perfektsionistid tippigu
$psversiontable.psversion
siis saab kätte ainult versioonihalduse numbrid (Major.Minor.Build.Revision) ja pääsete ülejäänust.
XP-l  peab PS käimahakkamiseks (kindlasti olgu v2) veidi vaeva nägema.
Märkusena
$ tähistab muutujanime algust, mis on kas objekt või objektikogum (collection). Muutujanime tippimine toob ekraanile selle sisust ühte teist, mida PS loojad peavad oluliseks, kuid vajadusel saab muutuja sisust kogu informatsiooni kätte.

6B. Hello, World! lause käsurealt:

Õnnetuseks ei ole Hello world tegemiseks peaaegu üldse vaja midagi õppida. Tuleb käsureale lüüa
"Hello, World!"
Saate Hello, World! ilma jutumärkideta (erinevalt DOS-st).

Teadjamad näevad siin, et lõpuks ometi on MS-s aru saadud, et kuidagi tuleb sõnesid eraldada. Nagu Unix-is, on siin 2 võimalust - kahekordsed ja ühekordsed jutumärgid. 
Nagu Unix-is asendatakse kahekordsete jutumärkide vahel oleva sõne sees muutujat tähistavad sõned muutuja sisuga, s.t. sõnesid interpoleeritakse. Lisaks muutujate asendamisele toimub veel erimärkide asendamine.

Ärge aga kihutage siit kiirelt üle, sest teid ootab ees üllatusmuna MS-lt. Tõtt öelda põhjendatult.
Paosümboliks on PS-is mitte langujoon, vaid backtick, kaldkoma.
Kaldkoma on minu leiutatud termin. Ülakoma juba on, miks mitte igasugustele komadele seltsiks lisada kaldkoma.
Kaldkoma ehk backtick-i  leiab üles inglise klaviatuuri puhul Esc sümboli all, Eesti klaviatuuripaigutuse korral backspace kõrvalt, shift klahvi kasutades.
Unix-is tähistab kaldkomade vahele asetatud sõne käsku, mis tuleb täita ja siis samasse kohta tagasi kirjutada.

Allpool ad nauseam näiteid hallotamisest:

PS C:\bat\power> 'hello world!'
hello world!
PS C:\bat\power> "Hello, World!"
Hello, World!
PS C:\bat\power> $Hello = "Hallo"
PS C:\bat\power> $World = "Maailm"
PS C:\bat\power> "$Hello, $World!"
Hallo, Maailm!
PS C:\bat\power> '$Hello, $World!'
$Hello, $World!

Kaldkoma aga päästab ka dollarimärgi eritähendusest. 

PS C:\bat\power> "`$Hello, `$World!"
$Hello, $World!

Topeltjutumärkide vahel saadakse aru reavahetusest, tabulaatorist jpm, 
Ühekordsete jutumärkide vahel neid asju ei interpoleerita.

PS C:\bat\power> "Hello,`nWorld"
Hello,
World
PS C:\bat\power> 'Hello,`nWorld'
Hello,`nWorld

Mõnikord tasuks sõnede sees täita mingi käsk ja tulemus istutada selle sõne sisse.
Proovime.
Kõigepealt õpiks ära mõne kasuliku käsu.
Enamike õppetekstide arvates õppur ei oma aimu hetke kuupäevast. Nii arvan ka mina.
Get-Date tagastab kuupäeva-kellaaega sisaldava objekti.
PS C:\bat\power> Get-Date

13. detsember 2015. a. 18:37:09

Seejärel saab sellest objektist kätte aastaarvu, pannes esimese operatsiooni sulgudesse ja seejärel saadud tulemusobjektist leides omaduse .year

PS C:\bat\power> (Get-Date).year
2015

Sõne  sisse istutame selle tulemuse  $(... ) operatsiooni abiga.

PS C:\bat\power> "Hello, World, anno $((Get-Date).year)"
Hello, World, anno 2015

Miks kaldkoma langujoone asemel paosümboliks sai on üsna mõistetav, sest MS-s on sama sümbol ka katalooginimede eraldajaks ja selle kasutamine paosümbolina oleks tekitanud suurt segadust.
Seevastu võite kasutada kataloogides navigeerimisel nii kaldkriipsu kui langujoont, ‘/’ või ‘\’
sümbolit, vahet ei ole.

6C. Hello, World! programm

Tõsisema PS huvi korral installeerige arvutisse Notepad++ (sobib väga hästi paljude teiste programmeerimiskeelte jaoks), seejärel aga hakake uurima PS ISE võimalusi, praegu võib piirduda notepad-ga, nii et
notepad helloworld.ps1
koos sinna kirjutatud programmitekstiga
"Hello, World!"
on täiesti piisav hakatuseks.
Kui nüüd PS käsurealt tippida helloworld, võiksite maailmatervitust näha.
Aga võta näpust.
PS aga soovitab selle asemele   .\helloworld –i.
Ka Unix-is on nii, ei maksa nördida ja PS on selle Unix-ilt üle võtnud.

Vaid $env:PATH –s sisalduvates kataloogides olevaid programme saab PS-s kasutada ilma rajata käitatava programmi juurde. Ülejäänud programme tõmmatakse käima kas täisnime kasutades (pikk tee C:/..) või siis lühikest, relatiivset teed kasutades, jooksva kataloogi puhul on kataloogi tähiseks ’.’
Tööarvutites,kus ei ole vaja PS skripte kirjutada, vaid ainult täita, nii peakski jääma. Arvutis, kus oleks ehk vaja kirjutada rohkesti PS skripte. tuleks lisada PATH keskkonnamuutujale ’.’, seda PATH lõppu, mitte algusesse. Siis ei hakata näiteks dir käsklust kohe otsma sellest kataloogist, kus asutakse, vaid PATH kataloogidest ja kurikaeltel on vaja rohkem vaeva näha, et teie arvuteid kahjustada...

Alustuseks, sellega harjumise (ja poliitilise korrektsuse) mõttes, jätkame endist viisi. Kui satute Linux maailma, võib sellest harjumusest olla kasu. Ja jumala eest, ärge rääkige seal kellelegi, et olete ka seal oma PATH muutuja ära sättinud nii, et oleks nagu Windows-s!
MS enda puhul hm on selline turvalisus võrreldav olukorraga I korrusel elades, kus uks on lukustatud, aken aga on pärani lahti. Sest .bat käsuaknas ei nõua keegi selliste formaalsuste täitmist.
Edaspidi näete veel ühte sellist tüütust – ps1 laiendiga programmid ei hakka automaatselt tööle (ja .cmd/.bat laiendiga hakkavad, nagu need oleksid mingid ohutuse etalonid).

Nii et meie praeguses kataloogis olevat helloworldi programmi võiks käivitada käsk
./helloworld (või .\helloworld, kui olete MS langujoonega harjunud. IMHO on jagamismärgi kasutamine mugavam).
Uus üllatusmuna -  PS1 programm vaikimisi käima ei lähe.
Järjekordne tüütus ps1 kasutamise teel: ps1 vaikimisi poliitika keelab ps1 skriptide täitmise...

PS C:\bat\power> ./helloworld
File C:\bat\power\helloworld.ps1 cannot be loaded because the execution of scripts is disabled on this system. Please s
ee "get-help about_signing" for more details.
At line:1 char:13
+ ./helloworld <<<<
    + CategoryInfo          : NotSpecified: (:) [], PSSecurityException
    + FullyQualifiedErrorId : RuntimeException

PS1-ga tutvumise algfaasis ei maksa lasta ennast heidutada. MS lihtsalt siin tahab näidata oma vägevust – vaikimisi ps1 käivitamise rezhiim on selline, et ps1 skripte üleüldse käivitada ei saa.
( restricted). Samal ajal igasuguste .reg, .inf failide, .cmd skriptide ja .bat skriptide käivitamine suvalistel masinatel on täiesti OK ja süsadmin peaks kõvasti vaeva nägema, et nii ei oleks. Tavaliselt pole tal selleks mahti.
Selle saladusliku executionpolicy saab kätte käsuga Get-Executionpolicy-ga:

PS C:\bat\power> get-executionpolicy
Restricted
Muutke see admin õigustes olles ära, abi saab
help set-executionpolicy –ga võimalike väärtuste jaoks.

PS C:\bat\power> set-executionpolicy remotesigned

Execution Policy Change
The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose
you to the security risks described in the about_Execution_Policies help topic. Do you want to change the execution
policy?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"): y

Remotesigned tähendab, et allalaaditud skripte niisama käima ei saa. Sihukene formaalne luud uksel ees...
Puhh.
Nüüd on suur töö tehtud ja  ./helloworld  läheb käima.

PS C:\bat\power> ./helloworld
Hello, World!
Teinekord, kui käsu sisu selge, kasutage võtit –force, et tüütust dialoogispämmist pääseda.

PS C:\bat\power> set-executionpolicy -force restricted
PS C:\bat\power> set-executionpolicy -force remotesigned
PS C:\bat\power>


6D: Kuidas vanaviisi jätkata: Get-Alias

Õnneks ei pea PS uurimisel kõike uuesti õppima.

Kui on meeles DOS või bash mõned käsud, võib neid kohe proovima hakata.
Enamasti on need olemas (copy, mv, cp, cd, pwd, dir ...). Seda saab kontrollida aga
Get-Alias / või lühemalt Alias käsuga.
Kõigepealt kasutage help käsku (mis tegelikult on lühend või alias Get-Help käsule).
Seda on vaja kasvõi selleks, et teada saada käsu õige nimi ning seejärel selleks,
et mõista PS / bash / DOS käsitluste erinevusi.
Näiteks tahate teada, mis käsk on dir analoog:

PS C:\bat\power> help dir

NAME
    Get-ChildItem

SYNOPSIS
    Gets the items and child items in one or more specified locations.

....

Help-i edasilugemisel selgub, et dir käsku õige nimega Get-ChildItem
saab rakendada mitte ainult failisüsteemis olevate failide sirvimiseks, vaid igasuguste
pakkujate / providers puhul.

Võib tekkida küsimus, et mis asi on provider? Ärge jookske kohe internetti guugeldama, kuigi ka nii võib.
Nagu Linuxis, on ka PS-s korralikud abitekstid enamasti olemas.
Nagu Linux-is, on ka PS abitekstid kohati  krüptilised, kuid umbes 3-ndal lugemisel juba mõistetavad. Nagu Linuxis ärge eeldage, et saate abitekstidest 1-l katsel jagu. Erinevalt Linux-ist saate abitekstidest mõnikord juba 3-ndal katsel jagu.
Siin aitab kõigepealt
PS C:\bat\power> help about

Name                              Category  Synopsis
----                              --------  --------
about_aliases                     HelpFile  Describes how to use alternate names for cmdlets and commands in Windows
about_Arithmetic_Operators        HelpFile  Describes the operators that perform arithmetic in Windows PowerShell.
about_arrays                      HelpFile  Describes a compact data structure for storing data elements.
..........
................................
 sealt leiate ka teema provider-ite kohta:

PS C:\bat\power> help about_providers
TOPIC
    about_Providers
........
..............

 BUILT-IN PROVIDERS
    Windows PowerShell includes a set of built-in providers that you can use
    to access the different types of data stores.


    Provider      Drive         Data store
    --------      -----         ----------
    Alias         Alias:        Windows PowerShell aliases

  Certificate   Cert:         x509 certificates for digital signatures

    Environment   Env:          Windows environment variables

    FileSystem    *             File system drives, directories, and files

    Function      Function:     Windows PowerShell functions

    Registry      HKLM:, HKCU   Windows registry

    Variable      Variable:     Windows PowerShell variables

    WS-Management WSMan         WS-Management configuration information

   * The FileSystem drives vary on each system.

Näiteks Env: draiv sisaldab tegelikult windows keskkonnamuutujaid, mis peaksid olema tuttavad juba DOS-st.

PS C:\bat\power>  dir env:

Name                           Value
----                           -----
ALLUSERSPROFILE                C:\ProgramData
..........................................................................................
.............................<spam spam spam> ........................

Variable: draiv sisaldab muutujaid.
PS-s on muidugi palju sisseehitatud muutujaid.
Tekitame muutuja $hello ja vaatame kas ta on Variable: draivil olemas:

PS C:\bat\power> $hello="hallo"
PS C:\bat\power> dir Variable:hello

Name                           Value
----                           -----
hello                          hallo

6E Ja nüüd: VETTE!

Proovin nüüd lõpuks talitada oma sõnade järgi. Ükskõik mis keelt saab rääkima õppida rääkides, programmeerimiskeelt õppida saab programmeerides. Kesktee foo-bar näidete ja reaalse elu näidete vahel on ehk mingid „programmeerimise ülesannete kogud”. Üks selline on ka Eestis väljastatud -
"Programmeerimise eksamiülesannete kogu", Tartu 2007,
autoreiks Helle Hein, Jüri Kiho, Reimo Palm, Eno Tõnisson.

Võtan siit ühe näite, mille varalt saab läbi kapata mõned põhilised konstruktsioonid PS-s.
Edaspidigi kasutan sealt näiteid (ka omale näpuharjutuseks).

Ülesanne ja programmitekst
(mis ei pretendeeri mitte mingis mõttes mingi õppeteksti või etaloni tiitlile, kuid mis siiski peaks töötama).

# Programmeerimise eksamiülesannete kogu 1
# On antud täisarvujärjendid poisid.txt ja tydrukud.txt, olgu näiteks arvud antud komadega eraldatuna,
# Moodustada tantsupaarid kõige pikem poiss kõige pikema tüdrukuga etc...
# Kui sugude vahel valitseb arvuline ebavõrdsus, jäävad kõige pikemad poisid või tüdrukuid paariliseta.
# Väljastada lähteandmed, tantsupaarid ja paariliseta jäänud poiste või tüdrukute pikkused.

$poisidAndmed = Get-Content "poisid.txt"
$tydrukudAndmed = Get-Content "tydrukud.txt"
"Poiste pikkused:"
$poisidAndmed
"Tüdrukute pikkused:"
$tydrukudAndmed
$poisid = $poisidAndmed -split "," | sort -descending
$tydrukud = $tydrukudAndmed -split "," | sort -descending

$diff = $poisid.count - $tydrukud.count
if ($diff -gt 0) 
   {
     $pyle = $poisid[0..($diff -1)]
             $poisid = $poisid[($diff)..($poisid.count - 1)];
             }
 elseif ($diff -lt 0) 
   {
   
     $tyle = $tydrukud[0..(-$diff -1)]
             $tydrukud = $tydrukud[(-$diff)..($tydrukud.count - 1)];
   }
# Paarid
$paarid = 0..($poisid.count -1)
foreach ($i in $paarid) {$paarid[$i] = "(" + $poisid[$i] + ", " + $tydrukud[$i]+")"}     
# Väljastus:
"Tantsupaarid on:"
$paarid -join " "
if ($diff -gt 0)
 {
 "Paarilisteta jäid poisid pikkustega"
 $pyle -join ", "
 }
 elseif ($diff -lt 0)
 {
 "Paarilisteta jäid tüdrukud pikkustega"
 $tyle -join ", "
 }


 Märkusi:

E1.
$poisidAndmed = Get-Content "poisid.txt"
Muutuja tunnus on dollar, nagu näiteks ka bashis, mida ehk natuke võiks pidada PS eellaseks.
Nagu skriptivates keeltes ikka, võib muutuja sisu olla suvaline ja seda ei pea ette teadma, mis sorti see võiks olla.
Muutuja võib sisaldada ühte või mitut objekti. Mitut objekti sisaldavad muutujad on kas paisktabelid, sõnastikud  (hash table, dictionary), ühe indeksi järgi saab leida objekti, mis selle indeksi taga peitub, või massiivid (array). Massiivide indeksiks on täisarv ja indekseerimine algab 0-st.
Get-Content loeb faili sisu (ekraanile või muutujasse) – DOS type analoog ning käsk omabki aliast type.
KUI failis on üks rida, siis sisaldab muutuja ainsa objektina seda rida ja ei ole massiiv.
Kui failis on mitu rida, siis tekib massiiv. Olgu failis tekst.txt mitu rida.
$tekst = type tekst.txt  
Nüüd faili esimene rida on $tekst[0], teine rida $tekst[1]etc
NB PS kari!
KUI on aga ainult üks rida, siis massiivi ei teki, ja $tekst[0] on selle faili ainsa rea esimene täht!
See ongi praegu just nii, ülesande lihtsuse tõttu ongi vaid üks rida andmeid (pikkused).
Korralikumas programmis, kus ette ei või teada, on seal null, üks või mitu rida, tuleb tulem ümber lõigata massiiviks. Massiiviks ümberlõikamise operaator on
 @()
Peaaegu alati (see ülesanne ehk on erand) tasub faili lugemist teha nii:

$poisid = @(type poisid.txt)

Nüüd $poisid.count / või $poisid.length  , vastavalt maitsele on faili ridade arv. See on ka nii siis, kui failis pole ühtegi rida.
Näide, mis võiks veenda, et ka tühja faili ridade arvu näidatakse korrektselt:
(format-custom (fc) siin formaadib tühjust ja suunab väljundi ümber faili)
Touch PS-s ei toimi.

PS C:\bat\power\PROGYL>  fc >proov.txt
PS C:\bat\power\PROGYL> $proov = @(type proov.txt)
PS C:\bat\power\PROGYL> $proov.count
0

Küllaltki tõenäoliselt langete siin programmeerijate hierarhias kategooriasse 'F', nagu minagi, kellel tuli selle teadasaamiseks see viga läbi teha (kuigi manuaalis oli ju kõik kirjas, oops).

E2. $poisidAndmed
väljastab muutuja sisu ekraanile, ei pea echo-tama, nagu DOS-s.
>, >> ümbersuunamise operaatorid toimivad nagu alati, kõik saab ümber suunata faili.
(Allpool sellest  veel -gt operaatori juures, mis ehk natukene selgitab > ja < operaatorite mittetoimimist tavalistes avaldistes)

E3.
$poisid = $poisidAndmed -split "," | sort -descending
-split jagab sõne massiiviks, siin on eraldajaks koma. Muuseas, alati on tulemus massiiv erinevalt Get-Content karist. Seda ka siis, kui sõne sees koma ei olegi, siis on massiivis üks element.
-join teeb vastupidist, leiate programmi lõpus ka seda kasutava rea.

E4. if ($diff -gt 0)

<> märke võrldusoperatsioonides PS ei tunnista. Põhjuseks on nende sümbolite kasutamine PS-s ümbersuunamistel.
Õnneks on loobutud MS täiesti iseäralikest operaatoritest DOS puhul ning kasutatakse samu operaatoreid, mis näiteks Perlis ka toimivid.
Niisiis:
- eq             on võrdne
 -ne            ei ole võrdne
 -ge            suurem võrdne
 -gt            suurem kui
 -lt            vähem kui
 -le            vähem või võrdne

Neid operaatoreid on veel, aga praeguseks piisab. Kui operaatoritele ette kirjutada c, siis on võrdlused sõnede puhul
tõstutundetud, i ette kirjutamine ei muuda (s.t. võrdlus on tõstutundetu, aga perfektsionistid eelistavad täpset kirjaviisi, siis peaks olema selgem, et võrdlus ei arvesta tähe tõstu.
Probleemiks nende võrdluste puhul on see, et need on jälle üldisest süsteemist väljas. Aga kesta skriptivate keelte puhul ongi asjad tavaliselt isemoodi. Võrreldes DOS-ga asjad vähemalt toimivad.

E5. Tüübid

Õige on programmis teha nii:

[int[]] $poisid = [int[]] ($poisidAndmed -split ",") | sort -descending
[int[]] $tydrukud = [int[]] ($tydrukudAndmed -split ",") | sort -descending

Tähelepanelik lugeja kindlasti märkas, et võrdlustes ei olnud mingit juttu tüüpidest. Selline lohakas stiil skriptimisel ei ole siiski väga shokeeriv. Kui väga ei ole vaja, tüüpidega ei armastata jahmerdada.
Õigem siiski oleks see asi korda panna. Üleval olen $poisid massiivi jaoks selgeks teinud, et need ON täisarvud. Seda, et tegemist on massiiviga ütleb [].
Ka vahepealses operatsioonis, kus sisendandmeid tuli alles massiiviks jagada, tuleb enne sortimist öelda, et sordi täisarve, mitte näiteks sõnesid, mis annavad valed tulemid.
PS enamasti üritab aru saada, mida programmi looja tahab, aga ta ei saa alati aru. Ja tüübi määratlemine ütleb vaid seda, et omistuse järel üritatakse vastav tüübiteisendus ära teha. Kui see ei õnnestu, tulevad veateated. Aga näiteks
int tüüpi muutujale omistada väärtus '012' ei ole mingi probleem, sellest saab vaikimisi arv 12.

Võrdlustes aga teisendatakse enne võrdlust tüübid ära.
Kui tüübid on võrdluses erinevad, määrab tüübiteisenduse ESIMENE operand.
Nii et kui kogemata on esimene operand arvu 12 asemel '12' (see ütleb selgelt, et siin ON sõne), siis teine operand lõigutakse ümber sõneks ja võrreldakse sõnesid.


E6. If üldkuju:

if ()
{}
elseif
{} …
else
{}
{} tähistab käsuplokki. Loogelised sulud peavad if järel olema. Nii ei saa, et if järel tuleb üks avaldis ilma looksulgudeta.  Ka see avaldis peab olema loogeliste sulgudega ümbritsetud.

E7. Massiivide tekitamine ja massiividest elementide võtmine indeksioperatsioonide abiga.

Vaatleme programmis ettetulnud lauseid, kus massiividega opereerimine käib:
  $pyle = $poisid[0..($diff -1)]
 $poisid = $poisid[($diff)..($poisid.count - 1)];

 $tyle = $tydrukud[0..(-$diff -1)]
 $tydrukud = $tydrukud[(-$diff)..($tydrukud.count - 1)];

# Paarid
$paarid = 0..($poisid.count -1)

Alustaksin lõpust:
K..N operatsioon tekitab PS-s täisarvude massiivi, kus esimene element on K ja viimane N.
Praegu on see rida lihtsalt paaride massiiv initsialiseerimiseks ja väga mugav oli sinna lihtsalt kirjutada juba ette indeksid.

 [] sisse kirjutatakse massiivi indeksid, et vastavaid elemente kätte saada. Neid võib olla mitu. Indeksid võivad ise moodustada massiivi. Millegipärast massiivi lõikumine väiksemaks toimib just nii (ei ole paremat meetodit).
$poisid = $poisid[($diff)..($poisid.count - 1)];
Sama trikiga tuleb massiivist elemente välja loopida, kopeerides vaid need elemendid, mida vaja.

$hei =@()
teeb massiivi tühjaks.
Nüüd
PS C:\bat\power> $hei[0]=5
Array assignment failed because index '0' was out of range.
At line:1 char:6
+ $hei[ <<<< 0]=5
    + CategoryInfo          : InvalidOperation: (0:Int32) [], RuntimeException
    + FullyQualifiedErrorId : IndexOutOfRange
annab veateate.
Väljastada massiivi piiridest väljas elemente saab (väljastatakse tühi väärtus
$NULL )

Indeksid võivad olla ka negatiivsed, siis käib loendamine lõpust, -1 on viimane element.
Seetõttu tüdrukute massiivi indeksi negatiivse väärtuse korral võib saada ootamatuid tulemeid, mitte veateate massiivi piiride ületamise kohta.
Silumise käigus juhtus see, et muutuja $diff jäi negatiivseks ja sain imelikud tulemid.

Vahemiku (range) operaator K..N ei ole siiski kõige parem meetod massiivi lihtsaks initsialiseerimiseks.
Kuid veel hullem meetod oleks alata tühjast massiivist ja siis elemente juurde liita.
Näiteks:
PS C:\bat\power\progyl> $hei=@()
PS C:\bat\power\progyl> $hei +="hoi"
PS C:\bat\power\progyl> $hei += (1,2,3)
PS C:\bat\power\progyl> $hei
hoi
1
2
3
See töötab väikeste massiivide jaoks, aga suurte massiivide puhul peab arvestama, et IGA elemendi liitmise korral tehakse massiivist uus koopia ja see on tohutult ebaefektiivne.
Jälle üks väike kivi PS kapsaaeda (mis õnneks ei tee asju siiski võimatuks, aga neid on vaja teada).

Nii et kui massiivi mõõtmed on ette teada (ja kui ka ei ole, aga maks mõõde on teada), initsialiseerige massiiv ära ja ärge kasutage tsüklites massiivide liitmist või massiividele elementide liitmist.
Parimat meetodit massivi alginitsialiseerimiseks vaatan allpool, kui foreach tsükli asendame parema variandiga (selle ülesande puhul).

E7.  Foreach ja for tsükkel

# Paarid
$paarid = 0..($poisid.count -1)
foreach ($i in $paarid) {$paarid[$i] = "(" + $poisid[$i] + ", " + $tydrukud[$i]+")"}     

Foreach tsükkel on üsna isedokumenteeriv - $i käib läbi kõik $paarid väärtused. See on sageli mugavam, kui ise õiendada tsüklimuutujatega ja neile ühte juurde liita.
Tsükli kiiruse mõttes ei ole siiski nii praegu kõige prem.
$paarid võiks lihtsalt initsialiseerida ühe väärtusega ja kasutada for tsüklit.
Õigem oleks nende 2 rea asemel kirjutada:

$paarid = @("") * ($poisid.count)
for ($i=0 ; $i -lt $poisid.count; $i++)
{ $paarid[$i] = "(" + $poisid[$i] + ", " + $tydrukud[$i]+")"}     

For tsükli 3  osa on alginitsialiseerimine ($i saab 0 –ks), tsükli jätkamise tingmus ning tsükli lõpu /uue alustuse eelne operatsioon, mis tavaliselt liidab  $i-le 1 juurde.
.....
Mitu liigutust on juures, tsükliloendur, mida foreachis pole vaja, tuleb algväärtustada, üks juurde liita, kontrollida piire.

PUHH. Selleks pühapäevaks aitab. 
PS -st aga veel isu täis saanud ei ole (erinevalt DOS-st), nii et jätkan millalgi.