If-Koubou

Как да използвате пакетен файл, за да направите PowerShell скриптове по-лесни за изпълнение

Как да използвате пакетен файл, за да направите PowerShell скриптове по-лесни за изпълнение (Как да)

По няколко причини повечето скриптове PowerShell, свързани със сигурността, не са толкова лесно преносими и могат да се използват като партидни скриптове. Въпреки това, ние можем да обединим партиден скрипт с нашите PowerShell скриптове, за да разработим тези проблеми. Тук ще ви покажем някои от тези проблемни области и как да създадете партиден скрипт, за да ги заобиколите.

Защо не мога просто да копирам файла .PS1 на друг компютър и да го стартирам?

Освен ако целевата система не е предварително конфигурирана, за да позволи изпълнение на произволни скриптове, изискваните привилегии и използването на правилните настройки, има вероятност да се натъкнете на някои проблеми, когато се опитате да направите това.

  1. PowerShell не е свързан по подразбиране с разширението .PS1.
    Първоначално го направихме в нашата серия PowerShell Geek School. Windows асоциира файловете .PS1 към Notepad по подразбиране, вместо да ги изпраща на PowerShell командния интерпретатор. Това е, за да се предотврати случайно изпълнение на злонамерени скриптове, като щракнете двукратно върху тях. Има начини да промените това поведение, но това вероятно не е нещо, което искате да правите на всеки компютър, на който носите скриптовете си, особено ако някои от тези компютри не са ваши собствени.
  2. PowerShell не позволява по подразбиране изпълнението на външни скриптове.
    Настройката ExecutionPolicy в PowerShell предотвратява изпълнението на външни скриптове по подразбиране във всички версии на Windows. В някои версии на Windows, по подразбиране не се допуска изобщо изпълнение на скриптове. Ние ви показахме как да промените тази настройка в Как да позволите изпълнението на PowerShell скриптове на Windows 7. Това обаче е нещо, което не искате да правите само на всеки компютър.
  3. Някои скриптове PowerShell няма да работят без разрешения от администратора.
    Дори да се изпълнява с профил на ниво администратор, все пак трябва да преминете през Управление на потребителски акаунт (UAC), за да извършвате определени действия. Не искаме да изключваме това, но все още е хубаво, когато можем малко по-лесно да се справим.
  4. Някои потребители може да имат персонализирани среди PowerShell.
    Вероятно няма да се сблъскате с това често, но когато го направите, може да стартирате и да отстранявате проблемите си със скриптове малко разочароващо. За щастие можем да постигнем това, без да правим никакви постоянни промени.

Стъпка 1: Щракнете двукратно, за да стартирате.

Нека започнем, като се обърнем към първия проблем - .PS1 файлови асоциации. Не можете да кликнете два пъти, за да стартирате .PS1 файлове, но можете да изпълнявате .BAT файл по този начин. Така че, ще напишем партиден файл, за да се обадите на скрипта PowerShell от командния ред за нас.

Така че не е нужно да презаписваме партидния файл за всеки скрипт или всеки път, когато преместваме скрипт, той ще използва самопрепращаща се променлива, за да изгради пътя за файла за скрипта PowerShell. За да направите това, партидният файл трябва да бъде поставен в същата папка като Вашия скрипт PowerShell и да има същото име на файл. Така че, ако вашият PowerShell скрипт се нарича "MyScript.ps1", вие ще искате да назовете вашето партидно файл "MyScript.bat" и се уверете, че е в същата папка. След това поставете тези редове в партидния скрипт:

@ECHO OFF PowerShell.exe - Команда "&"% dpn0.ps1 "" ПАУЗА

Ако не бяха останалите ограничения в сигурността, това би било всичко, което е необходимо, за да стартирате скрипт PowerShell от партиден файл. Всъщност, първият и последният ред са основно въпрос на предпочитание - това е втората линия, която наистина върши работата. Ето разбивката:

@ OFF OFF изключва командата. Това просто държи останалите ви команди да се показват на екрана, когато партидният файл се изпълнява. Тази линия е скрита от използването на символа в (@) пред нея.

PowerShell.exe - "Команда" & "% ~ dpn0.ps1" " всъщност изпълнява скрипта PowerShell. PowerShell.exe може, разбира се, да бъде извикан от всеки CMD прозорец или пакет файл, за да стартира PowerShell на гола конзола, както обикновено. Можете също така да го използвате, за да стартирате команди направо от партиден файл, като включите параметъра -Command и съответните аргументи. Начинът, по който това се използва за насочване към нашия .PS1 файл, е със специалната променлива% ~ dpn0. Стартирайте от партиден файл,% ~ dpn0 се оценява на буквата на устройството, пътя на папката и името на файла (без разширение) на партидния файл. Тъй като партидният файл и скриптът PowerShell ще бъдат в една и съща папка и имат едно и също име,% ~ dpn0.ps1 ще се преведе към пълния пътека на файла на скрипта PowerShell.

PAUSE просто спира изпълнението на партидата и чака за въвеждане от потребителя. Това обикновено е полезно да имате в края на партидните си файлове, така че да имате възможност да прегледате произволен команден изход, преди прозорецът да изчезне. Докато преминаваме през тестването на всяка стъпка, полезността на това ще стане по-очевидна.

Така че основният партиден файл е настроен. За демонстрационни цели този файл се запазва като "D: \ Script Lab \ MyScript.bat" и в папката има "MyScript.ps1". Нека видим какво се случва, когато щракнете двукратно върху MyScript.bat.

Очевидно PowerShell скриптът не се изпълнява, но това може да се очаква - в края на краищата се занимавахме само с първия от четирите ни проблема. Има обаче някои важни битове, демонстрирани тук:

  1. Името на прозореца показва, че партидният скрипт успешно пуска PowerShell.
  2. Първият ред от изхода показва, че се използва персонализиран профил PowerShell. Това е потенциален проблем # 4, посочен по-горе.
  3. Съобщението за грешка показва ограниченията за ExecutionPolicy. Това е нашият проблем № 2.
  4. Подчертаната част от съобщението за грешка (което се извършва на изхода на грешка на PowerShell) показва, че партидният скрипт е правилно насочен към планирания скрипт PowerShell (D: \ Script Lab \ MyScript.ps1). Значи поне знаем, че много работи правилно.

Профилът, в този случай, е прост скрипт от една линия, използван за тази демонстрация, за генериране на изход, когато профилът е активен. Можете също така да персонализирате вашия собствен профил PowerShell, за да направите това, ако искате сами да тествате тези скриптове. Просто добавете следния ред към скрипта на потребителския си профил:

Изход за запис "Потребителски профил PowerShell в сила!"

Изпълняващото поле на тестовата система тук е настроено на RemoteSigned. Това позволява изпълнението на скриптове, създадени на място (като скрипта на потребителски профили), като блокират скриптовете от външни източници, освен ако не са подписани от доверен орган. За целите на демонстрацията, следната команда бе използвана за маркиране на MyScript.ps1 като от външен източник:

Добавяне на съдържание - Път "D: \ Лаборатория на скрипта \ MyScript.ps1" -Value "[ZoneTransfer] 'nZoneId = 3" -Стрийм' Zone.Identifier '

Това определя алтернативния поток от данни на Zone.Identifier в MyScript.ps1, така че Windows ще мисли, че файлът идва от Интернет. Тя може лесно да бъде обърната със следната команда:

Clear-Content -Path "D: \ Лаборатория на скрипта \ MyScript.ps1" -Stream "Zone.Identifier"

Стъпка 2: Първи около ExecutionPolicy.

Първи около настройката ExecutionPolicy, от CMD или партиден скрипт, всъщност е доста лесно. Просто променим втория ред на скрипта, за да добавим още един параметър към командата PowerShell.exe.

PowerShell.exe -ExecutionPolicy Bypass -Помощ "&"% ~ dpn0.ps1 ""

Параметърът -ExecutionPolicy може да се използва за промяна на ExecutionPolicy, която се използва, когато създавате нова PowerShell сесия. Това няма да продължи след тази сесия, така че можем да управляваме PowerShell по този начин, когато имаме нужда от това, без да отслабваме общата охрана на системата. Сега, след като сме го решили, нека още нека да го направим:

Сега, когато скриптът е изпълнен правилно, можем да видим какво всъщност прави. Това ни позволява да знаем, че изпълняваме скрипта като ограничен потребител. Скриптът всъщност се управлява от акаунт с разрешения на администратор, но контролът на потребителските акаунти става все по-прозрачен. Въпреки че подробностите за проверката на скрипта за достъп от администратора са извън обхвата на тази статия, тук е кодът, който се използва за демонстрация:

ако (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity] :: GetCurrent ()) IsInRole ([Security.Principal.WindowsBuiltInRole] "Administrator")) Write-Output 'Running as Administrator! Write-Output 'Running Limited!' Пауза

Също така ще забележите, че сега има две операции "Пауза" в изхода на скрипта - един от скрипта PowerShell и един от партидния файл. Причината за това ще стане по-ясна в следващата стъпка.

Стъпка 3: Получаване на администраторски достъп.

Ако вашият скрипт не изпълнява команди, които изискват кота, и вие сте сигурни, че няма да се притеснявате за това, че някой потребителски профили попадне на пътя, можете да пропуснете останалата част от него. Ако използвате някои команди на ниво администратор, ще ви трябва това парче.

За съжаление, няма начин да се задейства UAC за покачване от рамките на партиден файл или CMD сесия. Въпреки това, PowerShell ни позволява да направим това с Start-Process. Когато се използва с "-Verb RunAs" в своите аргументи, Start-Process ще се опита да стартира приложение с разрешения за администратор. Ако сесията PowerShell вече не е повишена, това ще задейства подкана на UAC. За да го използвате от партидния файл, за да стартирате нашия скрипт, ще приключим създаването на два PowerShell процеси - един за задействане на Start-Process и друг, стартиран от Start-Process, за да стартирате скрипта. Вторият ред на партидния файл трябва да се промени на следния ред:

PowerShell.exe -Command "& Стартиране на процеса PowerShell.exe -ArgumentList '-ExecutionPolicy Bypass -Файл" "% ~ dpn0.ps1" "-Verb RunAs"

Когато се стартира партидният файл, първият ред от изхода, който ще видим, е от скрипта на PowerShell профил. След това ще се появи подкана на UAC, когато Start-Process се опита да стартира MyScript.ps1.

След като кликнете върху подкана на UAC, ще се появи нов модел PowerShell. Тъй като това е нов случай, разбира се, отново ще видим известието за скрипт за профил. След това MyScript.ps1 работи и ние виждаме, че наистина сме в повишена сесия.

И има причината да имаме и две паузи тук. Ако не е за скрипта PowerShell, никога няма да видим изхода на скрипта - прозорецът PowerShell ще изскочи и ще изчезне веднага щом скриптът свърши. И без паузата в партидния файл, нямаше да можем да видим дали имаше някакви грешки при стартирането на PowerShell на първо място.

Стъпка 4: Първи около потребителски PowerShell профили.

Хайде да се отървем от това неприятно известие за потребителски профил сега, нали? Тук дори не е неудобство, но ако потребителският профил PowerShell променя настройките по подразбиране, променливите или функциите по начини, които вероятно не сте очаквали с вашия скрипт, те могат да бъдат наистина обезпокоителни. Много по-лесно е да изпълнявате сценария без профила изцяло, за да не се притеснявате за това. За да направите това, трябва да смените втория ред на партидния файл още веднъж:

PowerShell.exe -NoProfile -Command "& Стартиране на процеса PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -Файл" "% ~ dpn0.ps1" "-Verb RunAs"

Добавянето на параметъра -NoProfile и в двата случая на PowerShell, стартирани от скрипта, означава, че скриптът на потребителския профил ще бъде изцяло заобиколен и в двата стъпки и нашият скрипт PowerShell ще работи в доста предвидима, по подразбиране среда. Тук можете да видите, че в нито една от заровете на глави не е имало известие за потребителски профил.

Ако не се нуждаете от администраторски права в скрипта PowerShell и сте пропуснали стъпка 3, можете да го направите без втория потребителски модел PowerShell, а вторият ред от партидния ви файл трябва да изглежда така:

PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Помощ "&"% ~ dpn0.ps1 ""

Тогава изходът ще изглежда така:

(Разбира се, за скриптове, които не са от Administrator, можете да направите без пауза на края на скрипта във вашия PowerShell скрипт и в този момент, тъй като всичко е заловен в един и същ прозорец на конзолата и ще се проведе там с паузата в края на партито файл, така или иначе.)

Довършени партидни файлове.

В зависимост от това дали имате нужда от администраторски разрешения за вашия PowerShell скрипт (и наистина не трябва да ги поискате, ако не го направите), последният партиден файл трябва да изглежда като един от двата по-долу.

Без администраторски достъп:

@ECHO OFF PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "&"% dpn0.ps1 "" ПАУЗА

С администраторски достъп:

@Exo OFF PowerShell.exe -NoProfile -Command "& Стартиране на процеса PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -Файл" "% ~ dpn0.ps1" "-Verb RunAs" ПАУЗА

Не забравяйте да поставите партидния файл в същата папка като скрипта PowerShell, за който искате да го използвате, и дайте същото име. След това, без значение от каква система ще вземете тези файлове, ще можете да стартирате своя PowerShell скрипт, без да се налага да се нахвърляте върху някоя от настройките за сигурност в системата. Винаги можете да правите тези промени ръчно всеки път, но това ви спестява неприятностите и няма да ви се налага да се притеснявате, че ще се върнете към промените по-късно.

Препратки:

  • Стартиране на PowerShell скриптове от пакетен файл - Блогът за програмиране на Даниел Шрьодер
  • Проверка за разрешения за администратор в PowerShell - хей, скриптов човек! Блог