Hjemmeside » hvordan » Slik bruker du en batchfil for å gjøre PowerShell-skript enklere å kjøre

    Slik bruker du en batchfil for å gjøre PowerShell-skript enklere å kjøre

    Av flere grunner er de fleste sikkerhetsrelaterte, PowerShell-skriptene ikke like lett bærbare og brukbare som batchskript kan være. Vi kan imidlertid pakke et batch script med våre PowerShell-skript for å løse disse problemene. Her vil vi vise deg noen av disse problemområdene, og hvordan du bygger et batch script for å komme seg rundt dem.

    Hvorfor kan jeg ikke bare kopiere min .PS1-fil til en annen datamaskin og kjøre den?

    Med mindre målsystemet har blitt forhåndskonfigurert for å tillate kjøring av vilkårlig skript, med de nødvendige privilegiene, og ved hjelp av de riktige innstillingene, er det sjanse for at du kommer til å løbe inn i noen problemer når du prøver å gjøre dette.

    1. PowerShell er ikke knyttet til .PS1 filutvidelsen som standard.
      Vi tok opp dette opprinnelig i vår PowerShell Geek School-serie. Windows forbinder .PS1-filer til Notisblokk som standard, i stedet for å sende dem til PowerShell-kommandotolken. Dette er for å forhindre utilsiktet utførelse av ondsinnede skript ved å dobbeltklikke dem. Det er måter du kan endre denne oppførselen på, men det er sannsynligvis ikke noe du vil gjøre på hver datamaskin du bærer skriptene dine til - spesielt hvis noen av disse datamaskinene ikke er dine egne.
    2. PowerShell tillater ikke ekstern scriptutførelse som standard.
      Innstillingen Execution Policy i PowerShell forhindrer utførelse av eksterne skript som standard i alle versjoner av Windows. I enkelte Windows-versjoner tillater ikke standard i det hele tatt script-utførelse. Vi viste deg hvordan du endrer denne innstillingen i Slik tillater du å utføre PowerShell-skript på Windows 7. Dette er imidlertid også noe du ikke vil gjøre på bare hvilken som helst datamaskin.
    3. Noen PowerShell-skript fungerer ikke uten administratorrettigheter.
      Selv å kjøre med en Administrator-nivå-konto, trenger du fortsatt å gå gjennom User Account Control (UAC) for å utføre bestemte handlinger. Vi vil ikke deaktivere dette, men det er fortsatt hyggelig når vi kan gjøre det litt lettere å håndtere.
    4. Noen brukere kan ha tilpassede PowerShell-miljøer.
      Du vil sannsynligvis ikke løpe inn i dette ofte, men når du gjør det, kan det føre til å løpe og feilsøke skriptene litt frustrerende. Heldigvis kan vi komme rundt dette uten å gjøre noen permanente endringer også.

    Trinn 1: Dobbeltklikk for å kjøre.

    La oss starte med å ta opp det første problemet - .PS1 filforeninger. Du kan ikke dobbeltklikke for å kjøre .PS1-filer, men du kan kjøre en .BAT-fil på den måten. Så skriver vi en batchfil for å ringe PowerShell-skriptet fra kommandolinjen for oss.

    Så vi trenger ikke å skrive om batchfilen for hvert skript, eller hver gang vi flytter et skript rundt, skal det benytte seg av en selvreferansevariabel for å bygge filbanen for PowerShell-skriptet. For å gjøre dette arbeidet må batchfilen plasseres i samme mappe som PowerShell-skriptet ditt, og har samme filnavn. Så hvis PowerShell-skriptet ditt heter "MyScript.ps1", vil du ha navnet på batchfilen "MyScript.bat" og sørg for at den er i samme mappe. Sett deretter disse linjene i batch-skriptet:

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

    Hvis det ikke var for de andre sikkerhetsrestriksjonene på plass, ville det virkelig være alt som trengs for å kjøre et PowerShell-skript fra en batchfil. Faktisk er de første og siste linjene bare et spørsmål om preferanse - det er den andre linjen som virkelig gjør jobben. Her er nedbrytingen:

    @ECHO OFF slår av kommandoen ekko. Dette holder bare dine andre kommandoer fra å vises på skjermen når batchfilen kjører. Denne linjen er selv skjult ved bruk av at (@) symbolet foran den.

    PowerShell.exe -Command "& '% ~ dpn0.ps1'" Kjører faktisk PowerShell-skriptet. PowerShell.exe kan selvfølgelig bli kalt fra et CMD-vindu eller en batchfil for å starte PowerShell til en bare konsoll som vanlig. Du kan også bruke den til å kjøre kommandoer rett fra en batchfil, ved å inkludere parameteren -Command og passende argumenter. Måten dette brukes til å målrette mot .PS1-filen, er med den spesielle% ~ dpn0-variabelen. Kjør fra en batchfil, evaluerer% ~ dpn0 til stasjonsbokstaven, mappebanen og filnavnet (uten utvidelse) av batchfilen. Siden batchfilen og PowerShell-skriptet vil være i samme mappe og ha samme navn, vil% ~ dpn0.ps1 oversette til hele filbanen i PowerShell-skriptet.

    PAUSE stopper bare batch-utførelsen og venter på brukerinngang. Dette er generelt nyttig å ha på slutten av batchfilene dine, slik at du har mulighet til å gjennomgå hvilken kommandoutgang som helst før vinduet forsvinner. Når vi går gjennom testing av hvert trinn, vil nytten av dette bli tydeligere.

    Så er den grunnleggende batchfilen satt opp. For demonstrasjonsformål lagres denne filen som "D: \ Script Lab \ MyScript.bat" og det er en "MyScript.ps1" i samme mappe. La oss se hva som skjer når vi dobbeltklikker på MyScript.bat.

    Selvfølgelig kjørte PowerShell-skriptet ikke, men det kan man forvente - vi har jo bare tatt opp det første av våre fire problemer. Det er imidlertid noen viktige biter vist her:

    1. Vinduets tittel viser at batchskriptet vellykket startet PowerShell.
    2. Den første produksjonslinjen viser at en tilpasset PowerShell-profil er i bruk. Dette er potensielt problem # 4, oppført ovenfor.
    3. Feilmeldingen demonstrerer ExecutionPolicy-restriksjoner i kraft. Det er vårt problem # 2.
    4. Den understrekte delen av feilmeldingen (som er gjort naturlig av PowerShells feilutgang) viser at batchskriptet var riktig målrettet mot det påtatte PowerShell-skriptet (D: \ Script Lab \ MyScript.ps1). Så vi vet i det minste at mye fungerer som det skal.

    Profilen, i dette tilfellet, er et enkelt enlinjeskript som brukes til denne demonstrasjonen for å generere produksjon når profilen er aktiv. Du kan tilpasse din egen PowerShell-profil for å gjøre dette også, hvis du vil teste disse skriptene selv. Bare legg til følgende linje i profilskriptet ditt:

    Skriv-utgang 'Tilpasset PowerShell-profil i kraft!'

    ExecutionPolicy på testsystemet her er satt til RemoteSigned. Dette tillater utførelse av skript opprettet lokalt (som profilskriptet), mens blokkering av skript fra eksterne kilder, med mindre de er signert av en klarert autoritet. For demonstrasjonsformål ble følgende kommando brukt til å flagge MyScript.ps1 som fra en ekstern kilde:

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

    Det setter Zone.Identifier alternativ datastrømmen på MyScript.ps1 slik at Windows vil tro at filen kom fra Internett. Det kan enkelt reverseres med følgende kommando:

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

    Trinn 2: Kom deg rundt ExecutionPolicy.

    Å komme seg rundt Execution Policy-innstillingen, fra CMD eller et batch script, er faktisk ganske enkelt. Vi endrer bare den andre linjen i skriptet for å legge til en parameter til PowerShell.exe-kommandoen.

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

    Parameteren -ExecutionPolicy kan brukes til å modifisere ExecutionPolicy som brukes når du henter en ny PowerShell-økt. Dette vil ikke vare utover den økten, slik at vi kan kjøre PowerShell slik som helst når vi trenger uten å svekke systemets generelle sikkerhetsstilling. Nå som vi har løst det, la oss få en annen gå til det:

    Nå som skriptet er riktig utført, kan vi se hva det egentlig gjør. Det gir oss beskjed om at vi kjører skriptet som en begrenset bruker. Skriptet kjøres faktisk av en konto med administratorrettigheter, men brukerkontokontroll blir i veien. Selv om detaljer om hvordan skriptet kontrollerer administratortilgang, er utenfor rammen av denne artikkelen, her er koden som brukes til demonstrasjon:

    hvis (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity] :: GetCurrent ()). IsInRole ([Security.Principal.WindowsBuiltInRole] "Administrator")) Skriv-utgang 'Kjører som administrator!' ellers Write-Output 'Running Limited!' Pause

    Du vil også merke at det nå er to "Pause" -operasjoner i skriptutgangen - en fra PowerShell-skriptet og en fra batchfilen. Årsaken til dette vil bli tydeligere i neste trinn.

    Trinn 3: Få administratoradgang.

    Hvis skriptet ikke kjører noen kommandoer som krever høyde, og du er ganske sikker på at du ikke trenger å bekymre deg for at noen tilpassede profiler kommer i veien, kan du hoppe over resten av dette. Hvis du kjører noen Administrator-nivå cmdlets skjønt, trenger du dette stykket.

    Dessverre er det ikke mulig å utløse UAC for høyde fra en batchfil eller CMD-økt. Men, PowerShell tillater oss å gjøre dette med Start-Process. Når det brukes med "-Verb RunAs" i sine argumenter, vil Start-Process forsøke å starte et program med administratorrettigheter. Hvis PowerShell-økten ikke allerede er forhøyet, vil dette utløse en UAC-prompt. For å bruke dette fra batchfilen for å starte vårt skript, vil vi ende opp med å spionere to PowerShell-prosesser - en til brann fra Start-prosess og en annen, startet av Start-prosess, for å kjøre skriptet. Den andre linjen i batchfilen må endres til dette:

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

    Når batchfilen kjøres, er den første linjen med utdata som vi ser, fra PowerShell-profilskriptet. Deretter vil det være en UAC-prompt når Start-Process prøver å starte MyScript.ps1.

    Etter å ha klikket gjennom UAC-prompten, vil en ny PowerShell-forekomst gyte. Fordi dette er en ny forekomst, vil vi selvfølgelig igjen se profilskriften. Deretter kjører MyScript.ps1 og vi ser at vi faktisk er i en forhøyet økt.

    Og det er grunnen til at vi har to pause her også. Hvis ikke for den i PowerShell-skriptet, ville vi aldri se skriptets utgang - PowerShell-vinduet ville bare komme opp og forsvinne så snart skriptet er ferdig. Og uten pause i batchfilen, ville vi ikke kunne se om det var noen feil å starte PowerShell i utgangspunktet.

    Trinn 4: Komme i gang med tilpassede PowerShell-profiler.

    La oss bli kvitt den ubehagelige tilpassede profilmeldingen nå, skal vi? Her er det ikke engang en plage, men hvis en brukerens PowerShell-profil endrer standardinnstillinger, variabler eller funksjoner på måter du kanskje ikke har forventet med skriptet ditt, kan de være veldig plagsomme. Det er mye enklere å kjøre skriptet uten profilen helt, slik at du ikke trenger å bekymre deg for dette. For å gjøre det, trenger vi bare å endre den andre linjen i batchfilen en gang til:

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

    Hvis du legger til -NoProfile-parameteren i begge instanser av PowerShell som lanseres av skriptet, betyr det at brukerens profilskript vil bli helt omgått i begge trinnene, og vårt PowerShell-skript vil kjøre i et ganske forutsigbart, standardmiljø. Her kan du se at det ikke er noen egendefinert profilvarsel i noen av de skjulte skjellene.

    Hvis du ikke trenger administratorrettigheter i PowerShell-skriptet, og du har hoppet over trinn 3, kan du gjøre det uten den andre PowerShell-forekomsten, og den andre linjen i batchfilen din skal se slik ut:

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

    Utgangen vil da se slik ut:

    (Selvfølgelig, for ikke-administratorskript, kan du gjøre uten pause i PowerShell-skriptet ditt akkurat nå, siden alt er fanget i samme konsollvindu og vil bli holdt der ved pause på slutten av batchfilen uansett.)

    Fullførte batchfiler.

    Avhengig av om du trenger Administrator-tillatelser for PowerShell-skriptet ditt (eller du burde ikke be dem om du ikke gjør det), må den endelige batchfilen se ut som en av de to nedenfor.

    Uten administrasjon:

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

    Med Admin tilgang:

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

    Husk å sette batchfilen i samme mappe som PowerShell-skriptet du vil bruke den til, og gi den samme navn. Så, uansett hvilket system du tar disse filene til, kan du kjøre PowerShell-skriptet ditt uten å måtte kvele med noen av sikkerhetsinnstillingene på systemet. Du kan sikkert gjøre disse endringene manuelt hver gang, men dette sparer deg for problemer, og du trenger ikke å bekymre deg for å vende om endringene senere.


    referanser:

    • Kjører PowerShell-skript fra en batchfil - Daniel Schroeders programmeringsblogg
    • Sjekker etter administratorrettigheter i PowerShell - Hei, Scripting Guy! bloggen