PowerShell: objektpipeline, kjøretid og sikker administrasjon

PowerShell er samtidig et interaktivt shell, et skriptspråk og et rammeverk for innebygging. Det skiller det både fra en ren kommandolinje og fra et vanlig programmeringsspråk: Kommandoer leverer typede objekter inn i en pipeline, applikasjoner kan bygge inn motoren i egne prosesser, og adminprodukter publiserer administrasjonsgrensesnittet sitt som cmdlets, providere eller HTTP-API-er. Microsoft beskriver derfor PowerShell som et plattformuavhengig rammeverk for automatisering og konfigurasjon av strukturerte data, REST-grensesnitt og objektmodeller (Microsoft – What is PowerShell?).

For drift er derfor ikke bare syntaksen relevant. Avgjørende er den konkrete utgaven og .NET-kjøretiden, prosess- og runspace-konteksten, innlastede moduler, identiteten på målsystemet, transport og autorisasjon, feilsemantikk samt dokumentasjon av hva et skript faktisk har endret. En kommando som fungerer i en interaktiv økt, er ennå ikke pålitelig automatisering.

Forklaringen følger en kommando gjennom parser, motor, runspace og objektpipeline frem til systemet som kontaktes. Moduler, providere, remoting, parallellitet, sikkerhet og drift knyttes deretter til denne kjøretidsmodellen.

PowerShell er shell, automatiseringsspråk og administrasjonskjøretid samtidig. Det avgjørende er at cmdlets sender .NET-objekter gjennom en pipeline, og at produktmoduler genererer lokale eller eksterne API-kall fra dem. Artikkelen følger denne veien fra kommandoen til virkningen i målsystemet.

Arkitektur for kjøretiden

En PowerShell-kjøring består av flere lag:

LagOppgaveTilstand som er relevant for administratorer
Vertstiller til rådighet konsoll, editor, tjeneste eller innebygd applikasjonvertsnavn, interaktiv/ubevoktet, inndata/utdata, profil
Motorparser språket, binder parametere og koordinerer kommandoerutgave, versjon, .NET, Language Mode, innstillinger
Runspaceisolert kjørekontekst med session stateidentitet, variabler, funksjoner, moduler, drives, endepunkt
Pipelinekobler kommandoprosessorer og transporterer objekter/strømmerrekkefølge, binding, enumerering, feil- og informasjonsstrømmer
Kommandocmdlet, funksjon, skript, alias eller native programkilde, modulversjon, parametere, sideeffekter
Adapter/provider/APIoversetter til .NET, operativsystem, lager eller ekstern tjenesteendepunkt, autentisering, rettigheter, rate limits, feilområde

Verten er ikke motoren. Windows Terminal, den klassiske konsollen, Visual Studio Code, en Scheduled Task eller en applikasjon innebygd i C# kan kjøre den samme PowerShell-motoren på ulike måter. En runspace er driftsmiljøet der kommandoene i en pipeline kjører; flere runspaces i én prosess kan tilby ulike session states og parallellitet (PowerShell Glossary, Microsoft – Runspace samples).

Prosessnavnet er et viktig diagnostisk kjennetegn: powershell.exe starter Windows PowerShell, pwsh den PowerShell-linjen som er basert på moderne .NET. Begge kan være installert side om side på Windows og kan derfor se ulike moduler, profiler, TLS-standardinnstillinger og assemblies. Kommandolinjegrensesnittet til pwsh dokumenterer også hvordan filer, kommandoer, enkodinger og ikke-interaktive kall bindes (Microsoft – about_Pwsh).

Inventariser kjøretid og kontekst

$PSVersionTable viser utgave, motor og plattform; Get-Host beskriver verten, ikke automatisk den underliggende operativsystemversjonen. En reproduserbar feilrapport må minst inneholde prosessbane, utgave, versjon, .NET-beskrivelse, arkitektur, Language Mode og modulbane.

Get-Process -Id $PID | Select-Object Path,Id,StartTime
$PSVersionTable
Get-Host
[System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription
$ExecutionContext.SessionState.LanguageMode
$env:PSModulePath -split [IO.Path]::PathSeparator

Utgaver, .NET og kompatibilitet

Siden PowerShell 5.1 skiller Microsoft mellom utgavene Desktop og Core. Desktop kjører på det Windows-spesifikke .NET Framework; Core kjører på moderne .NET og er tilgjengelig på Windows, Linux og macOS. Feltet CompatiblePSEditions i manifestet til en fremmed modul er imidlertid bare metadata: PowerShell håndhever ikke automatisk kompatibiliteten som angis der (Microsoft – about_PowerShell_Editions).

Windows PowerShell 5.1 og PowerShell 7+ er derfor to separate produkter, ikke to oppstartsalternativer for samme installasjon. PowerShell 7 kan ikke erstatte Windows PowerShell in-place; profiler, modulbaner og deler av API-overflaten er forskjellige. Microsofts migreringsveiledning anbefaler eksplisitt testing av avhengigheter og modulkompatibilitet (Microsoft – Migrating from Windows PowerShell 5.1 to PowerShell 7).

Kompatibilitetsbeslutningen tas per arbeidslast:

  • Motor: Krever skriptet Windows PowerShell/Desktop eller PowerShell/Core?
  • Operativsystem: Kaller det Windows-only-cmdlets, COM, Registry, WMI eller native programmer?
  • Modul: Er det portabelt som skriptmodul, bygget som binærmodul for riktig .NET-målkjøretid eller bare brukbart via en kompatibilitetsprosess?
  • Autentisering: Støtter kjøretiden den nødvendige flyten, sertifikatlageret og tokencachen?
  • Serialisering: Forblir det nødvendige objektet levende lokalt, eller kommer det fra en annen prosess som et deserialisert øyeblikksbilde?
  • Støtte: Angir produsenten nøyaktig denne kombinasjonen av motor, modul og produkt?

PowerShell 7 kan laste utvalgte Windows PowerShell-moduler gjennom en implisitt remoting-/kompatibilitetsøkt. Dette gir imidlertid deserialiserte objekter og en ytterligere prosessgrense; det er ingen erstatning for en innfødt kompatibilitetsbekreftelse (Microsoft – Using Windows PowerShell compatibility).

Når utgave og kjøretid er fastslått, forklarer objektpipelinen den viktigste forskjellen fra tekstorienterte shell: Filtrering, sortering og eksport arbeider med egenskaper i stedet for kolonneposisjoner.

Objektpipelinen

En klassisk Unix-pipeline kobler byte- eller tekststrømmer. PowerShell sender som hovedregel .NET-objekter videre innenfor én prosess. Et objekt har type, egenskaper og metoder; den neste pipelinekomponenten binder inndata etter parameterregler og kan få tilgang til egenskaper uten å parse tabellutdata på nytt (Microsoft – about_Objects, Microsoft – about_Pipelines).

Den synlige tabellen er ikke objektet. Formateringssystemet velger visninger og genererer formateringsinstruksjoner først på slutten av pipelinen. Format-Table og Format-List hører derfor hjemme ved utdataenden; brukes de midt i en datapipeline, mottar ikke etterfølgende kommandoer de opprinnelige administrasjonsobjektene lenger (Microsoft – about_Format.ps1xml).

$service = Get-Service -Name WinRM
$service.GetType().FullName
$service | Get-Member
$service | Select-Object Name,Status,StartType
$service | ConvertTo-Json -Depth 3

Binding, enumerering og strømmer

Pipeline-binding skjer per parameter etter verdi eller egenskapsnavn. Samlinger enumereres vanligvis elementvis; dette endrer oppførsel og minnebehov sammenlignet med én enkelt liste. For pålitelige funksjoner deklareres pipelineparametere eksplisitt, inndata behandles i process-blokken, og utdata forurenses ikke utilsiktet av hjelpeverdier.

PowerShell har flere logiske strømmer: Success, Error, Warning, Verbose, Debug, Information og Progress. Bare Success-strømmen er vanlig objektutdata; feil kan være synlige uten å stanse pipelinen. Omdirigering og sammenslåing av strømmene er en del av kallsgrensesnittet og må fastsettes bevisst for Scheduled Tasks, CI og overvåking (Microsoft – about_Output_Streams).

Native programmer forblir et overgangspunkt. Argumentkvotering, tegnkoding, standardutdata og exitkoder følger ikke fullt ut cmdlet-modellen. En wrapper bør håndtere $LASTEXITCODE, forventede exitkoder, enkoding og stderr, og normalisere resultatet som et eget objekt. At det finnes tekst på stderr, betyr ikke alltid at et program har feilet.

Kommandooppløsning, moduler og providere

Get-Command viser hvilket alias, hvilken funksjon, cmdlet, hvilket skript eller native program som faktisk kalles for et navn. Dette er viktigere enn den synlige skrivemåten: Et alias eller en funksjon med samme navn i profilen kan skjule en cmdlet. Det fullstendig kvalifiserte kallet Modulname\\Verb-Noun gjør opprinnelsen eksplisitt.

Moduler pakker kommandoer, type- og formatdata samt avhengigheter. En skriptmodul bruker vanligvis .psm1, en binærmodul en .NET-assembly; et manifest .psd1 beskriver blant annet rotmodul, versjon, eksporterte kommandoer, krav og kompatible utgaver. Et manifest er ikke obligatorisk for lasting, men kreves for publisering i PowerShell Gallery (Microsoft – about_Modules, Microsoft – about_Module_Manifests).

Motoren søker etter moduler via PSModulePath. Flere installerte versjoner er mulig; automatisk lasting og upresise Import-Module-kall kan derfor velge en annen implementering på en server enn i testmiljøet. Et produksjonsskript inventariserer derfor modulnavn, versjon, bane og repository og fester avhengigheter i deployment i stedet for å etterinstallere dem ukontrollert ved hver kjøring (Microsoft – about_PSModulePath).

Get-Command Get-Mailbox -All |
  Select-Object Name,CommandType,Source,Version,Definition
Get-Module -ListAvailable |
  Sort-Object Name,Version |
  Select-Object Name,Version,Path,CompatiblePSEditions
Get-InstalledModule -ErrorAction SilentlyContinue |
  Select-Object Name,Version,Repository

Providere stiller hierarkiske datalagre med et filsystemlignende grensesnitt til rådighet. FileSystem:, Registry:, Certificate:, Variable:, Function: eller WSMan: ser ut som drives, men har ulike egenskaper og sideeffekter. Før generisk kode brukes Get-PSProvider til å vise hvilke operasjoner en provider støtter. Den historiske språkspesifikasjonen nevner providere og drives som en grunnleggende modell for ellers vanskelig tilgjengelige data (Microsoft – PowerShell language specification, basic concepts).

En lokal kommando kjører i den aktuelle prosessen; remoting flytter kjøringen til en runspace på målet. Dermed endres identitet, nettverksbane, moduler og tilgang til lokale ressurser.

Remoting: lokal klient, transport, ekstern runspace

PowerShell Remoting utfører i utgangspunktet kode på målsiden. Lokalt forberedes kommandoen og argumentene; transport, listener og Session Configuration autentiserer kallet og oppretter en ekstern runspace. Dets operativsystem, motor, moduler, retningslinjer, identitet og nettverkstilgang bestemmer resultatet.

På Windows bruker klassisk remoting WS-Management via WinRM. PowerShell 7 støtter i tillegg SSH-remoting på Windows, Linux og macOS. Begge transportene bærer PowerShell-remotingdata, men tilbyr ikke de samme endepunktfunksjonene: Microsoft påpeker for eksempel at SSH-remoting ikke har PowerShell-endepunktkonfigurasjon og dermed ikke støtter JEA (Microsoft – about_Remote_Requirements, Microsoft – PowerShell remoting over SSH).

Test-WSMan -ComputerName mail01.example.ch
$session = New-PSSession -ComputerName mail01.example.ch -ConfigurationName Microsoft.PowerShell
Invoke-Command -Session $session -ScriptBlock {
  [pscustomobject]@{
    Host = $env:COMPUTERNAME
    Edition = $PSVersionTable.PSEdition
    Version = $PSVersionTable.PSVersion.ToString()
  }
}
Remove-PSSession $session

Verktøyene som brukes, er dokumentert under Test-WSMan, New-PSSession, Invoke-Command og OpenSSH-manualsiden for ssh.

Serialisering og objekttap

De fleste eksterne objekter serialiseres på målet og rekonstrueres lokalt. Resultatet er et øyeblikksbilde med egenskaper, men vanligvis uten metodene til det opprinnelige liveobjektet; typenavnet har ofte prefikset Deserialized.. Formateringsdata og Type-Depth avgjør hvilke egenskaper som overføres. Endringer i det lokale øyeblikksbildet endrer ikke målobjektet (Microsoft – about_Remote_Output).

Filtrering, aggregering og sensitive data behandles derfor så langt som mulig på målet, og bare det nødvendige resultatet overføres. Dette reduserer ventetid, serialiseringsvolum og dataavrenning:

schlecht:  200'000 Remoteobjekte → serialisieren → übertragen → lokal filtern
gut:       remote filtern/projizieren/aggregieren → 200 Ergebnisobjekte übertragen

Den kjente «Second Hop» er ikke en særegenhet ved PowerShell, men en delegeringsgrense: Identiteten som autentiserer seg fra adminklienten mot server A, har ikke automatisk gjenbrukbare påloggingsopplysninger for server B. Løsninger som Kerberos Constrained Delegation, CredSSP eller en tjenestekonto endrer tillitsmodellen og brukes bare med eksplisitt trusselanalyse (Microsoft – Making the second hop in PowerShell Remoting).

Autentisering, autorisasjon og minste privilegium

Remoting skiller mellom fire spørsmål:

  1. Transporttillit: Hvilken vert snakker klienten med, og hvordan kontrolleres nøkkelen eller sertifikatet?
  2. Autentisering: Hvilken person, Managed Identity, app, sertifikat eller SSH-nøkkel logger på?
  3. Autorisasjon: Hvilken Session Configuration, rolle og produktrettighet tillater hvilke operasjoner?
  4. Prosessidentitet: Hvilken lokal eller virtuell konto kjører den eksterne kommandoen faktisk under?

Just Enough Administration (JEA) oppretter begrensede PowerShell-endepunkter. Role Capabilities definerer synlige cmdlets, funksjoner, providere og eksterne programmer; Session Configurations tilordner brukere eller grupper til roller. Virtuelle kontoer eller gMSA-er kan utføre privilegerte handlinger uten å gi brukeren som kaller, en varig administratorkonto. Transkripsjoner og logger støtter sporbarhet (Microsoft – JEA overview).

JEA begrenser ikke automatisk enhver omgåelsesvei. Synlige kommandoer, parametere, providere, filtilgang, kallbare .NET-typer og eksterne programmer må kontrolleres samlet. En tilsynelatende harmløs editor, kompilator eller generisk skriptblokk kan utvide det tiltenkte kommandoomfanget.

Execution Policy, signaturer og applikasjonskontroll

PowerShell Execution Policy er på Windows en sikkerhetsfunksjon mot utilsiktet skriptkjøring, ikke en sikkerhetsgrense. En bruker som har tillatelse til å kjøre kommandoer, kan kalle innholdet i et blokkert skript på andre måter. På systemer som ikke er Windows, håndheves ikke policyen på samme måte som i Windows (Microsoft – about_Execution_Policies).

AllSigned og RemoteSigned bruker Authenticode for å kontrollere opprinnelse og integritet for bestemte PowerShell-filtyper. En gyldig signatur sier imidlertid bare at filen ikke er endret siden signeringen og passer til en klarert sertifikatkjede; den beviser ikke at koden er sikker eller faglig riktig (Microsoft – about_Signing).

En robust kontrollkjede kombinerer:

  • Source Control, gjennomgang og uforanderlige byggeartefakter;
  • signatur- og hashkontroll;
  • kontrollerte modul-repositories og avhengighetsversjoner;
  • App Control/System Lockdown eller tilsvarende applikasjonskontroll;
  • identitet med minste privilegium og begrensede remoting-endepunkter;
  • hemmeligheter utenfor kildekoden;
  • Script Block/Module Logging, transkripsjoner og sentral loggforsendelse.

Microsoft klassifiserer Execution Policy som Defense-in-Depth, mens App Control i System Lockdown kan fastsette Language Mode per runspace. Script Block Logging skriver behandlede kommandoer, funksjoner og skript til PowerShell Operational Log; mer omfattende logging kan i seg selv registrere hemmeligheter (Microsoft – PowerShell security features).

Kontroller signatur og artefakt

Get-AuthenticodeSignature kontrollerer Authenticode-statusen under Windows; Get-FileHash og sha256sum sammenligner en artefakt med en forventet verdi som er publisert uavhengig.

$script = 'C:\\Ops\\Deploy-MailPolicy.ps1'
Get-AuthenticodeSignature $script |
  Select-Object Status,StatusMessage,SignerCertificate,TimeStamperCertificate
Get-FileHash $script -Algorithm SHA256
Get-ExecutionPolicy -List

Hemmeligheter og ikke-interaktive identiteter

En SecureString er ikke et hvelv. Microsoft anbefaler at passord om mulig erstattes av sertifikater, Windows-autentisering eller andre passordløse metoder i ny utvikling. SecretManagement-modulen tilbyr et enhetlig cmdlet-grensesnitt for Extension Vaults; det registrerte hvelvet implementerer lagring og autentisering. Registreringen er brukeravhengig, noe som må tas hensyn til for tjenestekontoer og headless-automatisering (Microsoft – PowerShell security features, Microsoft – Understanding SecretManagement).

For hver automatisering dokumenteres separat:

  • Arbeidslastidentitet: Tjenestekonto, gMSA, Managed Identity, App Registration eller sertifikat;
  • Kilde for legitimasjon: Hvelv, sertifikatlager, workload-federation eller interaktiv broker;
  • Rettighet: Lokal rolle, RBAC-rolle, API-scope eller Application Permission;
  • Livssyklus: Utstedelse, rotasjon, utløp, tilbakekalling og Break Glass;
  • Kjøringssted: Agent, Scheduled Task, runner, Function eller adminklient;
  • Nettverksbane: DNS, proxy, TLS Trust, endepunkt og rate limit;
  • Revisjonsanker: Run-ID, identitets-ID, kodecommit og endrings-/ticket-ID.

Miljøvariabler og pipelinevariabler er transportmekanismer, ikke sikre lagre. De kan havne i underprosesser, dumps, diagnoseutdata eller CI-logger. Også tilgang til et hvelv begrenses til minst mulig secret-scope og kort levetid.

Sikker automatisering må oppdage om en operasjon faktisk har feilet. En rød melding, et unntak, en ikke-terminerende feil og en native exitkode er ulike signaler.

Feilsemantikk: Synlig rød linje er ikke en exitmodell

PowerShell skiller mellom ikke-terminerende, statement-terminerende og skript-terminerende feil. Mange cmdlets skriver en ikke-terminerende ErrorRecord for ett enkelt objekt og fortsetter å behandle resten av pipelinen. En try/catch fanger bare feil som forlater den kontrollerte blokken; -ErrorAction Stop kan eskalere egnede ikke-terminerende feil for dette kallet (Microsoft – about_Error_Handling, Microsoft – about_Try_Catch_Finally).

Produksjonskode definerer derfor:

  • hvilke feil per objekt som tolereres og logges;
  • hvilke feil som avbryter hele kjøringen;
  • hvilken exitkode prosessen leverer til scheduler eller CI;
  • om retry er sikkert og idempotent;
  • hvilken korrelasjons-ID som knytter feil, målobjekt og API-forespørsel sammen;
  • hvilke ressurser som lukkes i finally-blokken;
  • hvordan delvise endringer oppdages og kompenseres.
$ErrorActionPreference = 'Stop'
try {
  $result = Invoke-RestMethod -Uri $endpoint -Method Get -TimeoutSec 30
  $result | ConvertTo-Json -Depth 10
}
catch {
  Write-Error -ErrorRecord $_
  exit 1
}
finally {
  Remove-Variable result -ErrorAction SilentlyContinue
}

Eksempelet bruker Invoke-RestMethod, der HTTP- og feilatferd bevisst må inngå i feilhåndteringen. For native programmer kontrolleres også $LASTEXITCODE. Prosessvariabelen $? og PowerShell-feilstrømmene erstatter ikke en dokumentert kontrakt om exitkodene til det kalte programmet.

Sikker endringssemantikk og idempotens

En automatisering for administratorer skiller mellom innhenting, planlegging, endring og verifisering. Den sammenligner faktisk og ønsket tilstand ved hjelp av stabile ID-er, oppretter et eksplisitt endringssett og utfører bare den nødvendige differansen. Deretter leser den tilstanden på nytt via det relevante grensesnittet. «Cmdleten returnerte ingen feil» er ikke tilstandsbevis.

Advanced Functions kan med SupportsShouldProcess tilby Common Parameters -WhatIf og -Confirm. Funksjonen kaller $PSCmdlet.ShouldProcess() rett før sideeffekten. Microsoft dokumenterer imidlertid begrensninger ved videresending av WhatIfPreference mellom skriptmoduler; en vellykket -WhatIf er derfor en nyttig forhåndsvisning, ikke en transaksjonell garanti (Microsoft – Everything about ShouldProcess, Microsoft – about_CommonParameters).

En robust endringsprosess beholder:

  1. uforanderlig mål-ID og tidligere tilstand;
  2. forventet differanse og faglig godkjenning;
  3. brukt identitet, endepunkt- og modulversjon;
  4. svar-/forespørsels-ID fra målsystemet;
  5. tilstand lest på nytt og avhengig funksjonstest;
  6. rollback- eller roll-forward-regel fra Point of No Return.

Idempotens er en egenskap ved operasjonen og tilstandsmodellen dens, ikke ved språket. Set-* kan være idempotent, Add-* vanligvis ikke; en HTTP-PUT-operasjon kan gjentas, mens en POST oppretter et nytt objekt ved hvert retry. Før automatisk retry avklares API-semantikk, request-ID og serverstatus.

Parallellitet, jobber og runspaces

PowerShell kan parallellisere arbeid gjennom Background Jobs, Thread Jobs, Remoting Jobs, ForEach-Object -Parallel eller egne runspace-pooler. Disse modellene er ulike når det gjelder prosessisolasjon, serialisering, oppstartskostnad og delt tilstand. Eksterne jobber og prosessjobber serialiserer objekter; Thread Jobs og runspaces deler en prosess og kan dermed være raskere, men også mindre isolerte (Microsoft – about_Jobs, Microsoft – ForEach-Object -Parallel).

Optimal parallellitet begrenses av målsystemet:

  • API-rate-limit og Retry-After;
  • maksimalt antall remoting-sheller og operasjoner per bruker;
  • LDAP-/databaseforbindelsespool;
  • Exchange-throttling og cmdlet-kostnader;
  • minne per runspace og størrelse på serialiserte objekter;
  • krav til rekkefølge og låsing på målet;
  • feilbudsjett og evne til målrettet omstart.

Flere tråder øker ikke automatisk gjennomstrømmingen. Et adminskript måler kølengde, ventetid, suksessrate og throttling, begrenser samtidighet og bruker jitter/backoff. Det lagrer et sjekkpunkt per målobjekt i stedet for å gjenta hele batchen blindt etter en delfeil.

Produktmoduler og HTTP-API-er

PowerShell er ofte bare klientsiden av en ekstern control plane. Cmdleten kan validere parametere lokalt og deretter kontakte REST, WSMan, RPC, CIM eller et proprietært API. Feilområdet omfatter da lokal motor, modul, tokeninnhenting, DNS, proxy, TLS, API-versjon, autorisasjon, throttling og produkttjenesten.

Microsoft Graph PowerShell SDK genererer cmdlets fra Graph-API-metadataene. Rettigheter forblir Graph-rettigheter; cmdletnavnet opphever ikke Delegated-versus-Application-semantikk, consent og ressursbegrensninger (Microsoft – Microsoft Graph PowerShell overview). ExchangeOnlineManagement-modulen tilbyr Exchange-spesifikke cmdlets og bruker REST-baserte forbindelser for en rekke operasjoner; Exchange- og Graph-grensesnittene er ikke utskiftbare API-er til tross for overlappinger (Microsoft – About the Exchange Online PowerShell module).

Før en produksjonskjøring lagres følgende:

NivåSkal logges
Klientmotor/utgave, prosess, operativsystem, tidssone
Koderepository, commit, signert artefakt, konfigurasjon
Avhengighetmodulnavn, versjon, bane, repository, hash
IdentitetObject-/App-ID, autentiseringstype, Tenant/Realm
Rettighetroller, scopes, consent, Endpoint/Session Configuration
Forespørselmål-ID, operasjon, Correlation-/Request-ID, tidspunkt
Resultatstatus, feilklasse, retry, endret tilstand
Verifiseringuavhengig readback- eller protokollkontroll

Feilsøkingen starter derfor med kjørekonteksten: utgave, vert, bruker, språk, modulversjon og remotingbane. Først deretter undersøkes målproduktet.

Diagnose: først kjørekontekst, deretter målprodukt

En PowerShell-feil undersøkes langs de faktiske avhengighetene:

  1. Kall: Hvilken prosess, vert, bruker, Working Directory, profil- og NonInteractive-modus?
  2. Oppløsning: Hvilken kommando og modulversjon brukes faktisk?
  3. Lokal policy: Language Mode, App Control, Execution Policy, Trust Store og proxy?
  4. Transport: Er DNS, TCP, TLS, WSMan/SSH eller HTTPS tilgjengelig?
  5. Autentisering: Hvilken flyt, token/nøkkel/sertifikat, klokkeslett og tenant?
  6. Autorisasjon: Hvilken lokal rolle, JEA Capability, API-scopes og produktroller?
  7. Måltilstand: Finnes objektet under den brukte stabile ID-en og i riktig scope?
  8. Serversvar: Feilkode, request-ID, throttling, revisjons- og produktlogg?

Test-NetConnection kontrollerer TCP-tilgjengelighet på Windows, nc på Unix-systemer. Dette beviser verken vellykket TLS- eller applikasjonsautentisering, men skiller en tilkoblingsfeil fra høyere lag. Get-WinEvent leser Event Logs i Windows; journalctl leser systemd-journalen.

Test-NetConnection mail01.example.ch -Port 5986 -InformationLevel Detailed
Get-WinEvent -LogName 'Microsoft-Windows-PowerShell/Operational' -MaxEvents 100 |
  Select-Object TimeCreated,Id,LevelDisplayName,Message
Get-Command Invoke-Command -All |
  Select-Object CommandType,Source,Version,Definition

Logging, transkripsjoner og personvern

PowerShell kan bruke Script Block Logging, Module Logging, Protected Event Logging og Transcription. I Windows vises Script Block-hendelser i kanalen Microsoft-Windows-PowerShell/Operational. Start-Transcript registrerer tekstrepresentasjonen av en økt; det er ikke en fullstendig strukturert revisjonslogg og registrerer ikke all aktivitet utenfor verten (Microsoft – about_Logging).

Logging øker synligheten, men også risikoen for å lagre tokens, passord, e-postinnhold eller personopplysninger. Microsoft anbefaler Protected Event Logging for sensitive Script Block-logger. I tillegg defineres oppbevaring, tilgang, sentral videresending, tidssynkronisering og manipulasjonssikker lagring (Microsoft – PowerShell security features).

For egne automatiseringer er strukturerte hendelser bedre egnet enn fritt formaterte konsolltekster. En hendelse inneholder minst tidspunkt i UTC, Run-ID, kodeversjon, mål-ID, handling, resultat, varighet, request-ID og en klassifisert feilårsak. Hemmeligheter og unødvendige payloads fjernes før logging.

Kvalitetskontroll og deployment

Invoke-ScriptAnalyzer kontrollerer PowerShell-kode med statiske regler. Det finner mange stil-, kompatibilitets- og sikkerhetsproblemer, men erstatter verken tester eller produktintegrasjon. En robust pipeline omfatter:

  • parser- og analysekontroll;
  • unit tests for rene funksjoner og dataavbildning;
  • contract tests mot API-skjemaer og mock-svar;
  • integrasjonstest med minst mulige rettigheter;
  • -WhatIf/planutdata der det er faglig mulig;
  • test av tomme mengder, duplikater, paginering, throttling og delvise feil;
  • signering, hash og uforanderlig artefakt;
  • trinnvis utrulling med måleverdier og avbruddskriterier;
  • uavhengig readback-verifisering på målsystemet.

Profiler utelates som regel i produksjonsautomatisering med -NoProfile. Ikke-interaktive prosesser bruker -NonInteractive, definerte enkodinger, eksplisitte baner og en fast tidssone. Deployment leverer moduler med eller bruker et kontrollert internt repository; det installerer ikke ukritisk den nyeste avhengigheten ved hver kjøring.

Teknisk historie

Jeffrey Snover formulerte i Monad Manifesto en enhetlig, objektorientert administrasjonsmodell: små verktøy, konsekvent navngivning, felles parser- og pipelinefunksjon samt administrative grensesnitt via .NET. Microsoft beskriver dokumentet som utgangspunktet for utviklingen som senere ble PowerShell (PowerShell Team – Monad Manifesto).

I april 2006 ga Microsoft prosjektet, som ble utviklet under kodenavnet Monad, navnet Windows PowerShell; den første produktlinjen var tett bundet til Windows og .NET Framework (Microsoft Windows Server Blog – Monad’s new name). I denne linjen oppstod cmdlet-konvensjonene med verb-substantiv, objektpipelinen, providere, remoting, moduler, workflows og Desired State Configuration.

I 2016 publiserte Microsoft PowerShell under MIT-lisensen og utviklet en plattformuavhengig linje basert på .NET Core. PowerShell Core 6 ga støtte for Linux/macOS og SSH-remoting; PowerShell 7 fortsatte produktnavnet uten «Core». Kodebasen og utviklingen for PowerShell 7+ ligger i det offentlige repositoryet; endringer tilbakeporteres ikke til Windows PowerShell 5.1 (PowerShell GitHub repository, PowerShell Team – Announcing PowerShell 7).

Denne historien forklarer mange av dagens driftsgrenser: to utgaver på Windows, moduler med .NET Framework-avhengigheter, ulike remotingtransporter og en blanding av lokale Windows-administrasjonsgrensesnitt og plattformuavhengige HTTP-API-er. For administratorer er PowerShell derfor mindre «ett versjonsnummer» enn en konkret kombinasjon av motor, kjøretid, modul, transport og målprodukt.

Hva en administrator bør dokumentere på et øyeblikk

Et skript er først driftsklart når kjøretid, moduler, identitet, målsystem og feilhåndtering er kjent i tillegg til koden. Tabellen oppsummerer minste dokumentasjon som trengs.

SpørsmålMinste dokumentasjon
Hvilken PowerShell kjører?prosessbane, PSEdition, PSVersion, .NET, OS/arkitektur
Hva kjøres?løst CommandType, Source, Version, Definition
I hvilken kontekst?vert, runspace, profilmodus, Working Directory, Language Mode
Med hvilke avhengigheter?modulbane, manifest, versjon, repository, hash
Mot hvilket mål?endepunkt, Tenant/Realm, stabil objekt-ID, API-/Session-versjon
Med hvilken identitet?bruker/app/Managed Identity, authflow, sertifikat-/key-ID
Med hvilke rettigheter?lokal rolle, JEA Endpoint, scopes, produkt-RBAC
Hva skal endres?faktisk/ønsket differanse, plan, scope, godkjenning
Hva ble faktisk endret?serversvar, request-ID, readback og funksjonstest
Hvordan håndteres en delfeil?ErrorAction, exitkode, retry, sjekkpunkt, kompensasjon
Hvordan revideres det?Run-ID, strukturerte logger, Transcript/Operational Log, oppbevaring
Hvordan gjentas eller rulles det tilbake?idempotensnøkkel, Point of No Return, roll-forward/-back

Kilder

Nye artikler på e-post

En kort melding når en ny praktisk artikkel om meldinger, sikkerhet eller Microsoft 365 publiseres.

Adressen brukes bare til nyhetsbrevet. Avslutt med ett klikk. Personvern

Forstørret infografikk