9Sep

Cum se utilizează un fișier batch pentru a face scripturile PowerShell mai ușor de rulat

click fraud protection

Din mai multe motive, scripturile PowerShell legate de securitate nu sunt la fel de ușor de portabil și pot fi folosite ca scripturi batch. Cu toate acestea, putem lega un script batch cu scripturile PowerShell pentru a rezolva aceste probleme. Aici, vă vom arăta câteva dintre aceste zone problematice și cum să construiți un scenariu batch pentru a le înconjura.

De ce nu pot să copiez fișierul. PS1 pe alt computer și să îl rulez?

Cu excepția cazului în care sistemul țintă a fost preconfigurat pentru a permite rularea de scripturi arbitrare, cu privilegiile necesare și utilizând setările corecte, este posibil să aveți probleme atunci când încercați să faceți acest lucru.

  1. PowerShell nu este asociat implicit cu extensia. PS1.
    Am adus acest lucru inițial în seria PowerShell Geek School. Windows asociază în mod implicit fișierele. PS1 în Notepad, în loc să le trimită interpretului de comandă PowerShell. Acest lucru este de a preveni executarea accidentală a script-urilor malware prin simpla dublare a acestora. Există modalități prin care puteți schimba acest comportament, dar probabil că nu este ceva pe care doriți să-l faceți pe fiecare computer pe care purtați scripturile în jurul valorii de - mai ales dacă unele dintre aceste computere nu sunt ale tale.
    instagram viewer
  2. PowerShell nu permite execuția script-ului extern în mod implicit.
    Setarea ExecutionPolicy din PowerShell previne executarea de script-uri externe în mod implicit în toate versiunile de Windows.În unele versiuni Windows, implicit nu permite executarea script-ului. V-am arătat cum să modificați această setare în Cum să permiteți executarea scripturilor PowerShell pe Windows 7. Totuși, aceasta este și ceva ce nu doriți să faceți pe nici un computer.
  3. Unele scripturi PowerShell nu vor funcționa fără permisiuni de administrator.
    Chiar și cu un cont la nivel de Administrator, tot trebuie să faceți controlul contului de utilizator( UAC) pentru a efectua anumite acțiuni. Nu vrem să dezactivăm acest lucru, dar este încântător să putem face ceva mai ușor de rezolvat.
  4. Unii utilizatori pot avea medii personalizate PowerShell.
    Probabil că nu veți mai întâlni acest lucru frecvent, dar când faceți acest lucru, este posibil ca rularea și depanarea scenariilor dvs. să fie puțin frustrante. Din fericire, putem obține acest lucru fără să facem nici o schimbare permanentă.

Pasul 1: Faceți dublu clic pentru a rula.

Să începem prin abordarea primei probleme - asociații de dosare. PS1.Nu puteți face dublu clic pentru a rula fișierele. PS1, dar puteți executa un fișier. BAT în acest fel. Deci, vom scrie un fișier batch pentru a apela scriptul PowerShell din linia de comandă pentru noi.

Așadar, nu trebuie să re-scriem fișierul batch pentru fiecare script sau de fiecare dată când mutați un script în jur, va folosi o variabilă de auto-referință pentru a construi calea fișierului pentru scriptul PowerShell. Pentru a face acest lucru, fișierul lot va trebui să fie plasat în același director ca și scriptul PowerShell și să aibă același nume de fișier. Deci, dacă scriptul dvs. PowerShell este numit "MyScript.ps1", veți dori să denumiți fișierul batch "MyScript.bat" și să vă asigurați că este în același folder. Apoi, puneți aceste linii în scriptul de lot:

@ECHO OFF PowerShell.exe -Command "& '% ~ dpn0.ps1'" PAUSE

Dacă nu ar fi fost celelalte restricții de securitate în vigoare,este nevoie pentru a rula un script PowerShell dintr-un fișier lot. De fapt, prima și ultima linie sunt în principal doar o chestiune de preferință - este a doua linie care face într-adevăr munca. Iată defalcarea:

@ECHO OFF dezactivează comanda ecou. Acest lucru nu face ca celelalte comenzi să se afișeze pe ecran atunci când rulează fișierul lot. Această linie este ascunsă prin utilizarea simbolului de la( @) din fața acesteia.

PowerShell.exe -Command "&'% ~ Dpn0.ps1' " rulează de fapt scriptul PowerShell. PowerShell.exe poate fi, desigur, apelat din orice fereastră CMD sau fișier lot pentru a lansa PowerShell la o consolă goală, ca de obicei. De asemenea, puteți să o utilizați pentru a rula comenzi direct dintr-un fișier batch, incluzând parametrul -Command și argumentele corespunzătoare. Modul în care acest lucru este folosit pentru a viza fișierul. PS1 este cu variabila specială% ~ dpn0.Rulați dintr-un fișier batch,% ~ dpn0 este evaluat la litera unității, calea dosarului și numele fișierului( fără extensie) din fișierul lot. Deoarece fișierul batch și scriptul PowerShell vor fi în același folder și au același nume,% ~ dpn0.ps1 se va traduce în calea fișierului complet al scriptului PowerShell.

PAUSE doar întrerupe execuția lotului și așteaptă introducerea de către utilizator. Acest lucru este în general util pentru a avea la sfârșitul fișierelor lot, astfel încât să aveți șansa de a revizui orice ieșire de comandă înainte ca fereastra să dispară.Pe măsură ce trecem prin testarea fiecărui pas, utilitatea acestui lucru va deveni mai evidentă.

Deci, fișierul de bază de bază este configurat.În scopuri demonstrative, acest fișier este salvat ca "D: \ Script Lab \ MyScript.bat" și există un "MyScript.ps1" în același folder. Să vedem ce se întâmplă când faceți dublu clic pe MyScript.bat.

Evident, scriptul PowerShell nu a rulat, dar acest lucru este de așteptat - în cele din urmă am abordat doar prima dintre cele patru probleme. Cu toate acestea, există o serie de biți importanți demonstrat aici:

  1. Titlul ferestrei arată că scriptul pe loturi a lansat cu succes PowerShell.
  2. Prima linie de ieșire arată că este folosit un profil PowerShell personalizat. Aceasta este problema potențială # 4, menționată mai sus.
  3. Mesajul de eroare demonstrează că restricțiile de Executare Politică sunt în vigoare. Asta e problema noastră # 2.
  4. Partea subliniată a mesajului de eroare( care se efectuează nativ prin ieșirea de eroare a PowerShell) arată că script-ul batch a vizat în mod corect scriptul PowerShell intenționat( D: \ Script Lab \ MyScript.ps1).Deci, cel puțin știm că lucrurile funcționează corect.

Profilul, în acest caz, este un script simplu dintr-o singură linie folosit pentru această demonstrație pentru a genera ieșire ori de câte ori profilul este activ. Puteți personaliza propriul profil PowerShell și pentru a face acest lucru, dacă doriți să testați aceste scripturi. Pur și simplu adăugați următoarea linie în script-ul tău de profil:

Write-Output 'Profil personalizat PowerShell în vigoare!'

ExecutionPolicy pe sistemul de testare este setat la RemoteSigned. Acest lucru permite execuția de script-uri create local( cum ar fi scriptul de profil), în timp ce blocarea scripturilor din surse externe, cu excepția cazului în care sunt semnate de o autoritate de încredere.În scop demonstrativ, următoarea comandă a fost folosită pentru a semnala MyScript.ps1 ca fiind dintr-o sursă externă:

Add-Content -Path "D: \ Script Lab \ MyScript.ps1" -Value "[ZoneTransfer]" nZoneId = 3 "-Stream 'Zone. Identifier'

Setează fluxul de date alternativ Zone. Identifier pe MyScript.ps1 astfel încât Windows să creadă că fișierul a venit de pe Internet. Se poate inversa ușor cu următoarea comandă:

Clear-Content -Path "D: \ Script Lab \ MyScript.ps1" -Stream "Zone. Identifier"

Pasul 2: Noțiuni de bază despre ExecutionPolicy.

Obținerea setării ExecutionPolicy, din CMD sau dintr-un script batch, este de fapt destul de ușoară.Modificăm doar a doua linie a scriptului pentru a adăuga un alt parametru comenzii PowerShell.exe.

PowerShell.exe -ExecutionPolicy Bypass -Command "& '% ~ dpn0.ps1'"

Parametrul -ExecutionPolicy poate fi folosit pentru a modifica ExecutionPolicy care se utilizează atunci când faceți o nouă sesiune PowerShell. Acest lucru nu va persista dincolo de acea sesiune, astfel încât să putem rula PowerShell astfel, ori de câte ori avem nevoie, fără a slăbi postura generală de securitate a sistemului. Acum că am rezolvat acest lucru, hai să mergem la altul:

Acum că scriptul a executat corect, putem vedea ce face de fapt. Ne anunță că executăm scriptul ca utilizator limitat. Scriptul este, de fapt, rulat de un cont cu permisiuni de administrator, dar controlul contului de utilizator devine în cale. Deși detaliile despre modul în care scriptul verifică accesul administratorului sunt dincolo de domeniul de aplicare al acestui articol, iată codul care este folosit pentru demonstrație:

dacă( ([Security. Principal. WindowsPrincipal] [Security. Principal. WindowsIdentity]: : GetCurrent()} IsinRole( [Security. Principal. WindowsBuiltInRole] "Administrator")){ Write-Output 'Rularea ca Administrator!'} Else{ Write-Output 'Running Limited!'} Pauză

Veți observa că acum există douăOperațiile "Întrerupeți" în ieșirea scriptului - una din scriptul PowerShell și una din fișierul batch. Motivul pentru aceasta va fi mai evident în următorul pas.

Pasul 3: Obținerea accesului la administratori.

Dacă scriptul dvs. nu rulează comenzi care necesită altitudine și sunteți destul de sigur că nu va trebui să vă faceți griji cu privire la faptul că profilurile personalizate ale cuiva se blochează, puteți sări peste restul acestora. Dacă rulați unele cmdlet-uri la nivel de administrator, veți avea nevoie de această piesă.

Din păcate, nu există nicio modalitate de a declanșa UAC pentru elevație din cadrul unui fișier batch sau al unei sesiuni CMD.Cu toate acestea, PowerShell ne permite să facem acest lucru cu Start-Process. Când este folosit cu argumentul "-Verb RunAs" în argumentele sale, Start-Process va încerca să lanseze o aplicație cu permisiuni de administrator. Dacă sesiunea PowerShell nu este deja ridicată, aceasta va declanșa o solicitare UAC.Pentru a folosi acest lucru din fișierul batch pentru a lansa scriptul nostru, vom termina de reproducere două procese PowerShell - unul pentru a declanșa Start-Process și altul, lansat de Start-Process, pentru a rula scriptul. A doua linie a fișierului batch trebuie să fie schimbată la următoarea:

PowerShell.exe -Command "&{ Start-Process PowerShell.exe -ArgumentList" -ExecuțiePolicy Bypass -File ""% ~ dpn0.ps1 "" '-VerbRunAs} "

Când se execută fișierul batch, prima linie de ieșire pe care o vom vedea este din scriptul profilului PowerShell. Apoi, va exista un prompt UAC când Start-Process încearcă să lanseze MyScript.ps1.

După ce faceți clic pe promptul UAC, va apărea o nouă instanță PowerShell. Deoarece aceasta este o instanță nouă, bineînțeles, vom vedea din nou nota de script de profil. Apoi, MyScript.ps1 rulează și vedem că suntem cu adevărat într-o sesiune ridicată.

Și există motivul pentru care avem și două pauze aici. Dacă nu pentru cea din scriptul PowerShell, nu vom vedea niciodată ieșirea scriptului - fereastra PowerShell va apărea și va dispărea imediat ce scriptul este terminat.Și fără pauză în fișierul lot, nu am fi putut vedea dacă au apărut erori în primul rând în PowerShell.

Pasul 4: Obținerea profilelor personalizate PowerShell.

Să scăpăm de acea notificare de profil personalizată acum, nu? Aici, nu este chiar o provocare, dar dacă profilul PowerShell al unui utilizator modifică setările implicite, variabilele sau funcțiile în moduri pe care nu le-ați anticipat cu scenariul dvs., ele pot fi cu adevărat supărătoare. Este mult mai simplu să rulați scenariul fără profilul complet, astfel încât să nu vă faceți griji în legătură cu acest lucru. Pentru a face acest lucru, trebuie doar să schimbăm încă o dată al doilea rând al fișierului batch:

PowerShell.exe -NoProfile -Command "&{ Start-Process PowerShell.exe -ArgumentList" -NoProfile -ExecutionPolicy Bypass -File ""% ~ dpn0.ps1 "" -Verb RunAs} "

Adăugarea parametrului -NoProfile la ambele instanțe ale PowerShell lansate de script înseamnă că scriptul de utilizator al utilizatorului va fi complet ocolit în ambele etape și că scriptul PowerShell va rula înun mediu destul de previzibil, implicit. Aici, puteți vedea că nu există nicio notificare de profil personalizată în niciuna din cochilii care au dat naștere.

Dacă nu aveți nevoie de drepturi de administrator în scriptul dvs. PowerShell și ați sărit peste pasul 3, puteți să faceți acest lucru fără a doua instanță PowerShell și a doua linie a fișierului dvs. batch ar trebui să arate astfel:

PowerShell.exe -NoProfile -ExecutareaPolica Bypass -Command "& '% ~ dpn0.ps1'"

Ieșirea va arăta astfel:

( Bineînțeles, pentru scripturile non-Administrator, puteți face fără o pauză de sfârșit de script în scriptul PowerShellla acest moment de asemenea, deoarece totul este capturat în aceeași fereastră de consolă și ar fi ținut acolo de pauza de la sfârșitul fișierului lot oricum.)

Fișiere batch completate.

În funcție de dacă aveți sau nu nevoie de permisiuni de administrator pentru scriptul dvs. PowerShell( și de fapt nu ar trebui să le cereți dacă nu), fișierul batch final ar trebui să arate ca unul din cele două de mai jos.

Fără acces Admin:

@ECHO OFF PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '% ~ dpn0.ps1'" PAUSE

Cu acces Admin:

@ECHO OFF PowerShell.exe -NoProfile -Command "&{Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecuțiePolitica Bypass -File ""% ~ dpn0.ps1 ""' -Verb RunAs} "PAUSE

Nu uitați să puneți fișierul batch în același director ca scriptul PowerShell pe care dorițisă-l folosești și să-i dai același nume. Apoi, indiferent de sistemul în care faceți aceste fișiere, veți putea să rulați scriptul dvs. PowerShell fără a fi nevoit să vă distrați cu oricare dintre setările de securitate de pe sistem. Cu siguranță puteți face aceste modificări manual de fiecare dată, dar acest lucru vă salvează acea problemă și nu va trebui să vă faceți griji că veți reveni mai târziu la schimbări.

Referințe:

  • Scrierea scripturilor PowerShell dintr-un fișier batch - Blogul de programare al lui Daniel Schroeder
  • Verificarea permisiunilor de administrator în PowerShell - Hei, Scripting Guy! Blog