Hjemmeside » hvordan » Sådan bruges en batchfil til at gøre PowerShell-scripts nemmere at køre

    Sådan bruges en batchfil til at gøre PowerShell-scripts nemmere at køre

    Af flere årsager er de fleste sikkerhedsrelaterede PowerShell-scripts ikke lige så let bærbare og anvendelige, som batchskripter kan være. Vi kan dog bundtes et batch script med vores PowerShell-scripts til at løse disse problemer. Her vil vi vise dig et par af disse problemområder, og hvordan du opbygger et batch script til at omgå dem.

    Hvorfor kan jeg ikke bare kopiere min .PS1-fil til en anden computer og køre den?

    Medmindre målet er blevet præ-konfigureret til at tillade kørsel af vilkårlige scripts, med de nødvendige rettigheder, og bruge de rigtige indstillinger, chancerne er du kommer til at løbe ind i nogle problemer, når du forsøger at gøre dette.

    1. PowerShell er ikke tilknyttet .PS1 filtypen som standard.
      Vi bragte det først op i vores PowerShell Geek School-serie. Windows associerer .PS1-filer til Notesblok som standard, i stedet for at sende dem til PowerShell-kommandotolken. Dette er for at forhindre utilsigtet udførelse af ondsindede scripts ved blot at dobbeltklikke på dem. Der er måder du kan ændre denne adfærd på, men det er nok ikke noget, du vil gøre på hver computer, du bærer dine scripts rundt til - især hvis nogle af disse computere ikke er dine egne.
    2. PowerShell tillader ikke ekstern scriptudførelse som standard.
      Execution Policy-indstillingen i PowerShell forhindrer udførelse af eksterne scripts som standard i alle versioner af Windows. I nogle Windows-versioner tillader det overhovedet ikke at udføre scriptudførelse. Vi viste dig, hvordan du ændrer denne indstilling i Sådan tillader du udførelse af PowerShell Scripts på Windows 7. Dette er også noget, du ikke vil gøre på bare en hvilken som helst computer.
    3. Nogle PowerShell-scripts virker ikke uden administratorrettigheder.
      Selv med at køre med en administrator-konto, skal du stadig gennemgå brugerkontrolkontrol (UAC) for at udføre bestemte handlinger. Vi ønsker ikke at deaktivere dette, men det er stadig godt, når vi kan gøre det lidt lettere at håndtere.
    4. Nogle brugere kan have tilpassede PowerShell-miljøer.
      Du vil sandsynligvis ikke løbe ind i dette ofte, men når du gør det, kan det gøre kørsel og fejlfinding af dine scripts lidt frustrerende. Heldigvis kan vi komme rundt om dette uden at lave nogen permanente ændringer.

    Trin 1: Dobbeltklik for at køre.

    Lad os begynde med at løse det første problem - .PS1 filforeninger. Du kan ikke dobbeltklikke for at køre .PS1-filer, men du kan udføre en .BAT-fil på den måde. Så vi skriver en batchfil for at kalde PowerShell-scriptet fra kommandolinjen for os.

    Så vi behøver ikke at omskrive batch-fil til hver script, eller hver gang vi flytter et script rundt, går det at gøre brug af en selvrefererende variabel til at bygge stien til PowerShell script. For at gøre dette arbejde skal batchfilen placeres i samme mappe som dit PowerShell-script og have samme filnavn. Så hvis dit PowerShell script hedder "MyScript.ps1", vil du gerne navngive din batchfil "MyScript.bat" og sørg for, at det er i samme mappe. Sæt derefter disse linjer i batch scriptet:

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

    Hvis det ikke var for de øvrige sikkerhedsrestriktioner på plads, ville det virkelig være alt, hvad der kræves for at køre et PowerShell-script fra en batchfil. Faktisk er de første og sidste linjer først og fremmest et spørgsmål om præference - det er den anden linje, der virkelig gør arbejdet. Her er sammenbruddet:

    @ECHO OFF slukker for kommando-ekko. Dette holder bare dine andre kommandoer vist på skærmen, når batchfilen kører. Denne linje er selv skjult ved brug af at (@) symbolet foran den.

    PowerShell.exe -Command "& '% ~ dpn0.ps1'" driver faktisk PowerShell-scriptet. PowerShell.exe kan selvfølgelig kaldes fra ethvert CMD-vindue eller batch-fil for at starte PowerShell til en bare konsol som normalt. Du kan også bruge det til at køre kommandoer lige fra en batchfil ved at inkludere parameteren -Command og relevante argumenter. Den måde, hvorpå dette bruges til at målrette vores .PS1-fil, er med den specielle% ~ dpn0-variabel. Kør fra en batchfil evaluerer% ~ dpn0 til drevbogstav, mappebane og filnavn (uden udvidelse) af batchfilen. Da batchfilen og PowerShell-scriptet vil være i samme mappe og have samme navn, vil% ~ dpn0.ps1 oversætte til den fulde filsti i PowerShell-scriptet.

    PAUSE stopper bare batch-udførelsen og venter på brugerindgang. Dette er generelt nyttigt at have i slutningen af ​​dine batch-filer, så du har mulighed for at gennemgå nogen kommandoudgang, før vinduet forsvinder. Når vi går gennem test af hvert trin, bliver brugen af ​​dette mere tydelig.

    Så er den grundlæggende batch-fil oprettet. Til demonstration er denne fil gemt som "D: \ Script Lab \ MyScript.bat" og der er en "MyScript.ps1" i samme mappe. Lad os se, hvad der sker, når vi dobbeltklikker på MyScript.bat.

    Naturligvis kørte PowerShell-scriptet ikke, men det kan man forvente - vi har jo kun taget fat på det første af vores fire problemer. Der er dog nogle vigtige punkter demonstreret her:

    1. Vinduets titel viser, at batch scriptet succesfully lancerede PowerShell.
    2. Den første produktionslinje viser, at en brugerdefineret PowerShell-profil er i brug. Dette er potentielt problem nr. 4, der er anført ovenfor.
    3. Fejlmeddelelsen demonstrerer ExecutionPolicy-begrænsninger i kraft. Det er vores problem nr. 2.
    4. Den understregede del af fejlmeddelelsen (hvilket sker indbygget af PowerShell s fejludgang) viser batchscript var korrekt rettet mod den tilsigtede PowerShell script (D: \ Script Lab \ MyScript.ps1). Så vi ved i det mindste, at meget fungerer ordentligt.

    Profilen er i dette tilfælde et enkelt one-line script, der bruges til denne demonstration til at generere output, når profilen er aktiv. Du kan tilpasse din egen PowerShell-profil til at gøre det også, hvis du selv vil teste disse scripts. Du skal blot tilføje følgende linje til dit profil script:

    Skriv-Output 'Custom PowerShell-profil i kraft!'

    ExecutionPolicy på testsystemet her er indstillet til RemoteSigned. Dette tillader udførelse af scripts oprettet lokalt (som profil scriptet), mens blokering af scripts fra eksterne kilder, medmindre de er underskrevet af en betroet myndighed. Til demonstration blev følgende kommando brugt til at flagge MyScript.ps1 som værende fra en ekstern kilde:

    Add-indhold parameteren PATH 'D: \ Script Lab \ MyScript.ps1' -værdi "[ZoneTransfer] 'nZoneId = 3" -Stream 'Zone.Identifier'

    Det sætter Zone.Identifier alternativ datastream på MyScript.ps1, så Windows vil tro, at filen kom fra internettet. Det kan let vendes med følgende kommando:

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

    Trin 2: Kom godt i gang med ExecutionPolicy.

    At komme rundt i ExecutionPolicy-indstillingen, fra CMD eller et batch script, er faktisk ret nemt. Vi ændrer bare den anden linje i scriptet for at tilføje endnu en parameter til kommandoen PowerShell.exe.

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

    Parameteren -ExecutionPolicy kan bruges til at ændre ExecutionPolicy, der bruges, når du kaster en ny PowerShell-session. Dette vil ikke fortsætte ud over den session, så vi kan køre PowerShell sådan her, når vi har brug for uden at svække systemets generelle sikkerhedsstilling. Nu da vi har rettet det, lad os få en anden gå på det:

    Nu hvor scriptet er korrekt udført, kan vi se, hvad det egentlig gør. Det giver os besked om, at vi kører scriptet som en begrænset bruger. Scriptet bliver rent faktisk kørt af en konto med administratorrettigheder, men brugerkontokontrol er i vejen. Selvom detaljer om, hvordan scriptet kigger efter administratoradgang, er uden for denne artikels anvendelsesområde, her er koden, der bruges til demonstration:

    if (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity] :: GetCurrent ()). IsInRole ([Security.Principal.WindowsBuiltInRole] "Administrator")) Skriv-output 'Running som administrator!' else Write-Output 'Running Limited!' Pause

    Du vil også bemærke, at der nu er to "Pause" -operationer i script-output - en fra PowerShell-scriptet og en fra batchfilen. Årsagen til dette vil være mere tydelig i næste trin.

    Trin 3: Få administratoradgang.

    Hvis dit script ikke kører kommandoer, der kræver højde, og du er helt sikker på, at du ikke behøver at bekymre sig om, at andres tilpassede profiler kommer i vejen, kan du springe resten af ​​dette. Hvis du kører nogle cmdlets på Administrator-niveau, skal du bruge dette stykke.

    Der er desværre ingen mulighed for at udløse UAC for højde fra en batchfil eller CMD-session. PowerShell gør det dog muligt for os at gøre dette med Start-Process. Når det bruges med "-Verb RunAs" i sine argumenter, vil Start-Process forsøge at starte et program med administratorrettigheder. Hvis PowerShell-sessionen ikke allerede er forhøjet, vil dette udløse en UAC-prompt. Hvis du vil bruge dette fra batchfilen til at starte vores script, vil vi ende med at gyde to PowerShell-processer - en til at slukke for Start-Process og en anden, startet af Start-Process, for at køre scriptet. Den anden linje i batchfilen skal ændres til dette:

    PowerShell.exe -kommandoen "& Start-Proces PowerShell.exe -ArgumentList '-ExecutionPolicy Bypass -File "" % ~ dpn0.ps1 ""' -Verb runas"

    Når batchfilen køres, er den første produktionslinje, der ses fra PowerShell profil script. Derefter vil der være en UAC-prompt, når Start-Process forsøger at starte MyScript.ps1.

    Når du har klikket på UAC-prompten, vil en ny PowerShell-instans gyde. Fordi dette er en ny forekomst, vil vi selvfølgelig igen se profilskriftsmeddelelsen. Derefter kører MyScript.ps1 og vi ser, at vi faktisk er i en forhøjet session.

    Og der er grunden til, at vi også har to pauser herinde. Hvis ikke for den i PowerShell-scriptet, ville vi aldrig se scriptets output - vinduet PowerShell ville bare komme op og forsvinde, så snart scriptet er færdigt med at køre. Og uden pausen i batchfilen kunne vi ikke se, om der var nogen fejl, der startede PowerShell i første omgang.

    Trin 4: Kom godt i gang med brugerdefinerede PowerShell-profiler.

    Lad os slippe af med den ubehagelige brugerdefinerede profilbesked nu, skal vi? Her er det næppe endda en gener, men hvis en brugers PowerShell-profil ændrer standardindstillinger, variabler eller funktioner på måder, du måske ikke har forventet med dit script, kan de være meget besværlige. Det er meget enklere at køre dit script uden profilen helt, så du behøver ikke bekymre dig om dette. For at gøre det behøver vi bare at ændre den anden linje i batchfilen en gang til:

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

    Tilføjelse af -NoProfil-parameteren til begge instanser af PowerShell, der lanceres af scriptet, betyder, at brugerens profil script vil blive fuldstændigt omgået i begge trin, og vores PowerShell script vil køre i et forholdsvis forudsigeligt standardmiljø. Her kan du se, at der ikke er nogen brugerdefineret profilmeddelelse i nogen af ​​de skødede skaller.

    Hvis du ikke har brug for administratorrettigheder i dit PowerShell-script, og du har hoppet over trin 3, kan du undvære den anden PowerShell-forekomst, og den anden linje i din batchfil skal se sådan ud:

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

    Udgangen vil derefter se sådan ud:

    (Selvfølgelig, for ikke-administrator scripts, kan du uden en script-pause i dit PowerShell script også på dette tidspunkt, da alt er fanget i det samme konsolvindue og vil blive holdt der ved pause i slutningen af batchfilen alligevel.)

    Afsluttede batchfiler.

    Afhængigt af om du har brug for administratorrettigheder til dit PowerShell-script eller ej, og du burde virkelig ikke anmode om dem, hvis du ikke gør det, skal den endelige batchfil ligne en af ​​de to nedenfor.

    Uden admin adgang:

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

    Med Admin adgang:

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

    Husk at placere batchfilen i samme mappe som PowerShell-scriptet, du vil bruge det til, og giv det samme navn. Så uanset hvilket system du tager disse filer til, vil du kunne køre dit PowerShell-script uden at skulle kaste dig rundt med nogen af ​​sikkerhedsindstillingerne på systemet. Du kan helt sikkert gøre disse ændringer manuelt hver gang, men det sparer dig for problemer, og du behøver ikke bekymre dig om at vende tilbage senere.


    Referencer:

    • Running PowerShell scripts fra en batchfil - Daniel Schroeders Programmeringsblog
    • Kontrol af administratorrettigheder i PowerShell - Hej, Scripting Guy! Blog