Kako koristiti skupnu datoteku za lakše pokretanje PowerShell skripti
Iz nekoliko razloga, uglavnom vezanih uz sigurnost, PowerShell skripte nisu tako lako prenosive i upotrebljive kao što batch skripte mogu biti. Međutim, možemo povezati skriptu za batch s našim PowerShell skriptama za rješavanje tih problema. Ovdje ćemo vam pokazati neka od tih problematičnih područja i kako izgraditi skupni skript koji ih zaobilazi.
Zašto ne mogu jednostavno kopirati datoteku .PS1 na drugo računalo i pokrenuti ga?
Ako ciljni sustav nije unaprijed konfiguriran da bi omogućio pokretanje proizvoljnih skripti, s potrebnim povlasticama i korištenjem ispravnih postavki, vjerojatno ćete naići na neke probleme kada pokušate to učiniti.
- PowerShell po defaultu nije povezan s ekstenzijom .PS1 datoteke.
To smo na početku izneli u seriji PowerShell Geek School. Windows privremeno povezuje datoteke .PS1 s Notepadom, umjesto da ih šalje na tumač naredbi PowerShell. Time se sprječava slučajno izvršavanje zlonamjernih skripti jednostavnim dvostrukim klikom na njih. Postoje načini na koje možete promijeniti ovo ponašanje, ali to vjerojatno nije nešto što želite učiniti na svakom računalu na kojem nosite svoje skripte - osobito ako neka od tih računala nisu vaša. - PowerShell ne dopušta vanjsko izvođenje skripte prema zadanim postavkama.
Postavka ExecutionPolicy u programu PowerShell sprječava izvođenje vanjskih skripti prema zadanim postavkama u svim verzijama sustava Windows. U nekim verzijama sustava Windows, zadana vrijednost uopće ne dopušta izvođenje skripte. Pokazali smo vam kako promijeniti ovu postavku u Kako dopustiti izvršavanje skripti PowerShell u sustavu Windows 7. Međutim, to je nešto što ne želite raditi na bilo kojem računalu. - Neka PowerShell skripta neće raditi bez administratorskih dozvola.
Čak i ako imate administratorski račun na razini administratora, morate proći kroz kontrolu korisničkih računa (UAC) kako biste izvršili određene radnje. Ne želimo to onemogućiti, ali je još uvijek lijepo kada se možemo lakše nositi s tim. - Neki korisnici mogu imati prilagođena PowerShell okruženja.
Vjerojatno se nećete često susresti s tim, ali kada to učinite, pokretanje i rješavanje problema skripte će vam možda biti frustrirajuće. Srećom, to možemo zaobići bez trajnih promjena.
Korak 1: Dvaput kliknite za pokretanje.
Počnimo s rješavanjem prvog problema - .PS1 pridruživanja datoteka. Ne možete dvaput kliknuti da biste pokrenuli .PS1 datoteke, ali tako možete izvršiti .BAT datoteku. Tako ćemo napisati batch datoteku kako bismo pozvali PowerShell skriptu iz naredbenog retka za nas.
Stoga ne moramo ponovno pisati datoteku skupne obrade za svaku skriptu, ili svaki put kad pomičemo skriptu, koristit će se samo-referenciranu varijablu za izgradnju putanje datoteke za PowerShell skriptu. Da bi ovo funkcioniralo, skupna datoteka morat će se smjestiti u istu mapu s vašim PowerShell skriptom i imati isto ime datoteke. Dakle, ako se vaša PowerShell skripta naziva "MyScript.ps1", poželjet ćete imenovati datoteku "MyScript.bat" i provjeriti je li ona u istoj mapi. Zatim stavite ove retke u skriptu paketa:
@ECHO OFF PowerShell.exe -Upravljanje "&"% ~ dpn0.ps1 "PAUZA
Da nije bilo drugih sigurnosnih ograničenja, to bi zapravo bilo sve što je potrebno za pokretanje PowerShell skripte iz skupne datoteke. Zapravo, prvi i zadnji red su uglavnom samo pitanje preferencija - to je druga linija koja stvarno radi. Evo razdvajanja:
@ECHO OFF isključuje odjek naredbe. Ovo samo čuva vaše ostale naredbe od prikazivanja na zaslonu kada se pokrene skupna datoteka. Ova linija je sama skrivena korištenjem simbola at (@) ispred njega.
PowerShell.exe -Command "&"% ~ dpn0.ps1 "" zapravo pokreće skriptu PowerShell. PowerShell.exe može, naravno, biti pozvan iz bilo kojeg CMD prozora ili batch datoteke da pokrene PowerShell na golu konzolu kao i obično. Također ga možete koristiti za izvo enje naredbi izravno iz skupne datoteke, uključujući parametar -Command i odgovarajuće argumente. Način na koji se to koristi za ciljanje naše .PS1 datoteke je s posebnim% ~ dpn0 varijablom. Pokreni iz skupne datoteke,% ~ dpn0 procjenjuje na slovo pogona, putanju mape i naziv datoteke (bez ekstenzije) skupne datoteke. Budući da će batch datoteka i PowerShell skripta biti u istoj mapi i imat će isto ime,% ~ dpn0.ps1 će se prevesti na cijelu putanju datoteke PowerShell skripte.
PAUZA samo pauzira izvršenje serije i čeka korisnički unos. To je općenito korisno imati na kraju vaših skupnih datoteka, tako da imate priliku pregledati bilo koji izlaz naredbe prije nego što prozor nestane. Dok prolazimo kroz testiranje svakog koraka, korisnost ovoga će postati očitija.
Dakle, osnovna datoteka skupa je postavljena. U svrhu demonstracije, ova datoteka je spremljena kao "D: Skriptni laboratorij MyScript.bat" i tu je "MyScript.ps1" u istoj mapi. Pogledajmo što se događa kada dvaput kliknemo MyScript.bat.
Očito je da se PowerShell skripta nije pokrenula, ali to se i moglo očekivati - ipak smo riješili samo prvi od četiri problema. Međutim, ovdje su prikazani neki važni bitovi:
- Naslov prozora pokazuje da je serijski skript uspješno pokrenuo PowerShell.
- Prvi redak izlaza pokazuje da se koristi prilagođeni PowerShell profil. Ovo je potencijalni problem # 4, naveden gore.
- Poruka o pogrešci prikazuje ograničenja ExecutionPolicy na snazi. To je naš problem # 2.
- Podvučeni dio poruke o pogrešci (koji se provodi izvorno pomoću PowerShell-ovog izlaza pogreške) pokazuje da je batch skripta ispravno ciljala predviđenu PowerShell skriptu (D: Skriptni laboratorij MyScript.ps1). Tako barem znamo da mnogo toga radi ispravno.
Profil, u ovom slučaju, jednostavan je jednostruki skript koji se koristi za ovu demonstraciju kako bi generirao izlaz kad god je profil aktivan. Možete i prilagoditi svoj vlastiti profil PowerShell da biste to i učinili, ako želite sami testirati te skripte. Jednostavno dodajte sljedeći redak u skriptu profila:
Write-Output 'Custom PowerShell profil na snazi!'
ExecutionPolicy na testnom sustavu ovdje je postavljen na RemoteSigned. To omogućuje izvođenje skripti kreiranih lokalno (poput skripte profila), dok blokiraju skripte od vanjskih izvora, osim ako ih nije potpisalo ovlašteno tijelo. U svrhu demonstracije, sljedeća je naredba korištena za označavanje MyScript.ps1 kao vanjskog izvora:
Add-Content -Path 'D: Skriptni laboratorij MyScript.ps1' -Value "[ZoneTransfer] 'nZoneId = 3" -Stream' Zone.Identifier '
To postavlja alternativni tok podataka Zone.Identifier na MyScript.ps1, tako da će Windows misliti da je datoteka došla s Interneta. Može se jednostavno preokrenuti sljedećom naredbom:
Clear-Content -Path 'D: Skriptni laboratorij - MyScript.ps1' -Stream 'Zone.Identifier'
Korak 2: Dobivanje oko IzvršenjaPolitika.
Dobivanje oko postavke ExecutionPolicy, iz CMD-a ili skripte, zapravo je prilično jednostavno. Samo mijenjamo drugi redak skripte da bismo dodali još jedan parametar u naredbu PowerShell.exe.
PowerShell.exe -ExecutionPolicy Bypass -Command "&"% ~ dpn0.ps1 "
Parametar -ExecutionPolicy se može koristiti za izmjenu ExecutionPolicy koji se koristi kada se pojavljuje nova sesija PowerShell. To neće trajati i nakon te sesije, tako da možemo pokrenuti PowerShell ovako kad god nam zatreba, bez slabljenja općeg sigurnosnog položaja sustava. Sad kad smo to popravili, idemo još jednom na to:
Sada kada je skripta ispravno izvedena, možemo vidjeti što zapravo radi. To nas obavještava da pokrećemo skriptu kao ograničeni korisnik. Skriptu zapravo upravlja račun s administratorskim dozvolama, ali Kontrola korisničkih računa smeta. Iako pojedinosti o tome kako skripta provjerava je li administratorski pristup izvan opsega ovog članka, evo koda koji se koristi za demonstraciju:
if (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity] :: GetCurrent ()). IsInRole ([Security.Principal.WindowsBuiltInRole] "Administrator")) Write-Output 'Izvodi se kao administrator! Write-Output (Izlaz za pisanje) 'Running Limited!'
Također ćete primijetiti da sada postoje dvije operacije "Pauza" u izlazu skripte - jedna iz PowerShell skripte i jedna iz batch datoteke. Razlog za to će biti očitiji u sljedećem koraku.
Korak 3: Dobivanje pristupa administratora.
Ako vaša skripta ne pokreće naredbe za koje je potrebna nadmorska visina, a prilično ste sigurni da ne morate brinuti o tome kako vam netko smeta prilagođeni profili, možete preskočiti ostatak ovoga. Ako radite neke cmdletove na razini administratora, trebat će vam ovaj dio.
Nažalost, ne postoji način da se aktivira UAC za podizanje iz skupne datoteke ili CMD sesije. Međutim, PowerShell nam to omogućuje pomoću Start-Process. Kada se koristi s “-Verb RunAs” u svojim argumentima, Start-Process će pokušati pokrenuti aplikaciju s administratorskim dozvolama. Ako sesija PowerShell nije već povišena, to će potaknuti UAC prompt. Da bismo to koristili iz batch datoteke za pokretanje naše skripte, na kraju ćemo stvoriti dva PowerShell procesa - jedan za pokretanje Start-Process-a, a drugi za Start-Process, za pokretanje skripte. Drugi redak skupne datoteke treba promijeniti u ovo:
PowerShell.exe -Command "& Start-Process PowerShell.exe -AggumentList '-ExecutionPolicy obilazak -File" "% ~ dpn0.ps1" "' -Verb RunAs"
Kada se pokrene skupna datoteka, prvi redak izlaza koji ćemo vidjeti je iz skripte profila PowerShell. Zatim će se pojaviti UAC prompt kada Start-Process pokuša pokrenuti MyScript.ps1.
Nakon što kliknete UAC prompt, nova instanca PowerShell će se pojaviti. Budući da je ovo nova instanca, naravno, opet ćemo vidjeti obavijest skripte profila. Zatim se pokreće MyScript.ps1 i vidimo da smo doista u povišenoj sesiji.
I tu je razlog zašto imamo ovdje i dvije stanke. Ako ne za onu u skripti PowerShell, nikad ne bismo vidjeli izlaz skripte - prozor PowerShell bi se samo pojavio i nestao čim se skripta završi. I bez pauze u batch datoteci, ne bismo mogli vidjeti je li bilo kakvih pogrešaka pri pokretanju PowerShell-a na prvom mjestu..
Korak 4: Prijelaz na prilagođene profile PowerShell.
Da se sada riješimo te neugodne obavijesti o profilu, hoćemo li? Ovdje jedva da je čak i smetnja, ali ako korisnički profil PowerShell promijeni zadane postavke, varijable ili funkcije na način na koji možda niste predvidjeli svojim skriptom, oni mogu biti zaista problematični. Puno je jednostavnije pokrenuti skriptu bez profila, tako da ne morate brinuti o tome. Da bismo to učinili, samo još jednom moramo promijeniti drugi red batch datoteke:
PowerShell.exe -NoProfile -Command "& Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy obilazak -File" "% ~ dpn0.ps1" "' -Verb RunAs"
Dodavanje parametra -NoProfile u obje instance programa PowerShell koje pokreće skripta znači da će skripta korisničkog profila biti u potpunosti zaobiđena u oba koraka, a naša će se PowerShell skripta izvoditi u prilično predvidljivom, default okruženju. Ovdje možete vidjeti da ne postoji nikakvo upozorenje u bilo kojem od školjki.
Ako u PowerShell skripti ne trebate administratorska prava, a preskočili ste i korak 3, to možete učiniti bez druge instance programa PowerShell, a drugi redak datoteke skupa trebao bi izgledati ovako:
PowerShell.exe -NoProfile -IzradaPolitičkog zaobilaženja -Upravljanje "&"% ~ dpn0.ps1 ""
Izlaz će tada izgledati ovako:
(Naravno, za ne-administratorske skripte, u ovom trenutku možete i bez pauza na kraju skripte u vašoj PowerShell skripti, budući da je sve zarobljeno u istom prozoru konzole i tamo bi se zadržala pauza na kraju svejedno.
Dovršene skupne datoteke.
Ovisno o tome trebate li administratorske dozvole za svoju PowerShell skriptu (i ne biste ih trebali tražiti ako to ne učinite), konačna skupna datoteka trebala bi izgledati kao jedna od dvije ispod.
Bez administrativnog pristupa:
@ECHO OFF PowerShell.exe -NoProfil -Problem za IzgovorPolitika -Komandiranje "&"% ~ dpn0.ps1 "PAUSE
S administrativnim pristupom:
@ECHO OFF PowerShell.exe -NoProfile -Command "& Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy obilazak -File" "% ~ dpn0.ps1" "' -Verb RunAs" PAUSE
Ne zaboravite staviti skupnu datoteku u istu mapu kao i skriptu PowerShell za koju ga želite koristiti i dati joj isto ime. Zatim, bez obzira na to u koji sustav preuzimate te datoteke, moći ćete pokrenuti svoju PowerShell skriptu bez potrebe za zaobilaženjem sigurnosnih postavki na sustavu. Te promjene svakako možete napraviti svaki put ručno, ali to vam štedi tu nevolju i nećete morati brinuti o poništavanju promjena kasnije.
Reference:
- Pokretanje PowerShell skripti iz batch datoteke - Blog programiranja Daniela Schroedera
- Provjera administratorskih dozvola u programu PowerShell - Hej, Scripting Guy! Blog