Hvordan og hvorfor Windows og PowerShell forhindrer utføring av skript.
PowerShell er effektivt kommandoskallet og skriptspråk som er ment å erstatte CMD- og batchskript på Windows-systemer. Som et slikt, kan et PowerShell-skript ganske mye bli konfigurert til å gjøre alt du kan gjøre manuelt fra kommandolinjen. Det tilsvarer å gjøre praktisk talt enhver endring mulig på systemet ditt, opp til restriksjonene på plass på din brukerkonto. Så hvis du bare kan dobbeltklikke på et PowerShell-skript og kjøre det med full administratorrettigheter, kan en enkel en-liner som dette virkelig ødelegge dagen din:
Get-ChildItem '$env:SystemDrive' -Recurse -ErrorAction SilentlyContinue | Remove-Item -Force -Recurse -ErrorAction SilentlyContinue
IKKE kjør kommandoen ovenfor!
Det går ganske enkelt gjennom filsystemet og sletter alt det kan. Interessant, dette kan ikke gjøre systemet ubrukbart så fort du kanskje tror - selv når du kjører fra en forhøyet økt. Men hvis noen ringer deg etter at du har kjørt dette skriptet, fordi de plutselig ikke kan finne sine filer eller kjøre noen programmer, "slår den av og på igjen", vil sannsynligvis bare lede dem til Windows Startup Repair hvor de skal bli fortalt det er ingenting som kan gjøres for å fikse problemet. Hva som kan være verre er, i stedet for å få et skript som bare ødelegger filsystemet, kan din venn lurte på å kjøre en som laster ned og installerer en keylogger eller ekstern tilgangstjeneste. Deretter, i stedet for å stille deg spørsmål om Startup Repair, kan de ende opp med å spørre politiet noen spørsmål om bank svindel!
Nå skal det være åpenbart hvorfor visse ting er nødvendig for å beskytte sluttbrukere fra seg selv, så å si. Men strømforbrukere, systemadministratorer og andre geeks er generelt (selv om det er unntak) litt mer forsiktig med disse truslene, å vite hvordan de kan oppdage og enkelt unngå dem, og vil bare fortsette å få sitt arbeid gjort. For å gjøre dette må de enten deaktivere eller jobbe rundt noen få veiblokker:
- 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 Scripts på Windows 7, men vi dekker det også på noen få nivåer her.
- PowerShell er ikke knyttet til.PS1 filutvidelsen som standard. Vi tok opp dette opprinnelig i vår PowerShell Geek School-serie. Windows angir standardhandling for.PS1-filer for å åpne dem i Notisblokk, i stedet for å sende dem til PowerShell-kommandotolken. Dette er å forhindre utilsiktet utførelse av ondsinnede skript når de bare er dobbeltklikket.
- 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. For kommandolinjeverktøy kan dette være litt tungvint å si mildt. Vi ønsker ikke å deaktivere UAC, men det er fortsatt hyggelig når vi kan gjøre det litt lettere å håndtere.
Disse samme problemene blir tatt opp i Hvordan bruke en batchfil for å gjøre PowerShell-skript enklere å kjøre, der vi går deg gjennom å skrive en batchfil for midlertidig å komme seg rundt dem. Nå skal vi vise deg hvordan du setter opp systemet med en mer langsiktig løsning. Husk at du ikke generelt bør gjøre disse endringene på systemer som ikke utelukkende brukes av deg - ellers setter du andre brukere i større risiko for å løpe inn i de samme problemene som disse funksjonene er ment å forhindre.
Endre.PS1 filforening.
Den første, og kanskje først, irritasjon for å komme seg rundt, er standardforeningen for.PS1-filer. Å knytte disse filene til noe annet enn PowerShell.exe, er fornuftig for å forhindre utilsiktet utførelse av uønskede skript. Men vurderer at PowerShell kommer med et integrert skriptmiljø (ISE) som er spesielt utviklet for redigering av PowerShell-skript, hvorfor vil vi åpne.PS1-filer i Notisblokk som standard? Selv om du ikke er klar til å bytte fullstendig til å aktivere dobbeltklikk for å kjøre funksjonalitet, vil du sannsynligvis tilpasse disse innstillingene.
Du kan endre.PS1-filforeningen til hvilket program du vil bruke med kontrollpanelet Standardprogrammer, men å grave direkte inn i registret gir deg litt mer kontroll over nøyaktig hvordan filene skal åpnes. Dette lar deg også sette inn eller endre tilleggsalternativer som er tilgjengelige i kontekstmenyen for.PS1-filer. Ikke glem å sikkerhetskopiere registeret før du gjør dette!
Registerinnstillingene som styrer hvordan PowerShell-skript åpnes lagres på følgende sted:
HKEY_CLASSES_ROOTMicrosoft.PowerShellScript.1Shell
For å utforske disse innstillingene før vi går om å endre dem, ta en titt på den nøkkelen og dens undernøkler med Regedit. Shell-nøkkelen skal bare ha en verdi, "(Standard)", som er satt til "Åpne". Dette er en peker til standardhandling for å dobbeltklikke på filen, som vi ser i undernøklene.
Utvid Shell-tasten, og du vil se tre undernøkler. Hver av disse representerer en handling du kan utføre som er spesifikk for PowerShell-skript.
- 0 - Kjør med PowerShell. "Kjør med PowerShell" er faktisk navnet på et alternativ allerede i kontekstmenyen for PowerShell-skript. Teksten er bare trukket fra et annet sted i stedet for å bruke nøkkelnavnet som de andre. Og det er fortsatt ikke standard dobbeltklikk handling.
- Rediger - Åpne i PowerShell ISE. Dette gir mye mer mening enn Notisblokk, men du må fortsatt høyreklikke.PS1 filen for å gjøre det som standard.
- Åpne - Åpne i Notisblokk. Merk at dette nøkkelnavnet også er strengen lagret i "(Standard)" -verdien av Shell-nøkkelen. Dette betyr at dobbeltklikk på filen vil "Åpne" den, og at handlingen normalt settes til bruk Notisblokk.
Hvis du vil holde fast med de forhåndsbygde kommandostrengene som allerede er tilgjengelige, kan du bare endre "(Standard)" -verdien i Shell-tasten for å matche navnet på nøkkelen som samsvarer med det du vil ha et dobbeltklikk med å gjøre. Dette kan enkelt gjøres fra Regedit, eller du kan bruke erfaringer fra vår veiledning om å utforske registeret med PowerShell (pluss en liten PSDrive-tweak) for å begynne å bygge et gjenbrukbart skript som kan konfigurere systemene dine for deg. Kommandoene nedenfor må kjøres fra en forhøyet PowerShell-økt, som ligner på å kjøre CMD som administrator.
Først vil du konfigurere en PSDrive for HKEY_CLASSES_ROOT siden dette ikke er konfigurert som standard. Kommandoen for dette er:
New-PSDrive HKCR Registry HKEY_CLASSES_ROOT
Nå kan du navigere og redigere registernøkler og verdier i HKEY_CLASSES_ROOT akkurat som du ville i de vanlige HKCU og HKLM PSDrives.
For å konfigurere dobbeltklikk for å starte PowerShell-skript direkte:
Set-ItemProperty HKCR:Microsoft.PowerShellScript.1Shell '(Default)' 0
For å konfigurere dobbeltklikk for å åpne PowerShell-skript i PowerShell ISE:
Set-ItemProperty HKCR:Microsoft.PowerShellScript.1Shell '(Default)' 'Edit'
For å gjenopprette standardverdien (sett dobbeltklikk for å åpne PowerShell-skript i Notisblokk):
Set-ItemProperty HKCR:Microsoft.PowerShellScript.1Shell '(Default)' 'Open'
Det er bare grunnleggende om å endre standard dobbeltklikk handling. Vi vil gå nærmere på å tilpasse hvordan PowerShell-skript håndteres når de åpnes i PowerShell fra Explorer i neste avsnitt. Husk at scoping hindrer PSDrives fra å fortsette på tvers av øktene. Så vil du sannsynligvis inkludere New-PSDrive-linjen ved starten av et konfigurasjonsskript du bygger for dette formålet, eller legg det til i PowerShell-profilen din. Ellers må du kjøre den bit manuelt før du prøver å gjøre endringer på denne måten.
Endre PowerShell ExecutionPolicy-innstillingen.
PowerShells ExecutionPolicy er et annet lag av beskyttelse mot utførelse av ondsinnede skript. Det er flere alternativer for dette, og et par forskjellige måter det kan settes på. Fra de fleste til minst sikre er tilgjengelige alternativer:
- Begrenset - Ingen skript får lov til å kjøre. (Standardinnstilling for de fleste systemer.) Dette vil til og med forhindre at profilskriptet ditt kjører.
- AllSigned - Alle skript må være digitalt signert av en klarert utgiver for å kjøre uten å spørre brukeren. Skript signert av utgivere som er uttrykkelig definert som usikre, eller skript som ikke er digitalt signert i det hele tatt, vil ikke kjøre. PowerShell vil spørre brukeren om bekreftelse dersom et skript er signert av en utgiver som ennå ikke er definert som pålitelig eller usikker. Hvis du ikke digitalt har signert profilskriptet ditt og etablert tillit til den signaturen, vil den ikke kunne kjøre. Vær forsiktig med hvilke utgivere du stoler på, siden du fortsatt kan ende opp med å kjøre ondsinnede skript hvis du stoler på den gale.
- RemoteSigned - For skript lastet ned fra Internett, er dette faktisk det samme som "AllSigned". Skript som er opprettet lokalt eller importert fra andre kilder enn Internett, kan imidlertid kjøre uten noen spørsmål om bekreftelse. Her må du også være forsiktig med hvilke digitale signaturer du stoler på, men til og med være mer forsiktig med de ikke-signerte skriptene du velger å kjøre. Dette er det høyeste sikkerhetsnivået under hvilket du kan ha et fungerende profilskript uten å måtte signere det digitalt.
- Ubegrenset - Alle skript får lov til å kjøre, men en bekreftelsespørsmål vil bli krevd for skript fra Internett. Fra dette punktet er det helt opp til deg å unngå å kjøre uverdige skript.
- Bypass - Alt går uten advarsel. Vær forsiktig med denne.
- Udefinert - Ingen policy er definert i det nåværende omfanget. Dette brukes til å tillate tilbakebetaling til politikk definert i lavere rekkevidde (flere detaljer nedenfor) eller til OS-standardene.
Som foreslått av beskrivelsen av Undefined, kan de ovennevnte retningslinjene settes i en eller flere av flere områder. Du kan bruke Get-ExecutionPolicy, med -List parameter, for å se alle rekkevidde og deres nåværende konfigurasjon.
- MachinePolicy representerer en konsernpolitikk som er i kraft på datamaskinnivå. Dette gjelder vanligvis bare i et domene, men kan også gjøres lokalt.
- UserPolicy representerer en konsernpolitikk som er i kraft på brukeren. Dette brukes også bare i bedriftsmiljøer.
- Prosess er et omfang som er spesifikt for denne forekomsten av PowerShell. Endringer i retningslinjene i dette omfanget vil ikke påvirke andre kjørende PowerShell-prosesser, og vil være ineffektive etter at denne økten er avsluttet. Dette kan konfigureres av parameteren -ExecutionPolicy når PowerShell er lansert, eller det kan settes med riktig Sett-ExecutionPolicy-syntaks fra sangen.
- CurrentUser er et omfang som er konfigurert i det lokale registeret og gjelder for brukerkontoen som ble brukt til å starte PowerShell. Dette omfanget kan endres med Set-ExecutionPolicy.
- LocalMachine er et omfang som er konfigurert i det lokale registeret og gjelder for alle brukere på systemet. Dette er standardomfanget som endres hvis Set-ExecutionPolicy kjøres uten -Scope-parameteren. Som det gjelder for alle brukere på systemet, kan det bare endres fra en forhøyet økt.
Siden denne artikkelen hovedsakelig handler om å bevege seg rundt for å lette brukervennlighet, er vi bare opptatt av de tre nedre delene. Innstillingene MachinePolicy og UserPolicy er bare nyttige hvis du vil håndheve en restriktiv politikk som ikke er så enkelt omgått. Ved å holde våre endringer på prosessnivå eller under, kan vi til enhver tid enkelt bruke hvilken politikkinnstilling som vi anser som passende for en gitt situasjon.
For å opprettholde en viss balanse mellom sikkerhet og brukervennlighet, er politikken som vises i skjermbildet sannsynligvis best. Innstilling av LocalMachine-politikken til Begrenset forhindrer generelt kjøreskript av noen andre enn deg. Selvfølgelig kan dette bli omgått av brukere som vet hva de gjør uten mye innsats. Men det bør holde alle ikke-teknologiske kunnskapsrike brukere fra et uhell utløse noe katastrofalt i PowerShell. Å ha CurrentUser (ie.e.: you) sett som Ubegrenset gjør det mulig å manuelt utføre skript fra kommandolinjen, uansett, men beholder en påminnelse om forsiktighet for skript lastet ned fra Internett. Innstillingen RemoteSigned på prosessnivået må gjøres i en snarvei til PowerShell.exe eller (som vi gjør nedenfor) i registretverdiene som styrer oppførselen til PowerShell-skript. Dette vil tillate enkel dobbeltklikk til å kjøre funksjonalitet for eventuelle skript du skriver, samtidig som du oppretter en sterkere barriere mot utilsiktet utførelse av (potensielt skadelig) skript fra eksterne kilder. Vi ønsker å gjøre dette her, siden det er mye lettere å ved et uhell dobbeltklikke på et skript enn det vanligvis er å ringe det manuelt fra en interaktiv sesjon.
For å angi CurrentUser og LocalMachine-retningslinjene som i skjermbildet ovenfor, kjør følgende kommandoer fra en forhøyet PowerShell-økt:
Set-ExecutionPolicy Restricted Set-ExecutionPolicy Unrestricted -Scope CurrentUser
For å håndheve RemoteSigned-politikken på skript som kjører fra Explorer, må vi endre en verdi inne i en av registernøklene vi så på tidligere. Dette er spesielt viktig fordi standardkonfigurasjonen, avhengig av PowerShell- eller Windows-versjonen, kan være å omgå alle Execution Policy-innstillinger, bortsett fra AllSigned. For å se hva den nåværende konfigurasjonen er for datamaskinen din, kan du kjøre denne kommandoen (sørg for at HKCR PSDrive er kartlagt først):
Get-ItemProperty HKCR:Microsoft.PowerShellScript.1ShellCommand | Select-Object '(Default)'
Standardkonfigurasjonen din vil sannsynligvis være en av følgende to strenger, eller noe ganske like:
(Se på Windows 7 SP1 x64, med PowerShell 2.0)
'C:WindowsSystem32WindowsPowerShellv1.0powershell.exe' '-file' '%1'
(Se på Windows 8.1 x64, med PowerShell 4.0)
'C:WindowsSystem32WindowsPowerShellv1.0powershell.exe' '-Command' 'if((Get-ExecutionPolicy ) -ne 'AllSigned') { Set-ExecutionPolicy -Scope Process Bypass }; & '%1''
Den første er ikke så ille, da alt det gjør er å utføre skriptet under de eksisterende Execution Policy-innstillingene. Det kan gjøres bedre, ved å håndheve strammere begrensninger for en mer ulykkesbenlig handling, men dette var ikke opprinnelig ment å bli utløst med et dobbeltklikk uansett, og standardpolitikken er vanligvis begrenset etter alle. Det andre alternativet er imidlertid en full bypass til hva ExecutionPolicy du sannsynligvis har på plass - selv Begrenset. Siden bypasset blir brukt i prosessomfanget, påvirker det bare øktene som lanseres når skript kjøres fra Explorer. Dette betyr imidlertid at du kan ende opp med å lansere skript som du ellers ville forvente (og vil) ha politikk til å forby.
For å angi prosessnivå ExecutionPolicy for skript lansert fra Explorer, i tråd med skjermbildet ovenfor, må du endre den samme registreringsverdien vi nettopp har spurt. Du kan gjøre det manuelt i Regedit, ved å endre det til dette:
'C:WindowsSystem32WindowsPowerShellv1.0powershell.exe' '-ExecutionPolicy' 'RemoteSigned' '-file' '%1'
Set-ItemProperty HKCR:Microsoft.PowerShellScript.1ShellCommand '(Default)' ''C:WindowsSystem32WindowsPowerShellv1.0powershell.exe' '-ExecutionPolicy' 'RemoteSigned' '-file' '%1''
Kjør PowerShell-skript som administrator.
Akkurat som det er en dårlig ide å deaktivere UAC helt, er det også dårlig sikkerhetspraksis å kjøre skript eller programmer med forhøyede rettigheter, med mindre du faktisk trenger dem til å utføre operasjoner som krever administratortilgang. Så det anbefales ikke å bygge UAC-ledeteksten til standardhandling for PowerShell-skript. Vi kan imidlertid legge til et nytt kontekstmenyalternativ som gjør at vi enkelt kan kjøre skript i forhøyede økter når vi trenger det. Dette ligner på metoden som brukes til å legge til "Åpne med Notisblokk" i kontekstmenyen for alle filer - men her skal vi bare målrette mot PowerShell-skript. Vi skal også bære over noen teknikker som ble brukt i forrige artikkel, hvor vi brukte en batchfil i stedet for registerhack for å starte vårt PowerShell-skript.
For å gjøre dette i Regedit, gå tilbake til Shell-nøkkelen, på:
HKEY_CLASSES_ROOTMicrosoft.PowerShellScript.1Shell
Der oppretter du en ny undernøkkel. Kaller det "Kjør med PowerShell (Admin)". Under det, opprett en annen undernøkkel kalt "Command".Sett deretter "(Standard)" -verdien under kommando til dette:
'C:WindowsSystem32WindowsPowerShellv1.0powershell.exe' '-Command' ''& {Start-Process PowerShell.exe -ArgumentList '-ExecutionPolicy RemoteSigned -File '%1'' -Verb RunAs}'
New-Item 'HKCR:Microsoft.PowerShellScript.1ShellRun with PowerShell (Admin)' New-Item 'HKCR:Microsoft.PowerShellScript.1ShellRun with PowerShell (Admin)Command' Set-ItemProperty 'HKCR:Microsoft.PowerShellScript.1ShellRun with PowerShell (Admin)Command' '(Default)' ''C:WindowsSystem32WindowsPowerShellv1.0powershell.exe' '-Command' ''& {Start-Process PowerShell.exe -ArgumentList ''-ExecutionPolicy RemoteSigned -File '%1''' -Verb RunAs}''
Vær også oppmerksom på forskjellene mellom strengen som legges inn gjennom PowerShell og den faktiske verdien som går inn i registret. Spesielt må vi pakke inn hele saken i single-sitater, og dobbeltklikke på de interne single-sitatene, for å unngå feil i kommandoparsering.
Nå bør du ha en ny kontekst-menyoppføring for PowerShell-skript, kalt "Kjør med PowerShell (Admin)".
Finpuss.
Det er bare et par flere tweaks til dette som kan bidra til å gjøre livet enda enklere. For en, hva med å kvitte seg med Notisblokkfunksjonen helt? Kopier bare "(Standard)" -verdien fra kommandotasten under Rediger (under), til samme sted under Åpne.
'C:WindowsSystem32WindowsPowerShellv1.0powershell_ise.exe' '%1'
Eller du kan bruke denne delen av PowerShell (med Admin & HKCR selvfølgelig):
Set-ItemProperty HKCR:Microsoft.PowerShellScript.1ShellOpenCommand '(Default)' ''C:WindowsSystem32WindowsPowerShellv1.0powershell_ise.exe' '%1''
En enda mindre irritasjon er konsollen sin vane å forsvinne når et skript er fullført. Når det skjer, har vi ingen sjanse til å gjennomgå skriptutgangen for feil eller annen nyttig informasjon. Dette kan bli tatt vare på ved å sette en pause på slutten av hvert av skriptene dine selvfølgelig. Alternativt kan vi endre "(Standard)" -verdiene for våre kommandoknapper for å inkludere parameteren "-NoExit". Nedenfor er de endrede verdiene.
(Uten Admin tilgang)
'C:WindowsSystem32WindowsPowerShellv1.0powershell.exe' '-NoExit' '-ExecutionPolicy' 'RemoteSigned' '-file' '%1'
(Med Admin tilgang)
'C:WindowsSystem32WindowsPowerShellv1.0powershell.exe' '-Command' ''& {Start-Process PowerShell.exe -ArgumentList '-NoExit -ExecutionPolicy RemoteSigned -File '%1'' -Verb RunAs}'
Og selvfølgelig vil vi gi deg de i PowerShell-kommandoer også. Siste påminnelse: Elevation & HKCR!
(Non-Admin)
Set-ItemProperty HKCR:Microsoft.PowerShellScript.1ShellCommand '(Default)' ''C:WindowsSystem32WindowsPowerShellv1.0powershell.exe' '-NoExit' '-ExecutionPolicy' 'RemoteSigned' '-file' '%1''
(Admin)
Set-ItemProperty 'HKCR:Microsoft.PowerShellScript.1ShellRun with PowerShell (Admin)Command' '(Default)' ''C:WindowsSystem32WindowsPowerShellv1.0powershell.exe' '-Command' ''& {Start-Process PowerShell.exe -ArgumentList ''-NoExit -ExecutionPolicy RemoteSigned -File '%1''' -Verb RunAs}''
Tar det for et snurr.
For å teste dette ut, skal vi bruke et skript som kan vise oss Execution Policy-innstillingene på plass og om skriptet ble lansert med administratorrettigheter eller ikke. Skriptet vil bli kalt "MyScript.ps1" og bli lagret i "D: Script Lab" på vårt utvalgssystem. Koden er under, for referanse.
if(([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {Write-Output 'Running as Administrator!'} else {Write-Output 'Running Limited!'} Get-ExecutionPolicy -List
Ved hjelp av "Kjør med PowerShell" -handling:
Add-Content -Path 'D:Script LabMyScript.ps1' -Value '[ZoneTransfer]`nZoneId=3' -Stream 'Zone.Identifier'
Zone.Identifier kan fjernes med dette:
Clear-Content -Path 'D:Script LabMyScript.ps1' -Stream 'Zone.Identifier'
Nyttige referanser:
- Kjører PowerShell-skript fra en batchfil - Daniel Schroeders Programmeringsblogg
- Sjekker etter administratorrettigheter i PowerShell - Hei, Scripting Guy! bloggen