9Sep

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 er forhåndskonfigurert for å tillate kjøring av vilkårlig skript, med de nødvendige privilegiene, og ved hjelp av de riktige innstillingene, er det sjansene 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 skript kjøring 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 Scripts 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 om du kjører 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 fint når vi kan gjøre det litt enklere å håndtere.
  4. Noen brukere kan ha tilpassede PowerShell-miljøer.
    Du vil sannsynligvis ikke komme inn på dette ofte, men når du gjør det, kan det gjøre kjører og feilsøking av skriptene litt frustrerende. Heldigvis kan vi komme seg 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 å omskrive 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 altdet tar å 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( @) symbolet foran den.

PowerShell.exe -Command "&'% ~ Dpn0.ps1' " driver 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 pause 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å noen kommandoutgang før vinduet forsvinner. Når vi går gjennom testing av hvert trinn, vil nytten av dette bli tydeligere.

Så grunnleggende batchfilen er 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 batch-skriptet 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 utgang 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:

Write-Output 'Custom PowerShell-profilen i kraft!'

ExecutionPolicy på testsystemet her er satt til RemoteSigned. Dette tillater utførelse av skript som er 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'

Som setter Zone. Identifier alternativ datastrøm 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: Komme rundt ExecutionPolicy.

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

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

Parameteren -ExecutionPolicy kan brukes til å endre 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 den generelle sikkerhetsstillingen i systemet. 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 det utenfor denne artiklens omfang, her er koden som brukes til demonstrasjon:

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

Du vil også merke at det nå er toPause-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, lansert av Start-prosess, for å kjøre skriptet. Den andre linjen i batchfilen må endres til dette:

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

Når batchfilen kjøres, er den første produksjonslinjen som kommer 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 hekte seg. Fordi dette er en ny forekomst, ser vi selvfølgelig igjen profilskriptet. 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 pauser her inne 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 som startet PowerShell i utgangspunktet.

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

La oss kvitte oss med denne ekkel tilpassede profilmeldingen nå, skal vi? Her er det nesten ikke 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} "

Legge til -NoProfil-parameteren i begge instansene av PowerShell som lanseres av skriptet, betyr at brukerens profilskript vil bli helt omgått i begge trinnene, og vårt PowerShell-skript vil kjøre innet ganske forutsigbart, standardmiljø.Her kan du se at det ikke er noen tilpasset profilvarsling 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 -ExecutionPolis Bypass-Kommando "& '%% dpn0.ps1'"

Utgangen vil da se slik ut:

( Selvfølgelig, for ikke-administratorskript, kan du gjøre uten en pause i scriptet i PowerShell-skriptetpå dette punktet også siden alt er fanget i samme konsollvindu og vil bli holdt der ved pause i slutten av batchfilen uansett.)

Fullførte batchfiler.

Avhengig av om du trenger administratorrettigheter for PowerShell-skriptet ditt, eller ikke, bør du ikke be om dem hvis du ikke gjør det. Den endelige batchfilen skal se ut som en av de to nedenfor.

Uten Admin-tilgang:

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

Med Admin tilgang:

@ECHO AV 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 haå bruke den til, og gi den samme navn. Så, uansett hvilket system du tar disse filene til, vil du kunne 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 å få problemer, og du trenger ikke å bekymre deg for å tilbakestille endringene senere.

Referanser:

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