A kötegfájl használata a PowerShell parancsfájlok könnyebb futtatásához
A PowerShell szkriptek több okból is, főleg a biztonsággal kapcsolatosak, nem olyan könnyen hordozhatóak és használhatók, mint a kötegfájlok. Azonban ezeket a problémákat a PowerShell parancsfájljainkkal kötegeltük össze. Itt megmutatjuk Önnek néhány problémás területet, és hogyan készíthetünk egy kötegelt szkriptet, hogy megkeressük őket.
Miért nem tudom csak másolni a .PS1 fájlt egy másik számítógépre, és futtatni?
Kivéve, ha a célrendszert előre beállították tetszőleges szkriptek futtatásához, a szükséges jogosultságokkal, és a megfelelő beállításokat használva, valószínűleg bizonyos problémákba ütközik, amikor ezt megpróbálja.
- A PowerShell alapértelmezés szerint nem kapcsolódik a .PS1 fájlkiterjesztéshez.
Ezt először a PowerShell Geek Iskolai sorozatunkban hoztuk létre. A Windows alapértelmezés szerint társítja a .PS1 fájlokat a Jegyzettömbbe, ahelyett, hogy elküldné őket a PowerShell parancsértelmezőnek. Ennek célja, hogy megakadályozza a rosszindulatú szkriptek véletlenszerű végrehajtását egyszerűen kettős kattintással. Vannak módok, amelyekkel megváltoztathatja ezt a viselkedést, de valószínűleg nem olyan dolog, amit minden olyan számítógépen szeretne csinálni, amelyen a szkriptet hordozza - különösen, ha ezek közül néhány nem a saját. - A PowerShell nem engedélyezi a külső szkriptek végrehajtását alapértelmezés szerint.
A PowerShell ExecutionPolicy beállítása megakadályozza a külső szkriptek alapértelmezett végrehajtását a Windows minden verziójában. Egyes Windows verziókban az alapértelmezett nem engedi meg a szkript végrehajtását. Megmutattuk, hogyan módosíthatja ezt a beállítást a PowerShell parancsfájlok végrehajtásának engedélyezése a Windows 7 rendszeren. Ez azonban egy olyan dolog, amit nem szeretne tenni egyetlen számítógépen sem. - Néhány PowerShell parancsfájl nem működik rendszergazdai engedély nélkül.
Még egy rendszergazdai szintű fiókkal is futhat, még mindig be kell mennie a felhasználói fiókok felügyeletén (UAC), hogy bizonyos műveleteket hajtson végre. Ezt nem akarjuk letiltani, de még mindig jó, ha egy kicsit könnyebb kezelni. - Lehet, hogy egyes felhasználók testre szabott PowerShell környezeteket használnak.
Valószínűleg nem fog belépni ehhez gyakran, de ha ezt megteheti, akkor kissé bosszantóvá teheti a szkriptek futását és hibaelhárítását. Szerencsére ezt a folyamatot állandó változások nélkül is el tudjuk érni.
1. lépés: Kattintson duplán a futtatáshoz.
Kezdjük az első problémával - .PS1 fájl társításokkal. Nem lehet duplán kattintani a .PS1 fájlok futtatásához, de végrehajthat egy .BAT fájlt. Tehát írunk egy kötegelt fájlt, hogy a PowerShell parancsfájlt hívja a parancssorból.
Tehát nem kell minden egyes parancsfájlra újraírni a kötegfájlt, vagy minden alkalommal, amikor egy szkriptet mozgatunk, egy önmegjelölő változót fog használni a PowerShell parancsfájl elérési útjának létrehozásához. A munka elvégzéséhez a kötegfájlt ugyanabban a mappában kell elhelyezni, mint a PowerShell parancsfájlja, és azonos fájlnevet kell adnia. Tehát, ha a PowerShell szkriptet „MyScript.ps1” -nek nevezzük, akkor a „MyScript.bat” kötegfájl nevét szeretnénk megnevezni, és győződjön meg róla, hogy az ugyanabban a mappában van. Ezután tegye ezeket a sorokat a kötegfájlba:
@ECHO OFF PowerShell.exe -Command "& '% ~ dpn0.ps1'" PAUSE
Ha nem lenne a többi biztonsági korlátozás a helyén, akkor ez mindenképpen szükséges ahhoz, hogy egy PowerShell parancsfájlt futtasson egy kötegelt fájlból. Tény, hogy az első és az utolsó sorok elsősorban csak preferencia kérdése - ez a második sor, ami valóban a munkát végzi. Íme a bontás:
@ECHO KI kikapcsolja a parancs visszhangját. Ez csak azt jelenti, hogy a parancsok a képernyőn megjelenjenek, amikor a kötegelt fájl fut. Ez a vonal maga elrejtve van az at (@) szimbólum használatával.
PowerShell.exe -Command “& '% ~ dpn0.ps1'” ténylegesen futtatja a PowerShell parancsfájlt. A PowerShell.exe-t természetesen bármelyik CMD ablakból vagy kötegelt fájlból lehet hívni, hogy a PowerShell-t a szokásos módon csupasz konzolra indítsa. Azt is használhatja, hogy a parancsokat közvetlenül egy kötegfájlból futtassa, a -Command paraméter és a megfelelő argumentumok hozzáadásával. Az .PS1 fájl célzásának módja a speciális% ~ dpn0 változó. Futtasson egy kötegfájlból, a% ~ dpn0 értékeli a kötegfájl meghajtóbetűjelét, mappaútvonalát és fájlnevét (kiterjesztés nélkül). Mivel a kötegfájl és a PowerShell parancsfájl ugyanabban a mappában lesz, és ugyanaz a neve lesz, a% ~ dpn0.ps1 lefordítja a PowerShell parancsfájl teljes fájlútvonalát.
SZÜNET csak szünetelteti a kötegelt végrehajtást, és vár a felhasználói bevitelre. Ez általában hasznos a kötegfájlok végén, így lehetősége van arra, hogy az ablak eltűnése előtt ellenőrizze a parancs kimeneteit. Ahogy végigkísérjük az egyes lépések tesztelését, ennek hasznossága nyilvánvalóbb lesz.
Így van beállítva az alapvető kötegfájl. Demonstrációs célból ez a fájl „D: Script Lab MyScript.bat” -ként kerül mentésre, és ugyanabban a mappában van egy „MyScript.ps1”. Lássuk, mi történik, ha kétszer kattintunk a MyScript.bat fájlra.
Nyilvánvaló, hogy a PowerShell szkript nem futott, de ez várható volt - csak az első négy problémánkról szóltunk. Néhány fontos bit azonban itt látható:
- Az ablak címe azt mutatja, hogy a kötegfájl sikeresen elindította a PowerShell-et.
- A kimenet első sora azt mutatja, hogy egyéni PowerShell profil van használatban. Ez a 4. probléma a fent felsorolt.
- A hibaüzenet a VégrehajtásiPolitikai korlátozásokat mutatja be. Ez a mi problémánk # 2.
- A hibaüzenet aláhúzott része (amelyet a PowerShell hibajavításával végeztek) mutatja, hogy a kötegfájl helyesen célozta meg a tervezett PowerShell parancsfájlt (D: Script Lab MyScript.ps1). Tehát legalább tudjuk, hogy sokan megfelelően működnek.
Ebben az esetben a profil egy egyszerű egysoros parancsfájl, amelyet a bemutató során a profil aktív állapotában generál. A saját PowerShell-profilját is testre szabhatja, ha ezt a szkriptet is szeretné tesztelni. Egyszerűen add hozzá a következő sort a profilszkripthez:
Írás-kimenet 'Egyéni PowerShell profil érvényes!'
Az itt található tesztrendszer ExecutionPolicy értéke RemoteSigned. Ez lehetővé teszi a helyileg létrehozott szkriptek végrehajtását (mint például a profilfájl), miközben blokkolja a külső forrásokból származó szkripteket, kivéve, ha azokat egy megbízható hatóság aláírta. Demonstrációs célokra a következő parancsot használták a MyScript.ps1 külső forrásból származó jelzésére:
Add-Content -D 'D: script Lab MyScript.ps1' -Value "[ZoneTransfer] 'nZoneId = 3" -Stream "Zone.Identifier"
Ez beállítja a Zone.Identifier alternatív adatfolyamot a MyScript.ps1 fájlban úgy, hogy a Windows úgy gondolja, hogy a fájl az internetről származik. Könnyen megfordítható a következő paranccsal:
Clear-Content -P 'D: Szkriptlabda MyScript.ps1' -Stream 'Zone.Identifier'
2. lépés: Az ExecutionPolicy megismerése.
Az ExecutionPolicy beállítás megismerése a CMD-ből vagy a kötegfájlból valójában nagyon egyszerű. Egyszerűen módosítjuk a parancsfájl második sorát, hogy még egy paramétert adjunk a PowerShell.exe parancshoz.
PowerShell.exe -ExecutionPolicy Bypass -Command "& '% ~ dpn0.ps1'"
A -ExecutionPolicy paraméter használható az ExecutionPolicy módosítására, amelyet akkor használunk, amikor új PowerShell munkamenetet szedsz. Ez nem tartható fenn ezen a munkameneten túl, így a PowerShell-et hasonlóan futtathatjuk, ha szükségünk van anélkül, hogy gyengítenénk a rendszer általános biztonsági pozícióját. Most, hogy rögzítettük, akkor menjünk hozzá:
Most, hogy a szkript megfelelően végrehajtott, láthatjuk, hogy mit csinál. Tudjuk, hogy a szkriptet korlátozott felhasználóként futtatjuk. A parancsfájlt valójában egy rendszergazdai jogosultsággal rendelkező fiók futtatja, de a felhasználói fiókok felügyelete elindul. Bár a rendszer a rendszergazdai hozzáférést ellenőrző szkript részleteit túlmutat e cikk hatályán, itt van a bemutatóhoz használt kód:
ha (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity] :: GetCurrent ()) IsInRole ([Security.Principal.WindowsBuiltInRole] "Adminisztrátor")) Írás-kimenet "Futtatás rendszergazdaként!" Írás-kimenet korlátozott! ” Szünet
Azt is észreveheted, hogy most már két „szünet” művelet van a szkript kimenetben - egy a PowerShell parancsfájlból, és az egyik a kötegfájlból. Ennek oka inkább a következő lépésben lesz látható.
3. lépés: A rendszergazdai hozzáférés elérése.
Ha a parancsfájl nem fut olyan parancsokat, amelyek magasságot igényelnek, és biztos vagy benne, hogy nem kell aggódnia, hogy bárki egyéni profilja az úton van, hagyja ki ezt a többit. Ha azonban néhány rendszergazdai szintű cmdlet-et futtat, szüksége lesz erre a darabra.
Sajnos nincs mód arra, hogy az UAC-t batch fájlból vagy CMD munkamenetből felemelje. A PowerShell azonban lehetővé teszi számunkra, hogy ezt a Start-Process segítségével végezzük el. Amikor a argumentumokban a „-Verb RunAs” -al együtt használja, a Start-Process megpróbálja indítani egy alkalmazást az adminisztrátori jogosultságokkal. Ha a PowerShell-munkamenet még nem emelkedett, akkor egy UAC-parancsot fog indítani. Ahhoz, hogy ezt a kötegfájlból használhassuk a script elindításához, akkor két PowerShell folyamatot fogunk végezni - az egyik a Start-Process, a másik pedig a Start-Process által indított, a parancsfájl futtatásához. A kötegfájl második sorát erre kell módosítani:
PowerShell.exe-parancs "& Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy Bypass-Fájl" "% ~ dpn0.ps1" "" -Verb RunAs "
A kötegfájl futtatásakor az első kimeneti sor a PowerShell profil szkriptéből származik. Ezután egy UAC-üzenet jelenik meg, amikor a Start-Process megpróbálja elindítani a MyScript.ps1-et.
Miután az UAC parancssorra kattintott, egy új PowerShell példány fog megszületni. Mivel ez egy új példány, természetesen újra látni fogjuk a profilfájl-értesítést. Ezután fut a MyScript.ps1, és látjuk, hogy valóban egy magas szintű munkamenetben vagyunk.
És van az oka annak, hogy itt is két szünet van. Ha nem a PowerShell parancsfájljához, akkor soha nem látnánk a szkript kimenetét - a PowerShell ablak csak felbukkan és eltűnik, amint a parancsfájl fut. És a kötegfájl szünetének hiányában nem tudnánk látni, hogy volt-e hiba a PowerShell elindításában..
4. lépés: Egyéni PowerShell profilok megismerése.
Hadd megszabaduljunk erről a csúnya egyéni profilról, most? Itt aligha lehet semmi baj, de ha egy felhasználó PowerShell profilja megváltoztatja az alapértelmezett beállításokat, változókat vagy funkciókat olyan módon, ahogyan nem valószínű, hogy a szkriptjei vannak, akkor ezek nagyon zavaróak lehetnek. Sokkal egyszerűbb a szkript futtatása anélkül, hogy a profilt teljes egészében el kellene végezni, ezért nem kell aggódnia. Ehhez még egyszer meg kell változtatnunk a kötegfájl második sorát:
PowerShell.exe -NoProfile -Command "& Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -Fájl" "~ ~ ~ nn.ps1" "-Verb RunAs"
A -NoProfile paraméter hozzáadása a szkript által indított PowerShell mindkét példányához azt jelenti, hogy a felhasználó profilfájlja mindkét lépésben teljesen megkerül, és a PowerShell parancsfájlja meglehetősen kiszámítható, alapértelmezett környezetben fog futni. Itt láthatod, hogy nincs egyéni profil értesítés az egyik ívelt kagylóban.
Ha nem kell adminisztrátori jogokat a PowerShell szkriptben, és kihagyta a 3. lépést, akkor a második PowerShell példány nélkül is elvégezhető, és a kötegfájl második sora így néz ki:
PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '% ~ dpn0.ps1'"
A kimenet így néz ki:
(Természetesen a nem adminisztrátori szkriptek esetében is elvégezhetjük a szkript vége nélkül a PowerShell szkriptben, mivel mindent ugyanabban a konzolablakban rögzítenek, és azt ott tartják a szünet után egyébként.
A befejezett kötegfájlok.
Attól függően, hogy szükség van-e adminisztrátori jogosultságokra a PowerShell-szkripthez (és valójában nem kellene őket kérni, ha nem), a végső kötegfájlnak az alábbi kettő egyikének kell lennie..
Adminisztrátori hozzáférés nélkül:
@ECHO OFF PowerShell.exe -NoProfile -FeltevésPolicy bypass-parancs "&"% ~ dpn0.ps1 "" PAUSE
Adminisztrátori hozzáféréssel:
@ECHO OFF PowerShell.exe -NoProfile -Command "& Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -Fájl"% ~ dpn0.ps1 ""' -Verb RunAs "PAUSE
Ne feledje, hogy a kötegelt fájlt ugyanabban a mappában helyezze el, mint a PowerShell szkriptet, amelyet használni kíván, és adja meg ugyanazt a nevet. Ezután, függetlenül attól, hogy milyen rendszereket vesznek ezekre a fájlokra, képes lesz futtatni a PowerShell szkriptet anélkül, hogy a rendszer biztonsági beállításainak bármelyikével kellett volna megfordulnia. Ezeket a változtatásokat minden bizonnyal manuálisan minden alkalommal megteheti, de ez megmenti ezt a problémát, és nem kell aggódnia a módosítások későbbi visszaállítása miatt.
Irodalom:
- PowerShell parancsfájlok futtatása egy kötegelt fájlból - Daniel Schroeder programozási blogja
- Rendszergazdai jogosultságok ellenőrzése a PowerShell-ben - Hé, Scripting Guy! blog