Category Archives

11 Articles

Guide/Windows 7

En liten guide om brukere på Windows 7 i ett hjemmemiljø

Posted by ragnar harper on

Her kommer en liten brukerveiledning på hvordan man kan effektivt sette opp brukere på Windows i ett hjemmemiljø. Den sier for eksempel litt om hvordan man kan sette opp kontoer med visse begrensninger.

Det er å anbefale at alle som benytter en datamaskin har sin egen bruker på maskinen. På denne måten kan man avgrense hva andre har adgang til, og man kan dele det man ønsker å dele.

Du har i hovedsak to ulike typer brukere – Administrator og standardbruker. En administrator har rettigheter til å konfigurere datamaskinen samt bestemme hvilke programmer som skal være installert. En standardbruker har rettigheter til å bruke det som finnes av programmer på datamaskinen (i utgangspunktet), og får sine egne filområder for å oppbevare filer. En standardbruker kan også konfigurere innstillinger som ikke påvirker andre brukere.

image

Opprette brukerkontoer og endre brukerkontoer

Fra kontrollpanelet kan du åpne brukerkonto administrering ved å klikke på Brukerkontoer og familiesikkerhet.

image

Om du ikke finner dette valget når du har åpnet kontrollpanelet, sjekk at du har valgt riktig visning. Den skal være Vis etter kategori

image

Om du ønsker å legge til eller fjerne en brukerkonto kan du også starte dette direkte fra kontrollpanelet ved å klikke på snarveien til operasjonen.

Etter at du har startet Brukerkontoer og familiesikkerhet skal vi legge til en brukerkonto. Dette gjør vi ved å velge ”Legg til eller fjern brukerkontoer”.

image

Etter å ha åpnet vinduet for å legge til eller fjerne brukerkontoer får du opp en liste med brukerkontoene som finnes på datamaskinen. Du vil minst se to kontoer, den som ble definert under installasjonen av Windows 7 samt Gjest. Vi skal ikke benytte Gjest brukeren her, da det anbefales at den holdes deaktivert.

For å opprette en ny konto trykker du nå på ”Opprett ny konto”.

image

Du vil nå få opp vinduet hvor du angir brukerens navn, og hvilken type brukerkonto det skal være. Det anbefales å opprette brukerkontoer av typen Standardbruker da dette gir høyest sikkerhet på datamaskinen.

image

Du vil nå finne brukeren du opprettet i lista over brukere. Om du ønsker å endre denne brukeren videre, kan du nå dobbeltklikke på brukerkontoen.

image

Hva kan du endre på brukerkontoen?

Du kan utføre følgende :

  • Endre kontonavn
  • Opprette passord
  • Endre bildet
  • Konfigurere sperrefunksjoner
  • Endre kontotypen
  • Slett kontoen

image

Jeg anbefaler at du oppretter et passord med en gang. På den måten har du bedre kontroll over dine egne filer. Om brukeren er av typen administrator anbefaler jeg på det sterkeste at brukeren har passord. Hvis ikke kan hvem som helst logge seg med adgang til maskinen logge seg på som administrator.

Du oppretter et passord ved å klikke på Opprett passord. Hvis du ikke oppretter ett passord når du lager brukerkontoen, kan du få problemer med å gjøre det senere. Problemer vil være om brukeren har opprettet EFS-krypterte filer, personlige sertifikater eller har lagrede passord for webområder /nettverksressurser. Disse vil brukeren isåfall miste! Jeg anbefaler derfor at du oppretter passord med engang, slik at brukeren ikke har informasjon av denne typen.

image

For å unngå tap av informasjon om brukeren skulle glemme passordet bør du opprette en diskett for å tilbakestilling av passord. Dette trenger ikke å være en diskett i tradisjonell fortstand, men kan like gjerne være en USB minnepinne.

Brukeren oppretter denne på følgende måte:

  • Brukeren hvis passord vi skal sikre logger seg på datamaskinen
  • Sett inn en USB-minnepinne eller diskett i datamaskinen
  • I søkefeltet på Startmenyen skriver du ”Passord”
  • Start ”Opprett en diskett for å tilbakestille passord”
    image
  • Følg veiviseren
    • Klikk
      Neste i første steg
    • Når du blir bedt om å angi stasjonsbokstav, velg enheten du ønsker å kopiere passordet til.
    • Skriv inn kontoens passord når du blir bedt om det

Konfigurer sperrefunksjoner

Sperrefunksjoner hjelper deg med å kontrollere og sperre for hva enkelte eller alle brukere kan gjøre. Du kan bestemme hvilke tidspunkt en bruker kan benytte datamaskinen, hvilke typer spill de kan spille, og hvilke programmer de kan kjøre. Hvis brukeren prøver å starte ett blokkert program eller spill vil han få beskjed om at dette er blokkert. Brukeren kan da trykke på en link, og be om adgang. Du kan da gi tilgang ved å skrive inn ditt (eller en administrators) brukernavn og passord.

For å konfigurere sperrefunksjoner må du være pålogget som administrator. Brukerne du ønsker å kontrollere må være standard brukerkontoer.

Det finnes også tredjeparts tillegg til Sperrefunksjonene som kan gi enda flere kontrollfunksjoner, for eksempel over Internett bruk.

Hvordan ta i bruk Sperrefunksjoner:

1. I søkefeltet på Startmenyen skriver du ”Sperrefunksjon”

2. Velg Sperrefunksjoner fra listen
image

3. I vinduet for Sperrefunksjoner som nå dukker opp vil du se en liste over alle definerte brukere på datamaskinen. Du kan nå velge brukeren du ønsker å konfigurere sperrefunksjoner på ved å dobbeltklikke på den.
image

· Det neste vinduet du får opp benyttes for å slå Sperrefunksjonen av og på for den angitte brukeren. Ved å velge ”På, fremtving gjeldene innstillinger” blir valgene for Sperre innstillinger aktive.
image

· For eksempel kan du velge Tidsbegrensninger og styre når brukeren kan benytte datamaskinen. Om brukeren prøver å logge på i et blokkert tidsrom vil han få beskjed om at kontoen ikke er tillatt brukt på nåværende tidspunkt. Om brukeren er pålogget når tidsbegresningen inntrer vil brukeren få beskjed, og deretter logget av datamaskinen.
image

· Du kan også sperre spill basert på klassifisering. Det betyr at du kan blokkere spill som inneholder Diskriminering, Narkotika, Sex, er skremmende, har upassende språkbruk eller inneholder vold. Du kan også definere hvilke aldersgrenser spillet må være tilpasset for.
image

· Det er også mulig å påvirke eksplisitt hvilke spill på datamaskinen brukeren får spille, eller som er blokkert for denne brukeren.
image

· På samme måte som med spill kan du også bestemme hvilke programmer brukeren skal få lov til å benytte. Om du tar i bruk denne funksjonen må du velge alle programmene som brukeren faktisk får kjøre.
image

Da har vi vært igjennom hvordan man kan sette opp brukerkontoer, og begrense hva disse får lov til. Håper dette er til nytte for flere der ute Smile

Guide/Windows 7

En liten introduksjon til bibliotek (Library) i Windows 7

Posted by ragnar harper on

Ofte vil du ha behov for å organisere same type informasjon i ulike mapper. For eksempel kan det være at du har bilder liggende i din private mappe, samt i mapper du deler med andre. Eller du kan ha arrangert bildene dine i mapper av andre årsaker. Ved å bruke bibliotek kan du samle alle disse mappene under ett felles navigasjonspunkt. Et bibliotek kan inneholde mapper fra ulike lokasjoner, for eksempel ulike disker eller til og med nettverkslokasjoner. Gjennom biblioteket kan du finne alle disse filene fra ett og samme sted.

Som standard kommer Windows 7 med biblioteker for Dokumenter, Bilder, Musikk og Video.

Hvorfor bruke bibliotek?

Bibliotek har flere egenskaper enn standard mapper. For eksempel kan du i et bibliotek vise frem filer uavhengig av hvilke mapper de ligger i. Du kan med andre ord bruke andre egenskaper ved fila for å bestemme hvordan filene skal grupperes.

Standardvisningen gir deg en visning gruppert etter mapper.

image

Du kan selv velge hvilken egenskap du ønsker å gruppere innholdet i biblioteket på gjennom å endre ”Ordne etter”.

For eksempel har jeg merket bildene mine med nøkkelord (tagg) og kan derfor enkelt gruppere bildene mine etter tagg.

image

Merk at bildene er gruppert etter tagg uavhengig av hvilken mappe de ligger i – så lenge mappen er en del av bibliotekets lokasjoner.

Her viser jeg bildene ordnet etter dag.

image

Hvordan endre hvilke lokasjoner som finnes i ett bibliotek

1. Start Windows Utforsker

2. Høyreklikk på biblioteket ”Dokumenter”, og velg Egenskaper fra menyen.

image

3. Du kan nå se hvilke lokasjoner som er inkludert i biblioteket under ”Bibliotekplasseringer”. Du kan legge til andre mapper ved å trykke ”Inkluder en mappe”. Du kan også fjerne en lokasjon ved å markere den i listen og trykke ”Fjern”.
For å bestemme hva som er standard lagringssted for nye dokumenter i biblioteket markerer du mappen du vil skal være standardvalget, og trykker ”Angi lagringsplassering”.

image

Figur : Egenskaper til bibliotek

Som du ser av figuren over så er standard mappe for nye filer i biblioteket ”Mine Dokumenter” (du ser det av haken som er plassert på venstre side av Mine dokumenter i listen). Det betyr at filer jeg legger inn i biblioteket havner i denne mappen om jeg ikke aktivt velger en annen mappe.

Om du ønsker å lagre i en annen lokasjon kan du velge fra alle bibliotekets lokasjoner i Windows Utforsker treet. Dette er vist i figuren under. Ved å velge Felles dokumenter fra denne listen kan jeg gå inn i den mappen.

image

Si ifra om det er andre beskrivelser eller guider dere vil jeg skal skrive Smile

Oppdatering 19.09 : Legge til lokasjoner fra delte mapper (network shares, unc paths osv)

Om du får melding om at lokasjonen ikke kan inkluderes fordi den ikke er indeksert kan du omgå dette ved å benytte andre verktøy for å legge til lokasjonen.

image

Du finner ett enkelt verktøy på http://zornsoftware.talsit.info/?p=3 som hjelper deg med dette.

Guide/Infrastruktur2.0

Infrastruktur 2.0–En kort oversikt

Posted by ragnar harper on

Hvorfor Infrastruktur 2.0?

Hvordan vi tenker rundt, designer og implementerer vår grunnleggende infrastruktur har endret seg lite iløpet av de siste 10-15 årene.
De siste årene har det skjedd endringer som snur på dette – virtualisering har blitt modent, automatisering har blitt tatt til nye høyder, og vi har blitt virkelig mobile.
I tillegg har Internett har gått fra å være en transportmekanisme, til å bli en tjenesteleverandør.

image

Bedriftene søker å bli mer og mer smidig – og opplever at tjenester på Internett er enkelt å ta i bruk.

En del bedrifter opplever også det vi kaller Peak IT

“Peak IT opptrer i en organisasjon når investeringene i automatisering og produktivitetsverktøy blir borte i økt drift og vedlikeholdskostnader. Dette resulterer i en nedadgående spiral med økt kompleksitet og kostnader samt tap av effektiv produktivitet”

Når så nye tjenester innføres i bedriftens eget datarom oppdager man at verden ikke nødvendigvis er like fleksibel og enkel. En ny tjeneste som innføres i bedriften trenger å være tilgjenglig fra hvor som helst, man trenger å ha backupløsninger og sikkerhetskopier. Den trenger også serverkraft, og denne serverkraften trenger ikke å være statisk. Enkelte applikasjoner har bruksmønstre som varierer sterkt. I en tradisjonell infrastruktur tar vi ofte høyde for toppene , og dimensjonerer etter disse. Dette kan bety at vi har en dårlig utnyttelsesgrad på våre servere (selv med virtualisering).

Videre definerer vi ofte sikkerheten etter hvor informasjonen fysisk ligger lagret. Vi benytter NTFS rettigheter, Share rettigheter – og eventuellt kryptering som EFS eller Bitlocker. Felles for alle disse er at de beskytter så lenge informasjonen ligger på angitte sted. Om vi flytter informasjonen til en USB stasjon (som ikke har BitLocker-To-Go), sender den på epost eller lagrer den i nettskyen – mister vi kontrollen med informasjonen.

I en gjennomsnittelig bedrift ligger identiteten lagret flere steder. Om en person slutter, er det mange steder vi må avslutte brukeren. Og det er lett å glemme alle stedene. Ikke minst gjelder dette adganger inn hos våre partnere – hvor også vår ansatt har egne brukere. Hvor mange har rutiner for å varsle partnere om at en persons adgang til systemene skal avsluttes. Tenk for eksempel på personer som driver med innkjøp. Disse har som regel kontoer med kredittrettigheter hos leverandørene. Når en person slutter som innkjøper, hender det ofte at disse kontoene ikke blir avsluttet. På denne måten kan man fortsatt logge seg inn, og plassere ordre. Problemet kan være stort nok på innsiden av egen bedrift, og blir ikke mindre mellom bedrifter.

Whatever_07
Infrastruktur 1.0 –> IT-Pro til venstre, og bruker til høyre.

For tilgang til våre interne systemer fra utsiden brukes en mengde ulike teknologier. Vi har VPN (og naturligvis ulike typer av VPN), HTTP(S), Terminal Server, RPC over HTTP(S) osv. Brukeren må læres opp i hvilken teknologi han skal benytte for adgang til de ulike systemene. Dette betyr gjerne flere pålogginger, og ikke så rent sjelden frustrasjon hos brukeren. I vår tradisjonelle infrastruktur har vi også DMZ, og de fleste tjenestene som er tilgjenglig fra utsiden går via DMZ, og eventuellt videre inn til en intern datasenter sone. Dette betyr at vi må ha egne dedikerte servere som kun benyttes for å gi våre brukere adgang fra utsiden. Disse serverne er ofte dedikerte, og gir som regel adgang til kun en tjeneste på innsiden. Tjenestene har ikke sjelden egne protokoller, egne sikkerhetsinnstillinger og egne behov. Dette betyr at vi øker kompleksiteten i våre løsninger. Økt kompleksitet betyr redusert sikkerhet og driftbarhet.

drawbridge-defense-7079
Infrastruktur 1.0 er en borg – vi beskytter kun det som er på innsiden

Infrastruktur 2.0 handler om hvordan du bygger ett dynamisk datasenter som lett knyttes til nettskyen. Infrastruktur 2.0 handler om hvordan du beskytter informasjonen – uansett hvor den fysisk lagres eller ligger. Infrastruktur 2.0 handler om en standardisert måte å håndtere identitet på –også utenfor egen bedrift. Infrastruktur 2.0 handler om hvordan du gir adgang til interne systemer – uten å bygge dedikerte servere i DMZ til hver enkelt tjeneste. Infrastruktur 2.0 handler om smidighet, fleksibilitet og sikkerhet. Infrastruktur 2.0 handler om ett datasenter som er virtuellt – og hvor tjenestene leveres fra egne servere, nettskyen og partnere.

Infrastruktur 2.0 krever at vi endrer hvordan vi tenker rundt, designer og implementerer vår grunnleggende infrastruktur.

Guide/Infrastruktur2.0

Infrastruktur 2.0 – en liten guide

Posted by ragnar harper on

Nå som ferien er over er det vel på tide å få skrevet litt igjen. Jeg har de siste to årene jobbet mye med det jeg kaller “Infrastruktur 2.0”, og jeg har tenkt å skrive en liten artikkel serie om dette.

IT-industrien har vært igjennom en del endringer også tidligere, og denne gangen skjer det virkelig ett paradigmeskifte. Jeg tenker selvsagt på nettskyen. Skal du jobbe i IT de kommende årene bør du sette deg grundig inn i nettskyen. (og Powershell bør du uansett beherske….)

Infrastruktur 2.0 handler om hvordan vi bygger en infrastruktur som er dynamisk og fleksibel, gir oss frigjøring fra fysisk lokasjon, samt støtter IT-løsninger lokalt, hos partnere og i nettskyen. De fleste kommer til å få hybrider – hvor de har løsninger kjørende flere steder.

Med en slik endring i tilnærming må vi også endre hvordan vi designer og implementerer grunnleggende komponenter i vår infrastruktur. Virtualisering er selvsagt en viktig egenskap for ditt datasenter – det samme gjelder automatisering og brukervennlige løsninger fjernadgang til ditt datasenter.  Vi må også strekke identiteten vår ut i nettskyen og til partnere, vi må ivareta informasjonsflyt mellom applikasjoner som kjører i ulike datasentre – og vi må sørge for informasjonssikkerhet uavhengig av den fysiske lokasjon til informasjonen.

Jeg tenker å ta for meg de siste elementene i denne serien – integrasjon mellom tjenestene, identitet og informasjonssikkerhet. Mitt fokus kommer til å ligge rundt Microsoft sine produkter og løsninger.

Guide/Powershell

Kom igang med Powershell – del 7 – Administrasjon av Windows

Posted by ragnar harper on

Dette er artikkel 7 i min Kom igang med Powershell guide og omhandler administrasjon av Windows.

Tidligere artikler har vært:

Del 6 : Feilsøking og debugging
Del 5 : Formatering og gruppering
Del 4 : Utvikle script med Powershell
Del 3 : Sikkerhet i Powershell
Del 2 : Basis Powershell kunnskap (2/2)
Del 1 : Basis Powershell kunnskap (1/2)

Håndtering av filer og kataloger

Ofte får man behov for å håndtere filer og kataloger med script. Vi skal her se på de vanlige behovene for opprettelse, lesing og sletting av filer og kataloger.

Opprettelse av filer og kataloger

Vi starter med opprettelse av fil:

New-item mintekstfil.txt –type File –Value ”Dette er fila mi”

Kjøringen av kommandoen feiler hvis fila finnes fra før. Hvis man ønsker å overskrive fila (hvis den finnes fra før) så bruker man parameteren –force.

New-Item mintekstfil.txt –type File –value “Skriver over..” –force

Hvis du ønsker å opprette en katalog istedet, så går du frem på omtrent samme måte:

New-Item MinKatalog –type Directory

Vi kan bruke –Path hvis vi ønsker å si klart ifra hvor fila eller katalogen skal opprettes.

New-Item –path c:\logfiles\MinLogg.log –type file

En annen måte å opprette filer på er ved å benytte redirection eller pipelineing. Dette er ofte det raskeste hvis vi ønsker at resultatet av en kommando eller operasjon skal inn i ei fil.

La oss lage ei fil med alle skriverne som er definert på maskinen (på en linje):

Get-WmiObject win32_printer | format-table Name,PrinterStatus > printerliste.txt

I kommandoen over benytter vi > til å skrive resultatet til fil. Enkel > oppretter fila, og skriver til den. Hvis fila finnes fra før, overskrives fila. Andre ganger har vi behov for å skrive til ei fil som finnes, og legge data eksisterende innhold. Dette kan vi benytte >> til. Ved å benytte >> opprettes også fila hvis den ikke finnes fra tidligere.

Tenk at du skal lage en logg som viser hver gang et script er kjørt:

Get-Date >> ScriptLogg.log

En del script ønsker man å ta tiden på, og skrive dette til en loggfil.

$start = Get-Date
# utfør script
$stopp = Get-Date
$stopp.Subtract($start) | format-table Days,Hours,Minutes,Seconds,Milliseconds >> ScriptLogg.log

Den siste linjen trekker starttidspunktet fra sluttidspunktet, og skriver resultatet til fila scriptlogg.log. Merk at linja som starter med $stopp.Subtract skal skrives på en linje.

Ok, dette kan også gjøres enklere med kommandoen Measure-Command :

Measure-Command {dir c: -recurse }
Lesing av filer

Mange script må lese inn filerog håndtere disse videre. Get-Content gjør dette for oss:

Get-content tekstfil.txt

Hvis vi ønsker å vise et bestemt antall linjer fra fil benytter vi –TotalCount parameteren.

Get-Content c:\serverlist.txt –TotalCount 5

Kommandoen over henter frem de første fem linjene av fila, og skriver disse ut. En annen måte å gjøre dette på er å benytte Select-Object CmdLet’en. Denne tilbyr mer funksjonalitet, også muligheten for å vise et bestemt antall linjer fra bunnen(slutten) av fila.

Get-Content c:\serverlist.txt | Select-object –last 5

Hvis vi med select-object skulle hentet ut de første fem linjene hadde vi benyttet -first istedet for -last.

Kopiering av filer

Av og til trenger man også å kopiere filer. Dette utføres med Copy-Item cmdlet’en.

Copy-Item *.log c:\logfiles

Copy-Item har også aliaset copy.

NB! Hvis du prøver å utføre tilsvarende operasjon som Copy *.log *.old så vil ikke PowerShell utføre denne operasjonen for deg! Det funker fint i cmd.exe , men av en eller annen grunn takler ikke PowerShell wildcards og kopiering hvor kildefilene og målfilene ligger i samme mappe.

Her er en workaround for dette problemet:

BulkCopy.ps1

Set-Location “C:\logs”
$files = get-childitem | where { $_.extension –eq “.log” }
Foreach($file in $files)
{
$filename=($file.FullName).ToString()
$arr=@($filename.split(“.”))
$newname=$arr[0]+”.old”
Write-Host “copying “$file.FullName “to” $newname
Copy $file.fullname $newname -force
}
Sletting av filer og kataloger

Til å slette filer og kataloger benytter vi Remove-Item. Hvis du ønsker å slette alle tmp filer i katalogen c:\temp kan du kjøre følgende kommando:

Remove-item c:\temp\*.txt

La oss si at du ønsker å fjerne alle loggfilene som er eldre enn 2006, og at året er en del av navnet:

Remove-Item C:\backup\*.* -recurse –exclude 2006*.log

Du kan også benytte –include. Selv om du på kommandoene finner parameteren –identity, så er ikke dette implementert i første versjon av PowerShell. (Hvis du for eksempel tenke å kjøre kommandoen som en annen enn den som var logget på)

Du sletter kataloger på samme måte som du sletter filer, men til det kan du også benytte aliaset rmdir, slik som sletting av filer har aliasene erase og del.

Rename filer

Det hender også at vi trenger å gi filene nytt navn, og til å gjøre dette har vi kommandoen Rename-Item.

Rename-Item aktivlogg.txt passivlogg.txt

En svakhet med Rename-Item kommandoen er at den heller ikke støtter wildcards. Så på samme måte med BulkCopy.ps1, må vi lage et script som endrer navnet på flere filer i en operasjon:

BulkRename.ps1

Set-Location “C:\Logs”
$files=Get-ChildItem –recurse | Where { $_.extension –eq “.log” }
Foreach ($file in $files)
{
$filename = ($file.name).ToString()
$arr=@($filename.split(“.”))
$newname=$arr[0] + “.old”
Write-Host “renaming “$file.fullname “to “$newname
Rename-item $file.fullname $newname -force
}
Test om filer og baner finnes

Med Test-Path kan vi sjekke om en katalog eller fil finnes. Den returnerer true hvis fila eller katalogen finnes, og false hvis ikke.

Test-Path c:\temp

Håndtering av rettigheter

Ettersom at alle objekter i Windows inneholder en ACL (Access Control List) som styrer tilgangen til objektet, har vi bruk for å kunne scripte disse adgangene. Det betyr for eksempel at vi kan lese av eller sette adgangen til filer,kataloger og registrynøkler.

La oss lese av rettighetene til fila boot.ini som finnes på rota av c:\

get-acl c:\boot.ini

Resultatet av denne kommandoen kan oppleves litt vanskelig å lese, og de fleste vil nok heller benytte følgende kommando:

Get-acl c:\boot.ini | format-list

Kommandoen kan benyttes mot filer, kataloger og registrynøkler. (Og eventuelt andre objekter hvor det finnes en provider som tilbyr dette.) (Kommandoen under er på en linje)

Get-Acl HKLM:\software\microsoft\windows\currentversion\run | format-list

La oss si at du ønsker å hente ut informasjon om hvem som er eier av filer og kataloger på c:\. Dette kan du enkelt hente ut med Get-Acl på følgende måte:

Get-Acl C:\* | format-table Path,Owner -autosize

Ser du nøye på parametrene til kommandoen vil du se at den mangler –recurse. Hvis du ønsker å ta ut rapporten på en mappestruktur (altså ta med undermappene også) kan følgende script kjøres:

GetOwnerReport.ps1

$report = “C:\OwnerReport.csv” #navn på fila som rapporten lagres i
$startingDir = Read-Host “Hvilken katalog vil du starte i?”
Get-ChildItem $startingDir –recurse | Get-Acl | Select Path,Owner | Export-Csv $report –NoTypeInformation
Write-Host “Rapporten er ferdig.”

Å lese rettigheter er enkelt med PowerShell. Dessverre kan vi si at å sette rettigheter ikke er like rett frem i dagens versjon av PowerShell. Faktisk er dette enklere med kommandoer som Cacls og Icacls, og jeg kommer til å demonstere begge mulighetene, så får du velge selv.

Årsaken til at PowerShell kan være vanskelig å bruke til dette er at den krever kunnskap om .NET sikkerhetsmodellen og hvordan en NTFS security descriptor skal bygges opp.

ChangeAcl.ps1

$Right=”FullControl” #rettigheten vi skal gi
$startingDir = Read-Host “Hvilken katalog vil du starte i?”
$principal= Read-Host “Hvilken bruker vil du gi Full Control til?`nBenytt formatet domene\brukernavn eller domene\gruppe”
$rule=new-object System.Security.AccessControl.FileSystemAccessRule ($principal, $right, “Allow”)
Foreach($file in $(Get-ChildItem $startingDir –recurse))
{
$acl=get-acl $file.Fullname
Write-Host –foregroundcolor Yellow $file.Fullname
$acl.SetAccessRule($rule)
Set-acl $file.Fullname $acl
$acl=get-acl $file.Fullname
Write-Host –foregroundcolor Green “Nye rettigheter”
Write-Host $acl.AccessToString `n
}

De verdiene du kunne ha puttet inn I $right variabelen er:

  • ListDirectory
  • ReadData
  • WriteData
  • CreateFiles
  • CreateDirectories
  • AppendData
  • ReadExtendedAttributes
  • WriteExtendedAttributes
  • Traverse
  • ExecuteFile
  • DeleteSubdirectoriesAndFiles
  • ReadAttributes
  • WriteAttributes
  • Write
  • Delete
  • ReadPermissions
  • Read
  • ReadAndExecute
  • Modify
  • ChangePermissions
  • TakeOwnership
  • Synchronize
  • FullControl

Selve jobben som scriptet utfører kan identifiseres i følgende linjer:

$acl=Get-acl $file.Fullname

Deretter legger vi til den nye rettigheten i $acl

$acl.SetAccessRule($rule)

Håndtering av eventlogger

Logger er gull, er et uttrykk jeg benytter ved en del anledninger. Men det kan være vanskelig å finne gullet, og hvordan kommer man til det?

Med PowerShell er det enkelt å jobbe med eventlogger gjennom CmdLet’en Get-EventLog.

For å se hvilke eventlogger du har tilgjenlig kan du kjøre følgende kommando:

Get-EventLog –list

For å hente ut informasjon fra Application kan du kjøre:

Get-EventLog Application

Dette er som regel ikke av interesse å dumpe hele eventloggen uten å filtrere på noen som helst måte.

La oss forsøke å hente ut de fem siste hendelsene:

Get-EventLog Application –newest 5

Ettersom at resultatet skrives ut i tabellformat kan det være avkortet. For å se fullstendig informasjon formaterer vi som liste ved å benytte format-list:

Get-EventLog Application –newest 5 | Format-List

For å filtrere mer kan vi benytte Where. La oss si at vi ønsker å finne en gitt eventid:

Get-EventLog Application | where { $_.eventid –eq 1018}

Hva så hvis vi ønsker å hente ut de fem siste (tidsmessig) hendelsene med eventid 1018?

(kjør neste kommando på ei linje)

Get-EventLog Application | where { $_.eventid –eq 1018 } | select –first 5

Hva hvis du ønsker å skrive ut de fem siste Error meldingene? Type event lagres i feltet EntryType, så da må vi benytte EntryType i where setningen :

Get-EventLog Application | where { $_.EntryType –eq “Error” } | select –first 5

Ønsker du å hente ut advarsler (warnings) bytter du ut Error med Warning:

Get-EventLog Application | where { $_.EntryType –eq “Warning” } | select –first 5

La oss kombinere EntryType og Source (fortsatt skal alt på en linje):

Get-EventLog Application | where { $_.EntryType –eq “Error” –and $_.Source –eq “WinMgmt” }

Eventloggene er også et område hvor regular expressions gjør stor nytte. La oss ta et enkelt søk i System loggen for alle meldinger som inneholder ordet ”disk”:

Get-Eventlog System | where { $_.Message –match ”disk” }

image

Get-Eventlog fungerer fint så lenge scriptet kjøres på den maskinen som du skal lese loggene fra. Men hva hvis du skal hente informasjon fra en annen maskin? Med Powershell 1.0 måtte du da benytte WMI. Powershell 2.0 har fått parameteren –ComputerName også på Get-EVentLog.

Kommandoen kan ta en tid, spesielt hvis det er mange poster i loggen du gjennomgår.

Håndtering av registry

Vi har vel over tid erfart at registry er stedet hvor applikasjoner går inn, og ingen helt vet hva som kommer ut av det. Det er ingen tvil om at selv om .NET skal befri oss fra dll-hell og et overbelastet registry, må vi inn i registry for å gjøre en del oppgaver. Registry er stedet hvor mye lagres, spesielt konfigureringer. En av PowerShells fordeler er at den behandler registry som enhver annen lokasjon eller katalog om du vil. Du kan altså navigere deg inn i registry direkte fra shellet, la oss gå inn i HKEY_LOCAL_MACHINE :

Cd hklm:
dir

Eller hva med HKEY_CURRENT_USER:

Cd hkcu:
dir

La oss se på hvordan vi kan lese informasjon fra registry. Vi kan finne hvilken Windows versjon som er installert, og hvem den er installert til på følgende måte:

$regpath="HKLM:\Software\Microsoft\Windows NT\CurrentVersion"
$regkey=Get-ItemProperty $regpath
$regkey

image

Vi kan selvsagt også angi banen vi skal lese fra direkte:

Get-ItemProperty "hklm:\software\microsoft\windows\currentversion\uninstall\imgburn"

Hvis du ønsker å se verdier der du står, kan du ikke benytte dir (eller Get-ChildItem) til dette. De kommandoene gir deg kun kataloger (eller nøkler) som ligger under området der du står. For å lese av verdiene der du står, benytter du . (punktum) på følgende måte:

Get-ItemPropery .

I tillegg til å lese av verdier trenger vi å endre samt opprette verdier i registry. La oss se på hvordan vi kan endre verdier med Set-ItemProperty.

Set-ItemProperty -path . –name Domain –value ”DittDomene”

MERK! Hvis du kjører Vista med User Account Control aktivert (som er default) krever dette at PowerShell kjører som administrator. Hvis ikke får du feilmelding, med beskjed om at du ikke har rettigheter. For å kjøre PowerShell som administrator høyreklikker du på PowerShell snarveien, og velger Run As Administrator.

For å se om verdien ble satt kan du nå kjøre følgende kommando som kun henter ut verdien til Domain:

(Get-ItemProperty .).Domain

Nå som vi har satt og hentet ut informasjon, la oss opprette en subkey, og opprette noen egenskaper i registry. For å gjøre dette navigerer vi oss til HKEY_CURRENT_USER, HKCU:

Set-Location HKCU:

Nå lager vi en subkey(underkatalog) med navn PowerShell kurs:

New-Item “PowerShell kurs”

Dette kan du nå bekrefte ved å kjøre dir av HKCU:

dir

La oss nå opprette noen verdier under PowerShell kurs, så først navigerer vi inn i PowerShell kurs:

cd “PowerShell kurs”

Deretter oppretter vi egenskapen Leverandør med verdien ”Harper” :

new-itemproperty –path . –name “Leverandør” –value “Harper”

Dette kan du nå enkelt kvalitetsikre med følgende kommando:

Get-ItemProperty .

Som du ser fikk vi nå en verdi av type string. Hvis du ønsker på ha en annen datatype, påvirker du dette med–PropertyType. La oss opprette en ny verdi i registry av typen DWORD:

new-itemproperty –path . –PropertyType DWORD –name ”Aktiv” –value 1

Du kan også endre navnet på ting i registry, på lik linje med i filsystemet. La oss endre navnet på ”PowerShell kurs” til kurs ”PowerShell” :

Jeg starter med å gå til nivået over der jeg står (da jeg står i ”PowerShell kurs” akkurat nå)

cd ..

Deretter benytter jeg Rename-Item (gjennom aliaset ren)

ren ”PowerShell kurs” ”PowerShell”

La oss fullføre registry arbeidet med å rydde opp etter oss (med andre ord, slette det vi har gjort) Jeg starter operasjonen med å gå inn i mappa vi opprettet, og som nå heter PowerShell :

cd PowerShell

Deretter fjerner jeg kun egenskapen Leverandør med følgende kommando:

remove-itemproperty –path . –name ”Leverandør”

Hvis vi ønsker å fjerne hele subkey ”PowerShell” kan vi også gjøre dette ved å gå opp et nivå, og kjøre Remove-Item, som følger:

cd ..
remove-item ”PowerShell”

Håndtering av services

Tilgang til services(tjenester) håndteres i PowerShell av kommandoene Get-Service, Start-Service, Stop-Service, Restart-Service,Suspend-Service, Resume-Service og Set-Service. Disse kommandoene gir oss tilgang til mesteparten av funksjonaliteten vi trenger, bortsett fra å sette konto eller passord til brukeren servicen kjører som.

Vi starter med å liste opp alle services:

Get-Service

Denne kommandoen lister ut alle servicene, uansett tilstanden de er i.

Hvis vi ønsker å liste ut alle med status Running kan vi utføre følgende kommando:

Get-Service | where { $_.status –eq ”Running” }

Vi starter og stopper prosesser med Start-Service og Stop-Service på følgende måte:

Stop-Service wsearch # stopper Windows Search
Start-Service wsearch # starter Windows Search

Hvis man ikke husker navnet på servicen, kan det være man husker ”Display name”, slik som Windows Search for servicen wsearch:

Stop-Service –DisplayName “Windows Search” # stopper Windows Search
Start-Service –DisplayName “Windows Search” # starter Windows Search
Parameteren displayname kan også benyttes sammen med Get-Service:
Get-Service –DisplayName “Windows Search”

Enkelte services (med andre ord – ikke alle) støtter det å bli satt i pause. Dette gjøres på tilsvarende måte som Stop-Service, men med CmdLet Suspend-Service. Med suspend slipper du å starte opp servicen på nytt etterpå, den ”lever” fortsatt, og kan fortsette med Resume-Service.

Vi kan også endre oppstartsoppførselen til en service gjennom Set-Service CmdLet :

Set-Service –name spooler –StartupType Manual

Istedet for Manual kan du også oppgi Automatic og Disabled.

Et annet eksempel som kan være nyttig er å kunne liste ut alle services som ikke kjører, men er satt til automatisk oppstart.

Get-WmiObject Win32_Service |where {$_.State –ne “Running” –and $_.StartMode –eq “Auto”} 

Eksemplet over tester for alle services som ikke har state lik ”Running” (-ne , not equals) og har startmode lik ”Auto” (-eq, equals).

Her benyttes også Get-WmiObject istedet for Get-Service – dette på grunn av at StartMode ikke er tilgjenglig i Get-Process CmdLet. Det viser også styrken til Get-WmiObject – hvis noe ikke er tilgjenglig gjennom Powershells innebygde kommandoer vil du finne det i WMI grensesnittet.

Håndtering av prosesser

Prosesser kan enkelt håndteres gjennom PowerShell med Get-Process CmdLet’en.

Slik lister du ut alle kjørende prosesser på maskina:

Get-Process

Ønsker du å ta en titt på en bestemt process angir du prosessnavnet som argument:

Get-Process calc

Vi kan også enkelt stoppe alle prosessene med navnet calc:

Stop-Process –name calc

Dette stopper alle kjørende forekomster av calc. Noen ganger ønsker vi kun å stoppe en enkelt av dem, og da kan vi benytte Id. Først henter du ut id med Get-Process, deretter kjører du Stop-Process med id.

Stop-Process 3874

Som med andre CmdLet’s for administrasjon, må du også på prosesser benytte WMI. La oss liste ut alle prosessene som kjører på maskinen DC1:

$cred = Get-Credential
Get-WmiObject –class Win32_Process –computer DC1 –credential $cred | Select Name,Handle,VirtualSize,WorkingSetSize | format-table 

Når man jobber med prosesser, spesielt med Stop-Process, kan det være smart å benytte –whatif, slik at man ser hva man gjør, før man utfører det.

Eksempel med –whatif :

Get-Process | Stop-Process -whatif

En annen ting vi skal se på når vi snakker om prosesser er hvordan PowerShell starter prosesser. I og med at Powershell er et shell (i tillegg til scriptspråk) så kan vi starte prosesser direkte fra PowerShell. Hvis du ønsker å kjøre calc.exe fra PowerShell, så skriver du navnet på den kjørbare fila. I dette tilfellet calc.

calc 

Eksemplet viser at kalkulatoren starter, og vi får returnert kontrollen umiddelbart tilbake til Powershell. Dette er fordi at calc.exe er en Win32 GUI (grafisk) prosess, og dermed kjøres i bakgrunnen. Andre kommandoer (ikke-grafiske) krever kjører som regel i samme prosess som PowerShell, og det gjør at vi ikke kan fortsette før kommandoen er fullført. Uansett, noen ganger er det nødvendig å vente til den grafiske applikasjonen er fullført før vi kan fortsette. I cmd.exe gjør vi dette med start /wait, i PowerShell gjør vi det slik:

calc | out-null

Ved å pipe til out-null tvinger vi prosessen til å fullføre før vi kan fortsette.

En annen måte å gjøre dette på er følgende:

$np = get-process notepad
$np.waitforexit()

I eksemplet over tar vi tak i en kjørende prosess, og venter til denne avslutter før vi går videre. Jeg vil også vise et eksempel til, hvor vi tar tak i den navnet på vinduet til den kjørende prosessen:

./filami.txt
$fp = gps | where {$_.mainwindowtitle -match "filami.txt"}
$fp.WaitForExit()

Følgende eksempel viser hvordan du kan benytte get-process til å identifisere applikasjoner som henger, og så avslutte dem med Kill().

Håndtering av Windows Firewall

Gjennom støtten for COM objekt kan man også jobbe mot Windows Firewall med PowerShell. Dette objektet lar deg både lese av innstillinger, samt gjøre konfigurasjonsendringer.

Vi starter med å opprette en variabel av typen HnetCfg.FwMgr. Dette er COM objektet vi benytter for å konfigurere Windows Firewall.

$fw = new-object –com HNetCfg.FwMgr

Sjekk om brannmuren er aktiv:

$fw.LocalPolicy.CurrentProfile.FireWallEnabled

Du kan enkelt aktivere brannmuren om den ikke er aktiv

(på lik linje kan du slå den av med $false):

$fw.LocalPolicy.CurrentProfile.FireWallEnabled = $true

På følgende måte kan du de om noen applikasjoner er autorisert til å gå igjennom brannmuren:

$fw.LocalPolicy.CurrentProfile.AuthorizedApplications

Hvis du ønsker å legge inn en åpning for innkommende trafikk på port 8080, kan du gjøre det på følgende måte:

$port=new-object -com HNetCfg.FWOpenPort
$port.Name="WebDemo"
$port.Port=8080
$port.Protocol=6
$fw.LocalPolicy.CurrentProfile.GloballyOpenPorts.Add($port)

HnetCfg.FWOpenPort er et COM objekt vi benytter for å jobbe med portene på brannmuren. I setningen $port.Protocol=6 står tallet 6 for protokollen TCP. Det betyr altså at vi åpner port 8080 på TCP protokollen.

Tilsvarende kan vi fjerne en åpen port på følgende måte:

(MERK! Dette krever administrator adgang)

$fw.LocalPolicy.CurrentProfile.GloballyOpenPorts.Remove(8080,6)

Man kan også liste åpne porter (tilsvarende netsh firewall show portopening)

$profile = (new-object -com HNetCfg.FwMgr).LocalPolicy.CurrentProfile
$profile.GloballyOpenPorts | ft name,port
Guide/Powershell

Kom igang med Powershell – del 6 – Feilsøking og debugging

Posted by ragnar harper on

Dette er artikkel 6 i min Kom igang med Powershell guide og omhandler feilsøking og debugging i Powershell 1.0 og Powershell 2.0.
Tidligere artikler har vært:

Del 5 : Formatering og gruppering
Del 4 : Utvikle script med Powershell
Del 3 : Sikkerhet i Powershell
Del 2 : Basis Powershell kunnskap (2/2)
Del 1 : Basis Powershell kunnskap (1/2)

Feilsøking og debugging

Noen ganger må vi håndtere feil som oppstår i kjøringen av en CmdLet, eller feil som vi selv er skyld i å innføre. Vi skal her se på hvordan vi kan påvirke hvordan feil skal håndteres.

Håndtering av feil (ErrorAction)

Feil i PowerShell deles inn i to kategorier

  • Terminating Denne type feil stopper scriptet
  • Non-terminating Selv om det har oppstått feil kan scriptet fortsette videre

Feil som oppstår representeres med et eget objekt – ErrorRecord. Dette objektet inneholder en exception som er beskriver årsaken til at feilen har oppstått, i tillegg til å si hvor.

ErrorRecord objektene lagres i en standard variabel med navn $error. $error er en samling med ErrorRecords.

Hvert ErrorRecord objekt inneholder følgende egenskaper:

  • Exception Exception er et eget objekt, med egne egenskaper. Den viktigste er Message som beskriver feilen. (Inneholder feilteksten)
  • TargetObject Dette er objektet hvor feilen oppsto
  • CategoryInfo Er en kategorisering av feil
  • FullyQualifiedErrorId Så spesifikk informasjon som mulig om feilen
  • ErrorDetails Denne er valgfri, så noen ganger er den null. Andre ganger inneholder den feilmeldingen i klartekst på engelsk.
  • InvocationInfo Hvis tilgjengelig, så sier denne deg hvilken linje i scriptet som har feilet, eller hvilken CmdLet. Kan være null.

Eksempel som skriver ut feilbeskrivelse for den siste feilen som har oppstått (error[0]):

$error[0].Exception.Message

De fleste CmdLets lar deg påvirke hvordan de enkle feilene skal håndteres (de som ikke øyeblikkelig stopper scriptet, men hvor det er mulig å fortsette. (non-terminating)). Dette påvirker du igjennom ErrorAction parametret.

Følgende verdier kan benyttes på ErrorAction parametret:

· Continue Dette er default valget, og betyr at feilen blir skrevet ut, men kjøringen fortsetter uansett.

· Stop Dette betyr at kjøringen skal stoppe ved feil

· Inquire Valget stopper kjøringen, og ber brukeren bestemme om kjøringen skal fortsette eller ikke

· SilentlyContinue Kjøringen av scriptet blir ikke avbrutt av feil. Feil blir heller ikke rapportert i resultatet.

Eksempel på bruk av ErrorAction (-ea) parameter:

$a=Get-WmiObject Win32_OperatingSystem –ea stop

Hvordan fange feil i Powershell 1.0?

Når feil oppstår sier vi at et ”unntak blir kastet”, eller ”throw exception”. Med unntak mener vi at det har oppstått en situasjon hvor vanlig planlagt prosessering ikke kan skje. La oss si at vi skal flytte ei fil fra mappe a til mappe b, men at fila ikke finnes. Da kan vi ikke flytte fila, og må kaste et unntak som sier vi ikke fant fila.

Når feil oppstår er det best practice å ta i mot feilen (catch exception), og til å gjøre dette benytter vi en errorhandler. (feilhåndterer).

Mal for en errorhandler

Trap [Exception] {
#håndter feilen, eller gi informativ informasjon
# $_ representerer ErrorRecord som ble kastet
Return [argument] | break | continue
}

I en errorhandler er det to ting som er spesielt viktig å huske. For det første har du informasjon om feilen som har oppstått tilgjengelig i variabelen $_ . Denne variabelen inneholder det ErrorRecord objektet som ble kastet der feilen oppstod. Videre er det viktig å huske at den siste linja i errorhandleren kan være en av tre kommandoer ; Return, Break eller Continue. Med return kan vi returnere verdier, med break kan vi stanse kjøringen, og med continue fortsetter vi uten å returnere noen verdi.

Følgende forklarer hvordan feilhåndtering virker i Powershell: Hvis en errorhandler er definert, blir denne utført når det oppstår feil. Errorhandler har tilgang til variabelen $error som forklarer hva som gikk galt. Den kan også sette ErrorPolicy for å si om scriptet skal fortsette eller ikke (defineres i slutten av errorhandler- slik som break eller continue, eller et hvilket som helst argument av eget ønske). Vi kan også definere en errorhandler til kun å omfatte bestemte typer feil. Dette angir vi direkte etter nøkkelordet Trap.

Her er et enkelt eksempel på en errorhandler:

TrapTest.ps1

function CheckWMI ($computer)
{
trap
{
Write-host “Det oppstod en feil:”
Write-host ”ID: ” $_.ErrorId
Write-host ”Beskrivelse:” $_.Exception.Message
continue
}
$osinfo = get-wmiobject Win32_OperatingSystem –property ServicePackMajorVersion –computer $computer –ea stop
Write-host “Maskin: “ $osinfo.ServicePackMajorVersion
}
Write-host “Sjekker service pack versjoner:”
CheckWMI(”FinnesEi”)
CheckWMI(”FinnesHellerIkke”)

I eksemplet over er det viktig at –ea stop er med. Hvis ikke vil feilen blir håndtert i CmdLet’en, og ikke i ErrorHandleren vi definerte. Du kan selv teste dette ved å fjerne –ea stop (da blir default Continue benyttet som erroraction, og CmdLet Get-WMIObject håndterer feilen selv).

Du kan også kaste feil selv ved å benytte throw:

throw “Noe gikk galt…”

Dette kan du også benytte i errorhandler, for eksempel for å behandle en feil, og sende den videre til neste errorhandler (hvis det er flere definert i overliggende scope)

Trap
{
throw $_
}

Hvordan fange feil med Powershell 2.0?

Powershell 2.0 har fått fullverdig feilhåndtering gjennom try, catch og finally.

Mal for try,catch, finally:

try
{
handlinger
}
catch
{
håndter feil
}
finally
{
rydd opp , f.eks. tilkoblinger du har åpnet som skal lukkes
}

Du må ikke ha med finally om du ikke trenger det.

Om kodeblokken som kjører i try ikke opplever feil vil kodeblokken(e) i catch setningen ikke kjøre. Finally vil kjøres uavhengig om det går bra eller ikke med try.

Vi kan bygge inn flere catch setninger etter hverandre. Vi starter da med de mest spesifikke, og kan avslutte med en generell catch til slutt.

try
{
$wc = new-object System.Net.WebClient
$wc.DownloadFile("http://www.contoso.com/MyDoc.doc")
}
catch [System.Net.WebException],[System.IO.IOException]
{
"Unable to download MyDoc.doc from http://www.contoso.com."
}
catch
{
"An error occurred that could not be resolved."
}

Merk: Finally kjøres selv om du trykker CTRL+C eller har en exit kommando i skriptet.

Debugging med Powershell 1.0

Debugging er antageligvis den mest arbeidssomme og tidkrevende delen av å skrive avanserte script.

I PowerShell versjon 1.0 er det lagt inn muligheter for debugbistand gjennom kommandoen Set-PSDebug. Jeg skal lett innrømme at denne kommandoen ikke er vakker i bruk, men den gir deg funksjonalitet som kan være av interesse når du støter på problemer, eller trenger å kjøre noe stegvis.

Du kan nå teste Set-PSDebug med følgende kommando:

Set-PSDebug -step

Kjør dereretter ett script du har liggende.

Som du ser får du nå anledning til å velge hva du ønsker å gjøre på hver linje. Det valget som er mest av interesse er S for Suspend. Når du trykker S stopper du kjøringen av scriptet, og havner i en kommandolinje sesjon hvor du kan inspisere variabler og endre verdier. Når du er klar til å fortsette skriver du exit, og scriptet vil fortsette å kjøre.

Hvis du ønsker å slå dette av skriver du:

Set-PSDebug -off 

Du kan også velge å kjøre sporing av alt som skjer gjennom parameteren trace. Denne har to alternativer, 1 og 2. Med 1 skriver den ut kodelinjene som utføres, med 2 skriver den også ut variabler som blir satt:

Set-PSDebug –trace 2

Debugging med Powershell 2.0

Med Powershell 2.0 er debugging blitt enklere. Vi har fått mulighet til å sette breakpoints, og med ISE har vi fått ett grafisk grensesnitt som er enklere å forholde seg til under debugging. La oss starte med å se hvordan du kan debugge fra kommandolinjen i Powershell 2.0

Debugging fra kommandolinjen

I Powershell 2.0 bruker vi ikke Set-PSDebug som i Powershell 1.0, men vi benytter Set-PSBreakPoint. Set-PSBreakpoint kan sette breakpoint på linje, cmdlet eller variabel. Vi kan også benytte en scriptblokk, noe som lar oss sette betingelser for ett breakpoint.

Vi starter med å se hvordan vi kan sette breakpoint på en gitt linje i ett skript. Følgende eksempel setter breakpoint på linje 2 i scriptet testscript.ps1:

Set-PSBreakpoint –Script testscript.ps1 –Line 2

Når du nå kjører scriptet vil det stoppe før linje 2 utføres. Du har da mulighet til å bruke egne debugkommandoer. Disse henter du frem ved å skrive h eller ? ved debugprompt.

Kommandoene du har tilgjenglig er:

  • s, stepInto
  • v, stepOver
  • o, stepOut
  • c, Continue
  • q, Quit
  • k, Get-PSCallStack
  • l, list
  • <enter>
  • h, ?

Av disse kommandoene bruker stepInto, stepOver, stepOut , quit og continue for å kontrollere kjøringen av scriptet. Om du ønsker å kjøre linje-for-linje velger du continue. Om du står på en linje som kaller en fuksjon eller ett annet script kan du bestemme om du skal debugge inn i funksjonen eller scriptet med stepInto og stepOver. StepInto tar deg inn i funsjonen eller scriptet, og stepOver utfører funksjonen eller scriptet, før den igjen stopper på neste linje i scriptet du allerde er i. StepOut kjører deg ut av funksjonen eller skriptet du nå er i. Quit avslutter kjøringen (og dermed også debuggingen) . Enter benyttes for å gjenta forrige valgte kommando.

image

Du kan også angi Actions som skal kjøres når ett breakpoint er aktivert. Dette gjør du med –Action paramteren. På Set-PSBreakpoint. I eksemplet under ser du at den ikke stopper når navnet er lik Pelle, men kun når navnet er lik Ragnar.

image

Se callstack under debugging

Ved debugprompten kan du se callstack for hvor du er med kommandoen k (ellet Get-PSCallStack). Det siste utførte steget er øverst, og det første er nederst i stakken. På eksemplet under ser du at sesjonen startet fra kommandolinjen (prompt) og vi står nå i scriptet testscript.ps1 på linje 2.

image

Debugging med Powershell ISE

For de fleste er Powershell ISE det enkleste stedet å utføre debugging. Last inn scriptet, og trykk F9 på linjen du ønsker å plassere ett breakpoint. I Powershell ISE har du en egen meny “Debug” hvor du kan se hvilke alternativer som er tilgjenglig. Powershell ISE har også egne tastatursnarveier for å kontrollere kjøringen av scriptet.

Step Over = F10

Step Into = F11

Step Out = Shift+F11

Run / Continue = F5

Stop Debugger = Shift + F5

Angi/fjerne Breakpoint = F9

Fjerne alle breakpoints = Ctrl+Shift+F9

Liste breakpoints = Ctrl+Shift+L

Vise callstack = Ctrl+Shift+D

 

image

En annen fin detalj er at ved å holde musmarkøren over en variabel vil de se innholdet av variabelen. På eksemplet under holder jeg musmarkøren over $Navn og får opp innholdet er lik Ragnar

image

Vi har i denne artikkelen sett litt på debugging og feilsøking i Powershell – med vekt på Powershell 2.0 og hva som er nytt der.

Guide/Powershell

Kom igang med Powershell – del 5 – Formatering, gruppering og eksport

Posted by ragnar harper on

Du finner de foregående delene av Kom igang med Powershell her:

Del 1 – Grunnleggende navigasjon og kommandoer

Del 2 – Grunnleggende navigasjon og kommandoer fortsetter

Del 3 – Sikkerhet og signering av script

Del 4 – Utvikle script

Sende data ut fra Powershell

Vi kikket kort på redirection i del 1, og skal her se på litt mer avanserte muligheter. Merk at PowerShell ikke støtter redirection inn til kommandoer (der bruker du pipeline). Pipelining og redirection hører tett sammen.

Du kan enkelt styre data ut dit du vil ved å pipe data til out kommandoene i PowerShell. Du har blant annet følgende out kommandoer:

  • Out-printer
  • Out-file
  • Out-null

Hvis du ønsker å skrive ut resultatet av en operasjon kan du ganske enkelt benytte følgende :

Dir | out-printer

Hvis du istedet ønsker å kjøre det til fil

Dir | out-file filnavn.txt

Formatering

Istedet for at hver kommando skal inneholde formateringskode benytter PowerShell seg av muligheten for å pipe resultatet til egne formateringskommandoer. Ettersom at PowerShell benytter seg objekter, har vi rike muligheter til å tilpasse og formatere utdataene med egne kommandoer. Formateringskommandoene starter med Format- , og de du kommer til å bruke mest er nok Format-List og Format-Table. Hva som er standard formatering bestemmes av CmdLet, og det varierer om det er Format-List eller Format-Table.

Format-List

Format-List gir deg resultatet som en liste, og ikke som en tabell. Det betyr at hvert objekt skrives ut med utvalgte egenskapene (eller de du velger) i en liste.

Se på følgende eksempel:

image

Som du ser av eksemplet over grupperes alle objektene adskilt med linjeskift. For hvert objekt skrives utvalgte egenskaper på egne linjer. Dette er god egnet for å skrive ut felt med mye informasjon, hvor informasjonen ikke får plass på et tabellformat. Du kan bruke parametret -property til å angi hvilke egenskaper du vil ha med.

Slik :

image

Hvis du lurer på hvilke egenskaper du har tilgjengelig – husk get-member.

image

Format-Table

Med Format-Table kan vi sette opp tabeller, hvor hvert objekt listes på en linje i tabelloppsett. En kommando som get-wmiobject kjører resultatet som standard ut som liste. La oss se på hvordan vi kan formatere resultatet fra get-wmiobject med format-table:

 image

På lik linje med Format-List kan vi også her angi hvilke egenskaper vi ønsker å ha med. Til dette bruker vi –property (kommandoen under skrives som en linje):

image

Som du ser av resultatet er alle kolonnene like store. For å unngå dette kan du bruke parameteret –autosize (fortsatt en linje)

image

Format-Wide

Det finnes også en formatering for å kjøre ut resultatet i to eller flere kolonner. Denne heter Format-Wide, og er tilpasset der vi skal dumpe ut en egenskap, og ønsker å kjøre resultatet over flere kolonner, slik at vi slipper å scrolle så mye.

image

Du kan også formatere antall kolonner slik du selv vil:

get-service | format-wide displayname -column 3

Format-Custom

Vi kommer ikke til å opprette egne formateringer her, men det finnes altså en mulighet til det. Da dette krever en god del kjennskap til .NET og XML, går vi ikke igjennom det her. Det betyr i praksis at man definerer en XML fil med formateringen, og benytter cmdlet’en Update-FormatData for å registrere formateringen.

GroupBy

Alle Format cmdlet’ene som er beskrevet ovenfor inneholder en parameter med navn GroupBy. Denne lar deg samle objektene under grupperinger. Se på følgende eksempel:

Get-service | format-table –groupby status

Du ble nok litt overrasket over resultatet av denne kommandoen, da den skriver ut og grupperer fortløpende. For at du skal få det resultatet du ønsker, må du først sortere resultatet på det du ønsker å gruppere på. Det leder oss videre til sortering.

Sortering

PowerShell innehar også egne sorteringskommandoer slik at hver enkelt kommando slipper å inneholde sorteringslogikk. Dette er også en av fordelene med objektorienteringen til PowerShell, der du enkelt kan ta ut egenskaper, og sortere på dem.

La oss fortsette på eksemplet fra GroupBy:

Get-Service | sort-object status | format-table –groupby status

Sort-Object

Sort-object har også noen parametere, slik som –descending for å sortere fallende (standard er stigende) samt –unique som kun gir oss unike verdier. (som en slags select distinct for de som jobber med SQL)

La oss opprette en liste å jobbe med:

$lista =@(6,3,9,7,1,4,5,7,6,1,4,8,2,50)

MERK: Jeg oppretter lista med @ og () denne gangen. Dette må jeg ikke benytte når jeg initsierer variabelen med verdier. Men i en situasjon hvor jeg ville ha opprettet en tom liste måtte jeg benyttet det på denne måten $lista=@()

Skriv nå ut lista som den er:

$lista

Deretter sorterer du den enkelt:

$lista | sort

 

image

Sort er et alias for sort-object, og foretrekkes av mange som enklere å lese.

Prøv nå:

$lista | sort –unique

Kommandolinja over sortere stigende, og tok bare med en av hver verdi. Hvis du ønsker å ha den største verdien øverst, og sortere fallende kan du benytte –descending

$lista | sort –unique -descending
image 

Merk! Det finnes også en cmdlet Get-Unique som lister opp unike verdier uten å sortere.

Men, hva om sorteringen din ikke fungerer som forventet?

La oss ta et eksempel – denne gangen med en hashtabell:

$hashlista =@{a=6;b=3;c=9;d=7;e=1;f=4;g=5;h=7;i=6;j=1;k=4;l=8}

Deretter så prøver vi å sortere denne lista:

$hashlista | sort

image

Resultatet blir ikke som forventet – uansett hvordan du prøver å sortere en hashliste, blir resultatet det samme. Årsaken til dette er at hashtabellen ikke sender objektene ut på ”pipen”, altså til neste kommando slik vi har blitt vant til. Hashtabellen sender kun seg selv, ikke innholdet. Dette ser du også om du prøver å konvertere den til kommaseparert fil eller gjøre utføre andre funksjoner på innholdet i hashtabellen.

Hvordan går vi frem for å sortere denne da?

Hvis vi tar en titt på hashtabellens egenskaper og metoder, vil vi se den inneholder metoden GetEnumerator. Ta en titt selv:

$hashlista | get-member

Hvis vi ønsker å sortere en hashtabell ( eller ønsker å ha hver enkelt forekomst i hashtabellen av andre årsaker) kan vi kalle denne metoden.

$hashlista.GetEnumerator() | sort -property Value

image

Denne gangen ser du at sorteringen ble korrekt.

Out-Gridview

Nytt i Powershell 2.0 er også Out-GridView. Denne krever .NET Framework 3.5 installert, og er kjekk for å enkelt manipulere utdata på en oversiktlig måte.

Med Out-GridView kan du i ett grafisk grensesnitt sortere og filtrere på informasjonen, slik at den er enklere å navigere seg frem i.

Eksempel på bruk av Out-GridView.

Get-Process | Out-Gridview
image
Where-Object

Where-object lar oss filtrere eller begrense hvilke av objektene fra resultatet vi vil ha med. Det betyr at vi tar resultatet av en cmdlet og piper inn i Where-Object for filtrering. Where-Object består av en kodeblokk, og må derfor ledsages av en { foran og en } til slutt. Her er et eksempel sammen med get-wmiobject cmdlet:

Get-wmiobject –class win32_service | where {$_.state –eq “Stopped”}

La oss konsentrere oss om følgende del av eksempelet over: where {$_.state –eq “Stopped”}

Where er som du sikkert allerede har gjettet et alias for Where-Object. Deretter kommer ”filteret” i kodeblokken som er mellom de to { } tegnene. Vi bruker standardvariabelen $_ som gir oss ett og ett objekt fra resultatet (av kommandoen Get-WmiObject). Deretter så leser vi av egenskapen .state til objektet, og sammenligner det med verdien ”Stopped”. Dette vil altså kun gi oss en liste over de servicene som har status stopped. Du kan også her bygge på med formatering.

For eksempel (kommandoen er på en linje) :

Get-wmiobject –class win32_service | where {$_.state –eq “Stopped”} | format-wide –column 3

Her vil vi skrive ut i tre kolonner alle services med status Stopped.

I filsystemet kan vi for eksempel bruke where-object til å bare liste ut kataloger:

Get-ChildItem | where { $_.PsIsContainer} 

 

Eksport

I en del tilfeller har du behov for å formatere dataene i et annet format, slik som HTML, CSV eller XML. Dette er tilfeller PowerShell er forberedt på, og gir deg egne eksport kommandoer til formålet. Dette betyr at du eksporterer informasjonen fra PowerShell på en enkel måte, uten at hver enkelt kommando trenger å ha innebygd funksjonalitet for eksport.

La oss se på Export-CSV, Export-CliXML og ConvertTo-HTML.

Export-CSV

Når vi skal håndtere data i bulk er kommaseparerte filer noe av det mest anvendelige formatet. Det er også veldig mye benyttet da det lar oss enkelt ”massere” dataene i Excel og tilsvarende verktøy. (Selv om XML er viktig for utviklere, står CSV filer sentralt for administratorene).

La oss se på et par eksempler:

Get-Process | Export-csv prosesser.csv

I eksemplet over opprettes fila prosesser.csv, og inneholder detaljert informasjon om prosessene på maskina.

Hvis du synes det ble returnert for mye informasjon i eksemplet over, kan du ta enkelt bestemme hvilke egenskaper du skal ha med på følgende vis:

Get-process | select-object name,id,cpu | Export-Csv prosesser.csv

Du kan enkelt dumpe innholdet av ei fil til shellet med get-content.

Get-content prosesser.csv

MERK! Hvis du får feilmeldinger under kjøring av slike kommandoer, kan det være du ikke har skriverettigheter til det området du prøver å lagre fila.

Export-CSV har også et par viktige parametre:

Tabell  Parametre til Export-CSV

Parameter

Beskrivelse

-NoTypeInformation

Standardinnstillingene skriver ut ei linje øverst i fila med feltnavnene. Hvis du ikke ønsker denne linja, benytter du –NoTypeInformation

-NoClobber

Hvis du ikke ønsker å overskrive eksisterende fil, benytter du –NoClobber (som standard overskrives altså eksisterende fil)

Import-Csv

En kommaseparert fil importerer du enkelt med Import-CSV:

Import-csv prosesser.csv

Merk! Import-csv kommandoen krever at den kommaseparerte fila har en header som angir feltnavnene. Med andre ord, første linje blir tolket som angivelse av feltnavn.

La oss se på hvordan du kan importere ei kommaseparert fil, og behandle den. Til eksemplet bruker vi csv fila vi opprettet med Export-Csv over (prosesser.csv)

TestImport.ps1

$prossesser = Import-Csv prosesser.csv

foreach ($p in $prosesser)

{

    Write-host $p.Name $p.id

}

Merk følgende i eksemplet over: Ettersom at fila prosesser.csv inneholder feltinformasjon i første linje, kan vi benytte dette direkte i løkka vår. Vi går altså igjennom hver ”post” med prosesser (hver post blir lagt i variabelen $p, en i gangen, til alle er gjennomgått) Vi angir direkte feltnavnet bak punktum på variabelen $p. Dette sier noe om hvor brukervennlig Powershell er, og hvor mye den gir oss direkte i slike tilfeller.

Export-CliXML

Om du ønsker å serialisere objektene du jobber med i Powershell kan du benytte Export-CliXml og Import-CliXml. På denne måten kan du enkelt flytte eller lagre objekter over tid, og jobbe videre med dem senere.

La oss si at du ønsker å lagre prosessene som kjører på maskinen akkurat nå, slik at du kan titte nærmere på dem ved en senere anledning:

Get-process | export-clixml prosesser.xml

Dette kan du importere med Import-CliXML, men først, kjør en vanlig get-content:

Get-content prosesser.xml

Deretter kjører du en import med import-clixml:

Import-CliXML prosesser.xml

Export-CliXML støtter også –NoClobber for å unngå å overskrive eksisterende filer.

ConvertTo-HTML

La oss også se på hvordan vi kan eksportere resultatet til HTML med ConvertTo-HTML.

ConvertTo-HTML tar resultatet og konverterer det til HTML (slik som navnet angir), og vi benytter den sammen med Out-File for å lagre til fil. Denne har også en del muligheter, men vi starter med et enkelt eksempel:

Get-process | ConvertTo-html | out-file prosesser.html

Hvis du åpner og titter i prosesser.html vil du kan si at det ble veldig mye data der. Og det kan du faktisk enkelt påvirke i convertto-html CmdLet’en. Se på følgende eksempel:

Get-process | ConvertTo-html Name,id | out-file prosesser2.html

ConvertTo-HTML har også noen parametre som kan benyttes til å påvirke hvordan html siden skal genereres.

Parameter

Beskrivelse

Head

Setter tekst inn i <head> tag på html siden.Typisk referanser til style sheets og lignende

Title

Tekst som skal inn i <title> tag på html siden. Dette lar deg gi siden et meningsfyllt navn

Body

Denne teksten kommer i mellom <body> og </body> taggene. Lar deg angi informasjon før tabellen fra Powershell settes inn.

La oss se på et eksempel med informasjonen over:

Process2HTML.ps1

#et stylesheet med navn style.css skal være i samme katalog som denne fila
$server=hostname
$body=”Prosesser for ”+$server.toUpper()+”<hr>”
$file=”c:\”+$server+”-prosesser.html”
# * teksten under er på en linje *
Get-process | ConvertTo-HTML Name,Id,WorkingSet,CPU –Title “Prosessrapport.” –Head “<link rel=stylesheet type=text/css href=style.css>” –Body $body | out-file $file 

Vi har nå tittet på enkel formatering, gruppering, sortering – håper du har nytte av denne guiden 🙂

Guide/Powershell

Kom igang med Powershell – del 4 – Utvikle script i PowerShell

Posted by ragnar harper on

Utvikle script i PowerShell

Dette er del 4 av Kom igang med Powershell guiden min.

Del 1: Kom igang med Powershell

Del 2: Kom igang med Powershell

Del 3: Kom igang med Powershell

Frem til nå har vi sett på hvordan kommandolinjen fungerer i PowerShell . Vi skal nå se på nyttige mekanismer for å kunne skrive script i Powershell. I denne sammenheng skal vi blant annet ta en titt på variabler, objekter, operatører, løkker og valg.

Grunnleggende om script

Script er et sett med kommandoer satt sammen for å gjøre en jobb. Ofte samler vi operasjoner vi ønsker å gjenta i script, for slik å slippe å skrive inn alt på nytt hver gang vi ønsker å utføre jobben. For å jobbe med script trenger man i utgangspunktet ikke mer enn en editor, slik som Notepad. Jobber man mye med script kan det være man ønsker å investere i noe som har litt mer funksjoner, blant annet Intellisense (som foreslår fullførelse av det du skriver). Det finnes flere editorer du kan benytte, slik som Sapien Primalscript , PowerGUI Editor og Powershell ISE, bare bruk det som funker for deg. Jobber man mye med script bør man også tenke på hvordan man skal håndtere ulike versjoner av script. Til dette kan man benytte alt fra Sharepoint document librarys , CVS, TeamServer og Sourcesafe. En del av editorene har muligheter til å direkte jobbe mot disse kildene.

En helt enkel malfil kan se slik ut :

#=====================================================================
#
# NAME: Scriptets navn
#
# AUTHOR: Ragnar Harper
# CREATED DATE : 02.05.2007
#
# DESCRIPTION: Beskriv formål med scriptet
#
# HISTORY: Endringer noteres her
#
#=====================================================================

Etter Name: legger jeg scriptets navn. I tillegg legger jeg inn en beskrivelse av scriptet under Description , og en oppdateringslogg under History.

Selv om man husker hvorfor man lager scriptet når man utvikler det, kan det ofte være vanskeligere å huske det etter ett år..

Bruk av variabler

Variabler identifiseres i PowerShell med $. Det betyr at alle variabler begynner med ett dollartegn. Vi skal i dette avsnittet se litt på bruken av variabler.

Benytt din favoritt editor til å skrive inn følgende linjer, som lagres som Script1.ps1:

$fornavn = Read-Host"Tast inn Fornavn"
$etternavn = Read-Host "Tast inn Etternavn"
Write-Host "Du heter $fornavn $etternavn"

I dette eksemplet oppretter vi to variabler, en navngitt $fornavn og en navngitt $etternavn. Vi benytter kommandoen Read-Host til å lese inn verdier i variabelene. Inntastingen av verdi avsluttes med at brukeren trykker <ENTER>.

Åpne PowerShell (hvis du ikke allerede har det åpent) og gå til mappen hvor du lagret script1.ps1

Start scriptet med å kjøre .\Script1.ps1

Du får da en dialog som ser noenlunde ut som denne:

image

Legg merke til at Read-Host autmatisk legger til : (kolon) bak teksten vår.

La oss gå videre, og lage scriptet Script2.ps1 :

$tallA = Read-Host("Tast inn tall 1")
$tallB = Read-Host("Tast inn tall 2")
Write-Host "Sum=$tallA+$tallB"

Lagre, og kjør scriptet. Hvordan ble resultatet denne gangen? Ble det som forventet?

La oss prøve oss på en endring av kildekoden. Endre linjen med Write-Host til å lyde som følger:

$tallA = Read-Host("Tast inn tall 1")
$tallB = Read-Host("Tast inn tall 2")
Write-Host (“Sum=” + ($tallA + $tallB))

Lagre Script2.ps1, og prøv å kjøre det en gang til. Ble resultatet annerledes nå?

Hos meg ble det slik:

image

Og dette skyldes at tallene håndteres som en tekststreng, og ikke som tall. Så hvordan kan vi fortelle PowerShell at vi jobber med tall?

I PowerShell kan vi eksplisitt angi hvilken datatype vi jobber med. Vi har frem til nå ikke hatt behov for det, og det er fordi PowerShell er veldig dyktig til å avgjøre hvilken datatype du ønsker å jobbe med. Men i enkelte tilfeller kan det være nødvendig å angi hva vi ønsker å ha. I Tabellen under ser du ulike datatyper du kan angi, men først et eksempel:

[int]$Tall1=Read-Host(“Tast inn tall 1”)
[int]$Tall2=Read-Host(“Tast inn tall 2”)
$tall1+$tall2

Når du kjører dette eksemplet, prøv også å lese inn bokstaver eller setninger. Som du ser feiler PowerShell da, med beskjed om at den ikke kan lagre verdien i en Integer. Du må altså oppgi et heltall for å få Powershell til å godta verdien.

La oss se på et annet eksempel også:

$x=”2”
$y=2
$x+$y
$y+$x

Hva skjer her? Jo, eksemplet viser at du kan sette de verdiene du vil til en variabel, og når du knytter dem sammen, slik som gjennom $x+$y og $y+$x så benytter Powershell datatypen til variabelen lengst til venstre for å avgjøre datatypen. I eksemplet $x+$y er $x en tekststreng (string), og svaret blir derfor to tekststrenger som blir satt sammen. I eksemplet $y+$x er $y et heltall, og Powershell prøver derfor automatisk å konvertere $x til heltall etter beste evne. Ettersom at tekststrengen ”2” kan oversettes til heltallet 2, utfører den operasjonen, men denne gangen altså med heltall verdier.

Tabell 2 Eksempel på typer og deres alias i PowerShell

PowerShell alias

Tilsvarende .NET type

[int]

System.Int32

[long]

System.Int64

[string]

System.String

[char]

System.Char

[bool]

System.Boolean

[byte]

System.Byte

[double]

System.Double

[decimal]

System.Decimal

[float]

System.Single

[single]

System.Single

[regex]

System.Text.RegularExpressions.Regex

[array]

System.Array

[xml]

System.Xml.XmlDocument

[scriptblock]

System.Management.Automation.ScriptBlock

[switch]

System.Management.Automation.SwitchParameter

[hashtable]

System.Collections.HashTable

[psobject]

System.Management.Automation.PSObject

[type]

System.Type

På mange av disse datatypene finnes datatypen som et array ( en samling med verdier ). Dette kan vi angi med [] etter datatypenavnet. Eksempel for int og long : [int[]] [long[]]

La oss si at vi ønsker å initisere variabelen $x som en samling med tallene 1.0, 2.2, 3.3 ,4.4, 5.5. Vi ønsker å lagre tallene som datatypen [double], en datatype som lar oss lagre desimaltall.

$x=1.0,2.2,3.3,4.4,5.5
$x.GetType()

Resultatet av denne operasjonen vil være et array – men av typen Object. Dette får du sjekket med komjmandoen $x.GetType(), som gir følgende utdata:

IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array

Hvorfor er dette et problem tenker du kanskje nå? Object funker bra i mange tilfeller, men kan gi feil senere. La oss se på følgende eksempel:

image

Resultatet ble riktig. Dette viser hvor kraftfullt PowerShell er til å ville gjøre det riktig for oss. Men, når datasamlingen vår er av type Object, betyr det at vi kan få den til å feile ganske enkelt, ved at de ulike verdiene kan være av forskjellige datatyper.

Merk! For sikkerhetsskyld bør du nullstille $sum variabelen på følgende måte:

$sum=””

Slik tester du det:

image

Denne gangen blir resultatet annerledes, og vi får ingen feilmelding. PowerShell bruker den første verdien den får inn i en variabel til å bestemme datatypen på denne variabelen. Det betyr at $sum denne gangen ble en [string] variabel, og at vi satte sammen tallene og bokstavene som om de var en tekst som skulle henge sammen.

For å sikre oss mot slike feil kan vi angi datatype og om det skal være en datasamling når vi tar i bruk variabelen.

Prøv følgende:

image

Denne gangen får du feilmelding når du prøver å sette verdien til ”R” fordi ”R” ikke er en verdi av type [double]

Du kan slette en variabel med Remove-Variable CmdLet’en. Verdier kan også slettes med Clear-Variable.

Det finnes også noen spesielle innebygde variabler. Jeg har satt disse opp i tabellen under. Det er viktig å kjenne til disse slik at du ikke benytter dem som egne variabel navn, og slik at du kan benytte dem.

Tabell 3 – Innebygde variabler

Variabelnavn

Beskrivelse

$_

Gjeldende objekt i pipeline. Dette benyttes hvor vi har behov for tilgang til hvert enkelt objekt som finnes i et resultat, enten for å sette verdier, lese verdier eller sammenligne verdier.

$^

Første tegnene (før mellomrom) i den siste linja som ble skrevet i shellet

$$

Siste tegnene (etter mellomrom) i den siste linja som ble skrevet i shellet

$?

Inneholder status på siste setning (suksess eller feil)

$args

Benyttes i funksjoner for å hente ut parametrene

$error

Hvis det oppstår feil lagres denne i $error

$home

Brukerens hjemmestasjon

$input

Inndata som pipes til en funksjon eller kodeblokk

$match

En tabell md elementene som er funnet i en –match operasjon

$ofs

Output field separator – benyttes når et array konverteres til en string. Standardverdien er mellomrom (space)

$shellid

Identifikasjonen til shellet. Benyttes til å finne ut executionpolicy og hvilke profiler som skal lastes

$stacktrace

Detaljert informasjon fra stack for siste feilmelding

Arrays

Enkelt forklart kan vi si at et array er en container for å lagre ting. For de fleste behov trenger vi kun enkle array. For administrativ skripting kan du tenke på at array er en datasamling, altså en variabel som er istand til å inneholde flere verdier. I faglitteraturen møter du også begrepet collection. For dette kursets del kan du da tenke at det er et array. Dere får ha meg unnskyldt for at jeg i teksten benytter begrepet datasamling / array om hverandre. Da de fleste administratorer har liten erfaring med skripting og programmering, prøver jeg å gjøre det så forståelig som mulig.

La oss lage et enkelt array:

image

Vi kan aksessere hver enkelt verdi i et array gjennom å angi indeksen til verdien vi ønsker. I eksempelet over med $arr har vi 10 verdier. Disse aksesseres gjennom en indeks som starter på 0, og teller opp til så mange elementer som vi har. I dette tilfellet aksesseres altså hver verdi ved å angi indeks fra 0 til 9.

image

Den siste gir deg ingen verdi, da det kun ligger verdier fra 0 til 9.

Forøvrig kunne vi skrevet initiseringen av $arr på en annen, og mer effektiv måte:

image

La oss se på et mer praktisk rettet eksempel hvor vi ønsker å hente ut informasjon fra flere maskiner. Maskinene vi skal hente ut informasjon om ligger i fila server.txt. Server.txt fila er formatert med et servernavn på hver linje, slik som dette:

ServerA
ServerB
ServerC


Tips

! Lag din egen liste over servere i ditt eget nettverk.

La oss lese inn innholdet av fila til en variabel med navn $serverliste:

image

Jeg har benyttet en punktum til å angi maskinen jeg kjører på, de andre maskinene har jeg angitt med navn,

La oss gå igjennom hver server (hver linje, eller hvert element i array’et om du vil)

image

Om en av serverne ikke er tilgjenglig, eller begrenset med brannmur får du følgende melding:

image

Vi ser at serveren hyper1.harper.labs ikke var tilgjengelig under kjøring av koden.

Vi har allerede under kurset benyttet arrays og vi kommer til å benytte det flere ganger.

En annen type array er et hash array, også kalt for dictionaries og associative arrays.

Dette er array hvor hvert element består av en nøkkel og en verdi. Vi kan da benytte nøkkelen til å gjøre oppslag, istedet for indeks nummeret slik vi må på vanlige array. La oss ta eksemplet hvor vi trenger å lagre salgstall for tre avdelinger:

Avdeling Salgstall

Trondheim 200 000

Oslo 100 000

Bodø 150 000

Vi kan nå deklarere dette i PowerShell på følgende måte:

$salgstall = @{“Trondheim”=200000;”Oslo”=100000;”Bodø”=150000}

Vi kan nå aksesserer tallene for Trondheim og Bodø gjennom følgende kode:

$salgstall.Trondheim
$salgstall.Bodø 

image

Merk! Hvis nøkkelen inneholder blant annet mellomrom eller punktum må vi ha ” rundt ordet, slik $salgstall.”Trondheim”

Objektorientering

En av de store fordelene med PowerShell er objektorienteringen. Hva betyr så dette?

Med objektorientert mener vi at data og handlinger henger sammen. La oss se på følgende enkle eksempel:

image

”Donald Duck i store bokstaver” er en string, og man har derfor anledning til å kalle alle metoder som hører til på en string. Eksemplet viser godt hvordan data og handlinger henger sammen.

I objektorientering møter du to typer metoder som kan påkalles. (Handlinger altså) Dette er statiske metoder og instansmetoder. Instansmetoder påkalles med punktum mellom objektet og metoden. Statiske metoder påkalles med :: mellom objektet og metoden.

Eksempel på bruk av statisk metode:

image

Du kan hente ut statiske metoder fra objekttyper ved å pipe dem til get-member –static:

[string] | get-member –static

For å hente ut instansmetoder kan du kalle get-member på en instans:

“Donald Duck” | get-member

Operatører

La oss se på ulike operatører i PoweShell. Vi starter med ulike sammenligningsoperatører. Ofte har vi behov for å sjekke om en variabel har en bestemt verdi, er større enn, mindre enn, eller ikke er en bestemt verdi.

Operatør

Beskrivelse

Eksempel

Resultat

-eq –ceq –ieq

Er lik

3 –eq 3

$true

-ne –cne –ine

Er ikke lik

3 –ne 3

$false

-gt –cgt –ige

Større enn

10 –gt 7

$true

-lt –clt –ilt

Mindre enn

10 –lt 7

$false

-ge –cge –ige

Større eller lik

10 –ge 7

$true

-le –cle –ile

Mindre enn eller lik

10 –le 7

$false

-contains

-ccontains

-icontains

Samlingen på venstre side inneholder verdien på høyre side

1,2,3 –contains 2

$true

-notcontains

-cnotcontains

-inotcontains

Samlingen på venstre siden inneholder IKKE verdien på høyre side

1,2,3 –notcontains 2

$false

En annen type operatører er de som setter verdier:

Operatør

Beskrivelse

Eksempel

Tilsvarer

=

Setter variabelen til en bestemt verdi

$a = 9

 

+=

Legger til eksisterende verdi, og setter variabelen lik den nye verdien

$a+=2

$a=$a+2

-=

Trekker verdi på høyreside ifra eksisterende verdi, og setter variabelen lik den nye verdien

$a-=2

$a=$a-2

*=

Multipliserer verdi på høyreside med eksisterende verdi, og setter variabelen lik den nye verdien

$a*=2

$a=$a*2

/=

Deler verdi på høyresiden med eksisterende verdi, og setter variabelen lik den nye verdien

$a/=2

$a=$a / 2

%=

Utfører heltallsdivisjon, og gir oss rest etter utført operasjon

$a%=2

$a=$a % 2

Et særtrekk ved PowerShell jeg ønsker du skal kjenne til er at man kan sette flere verdier på en effektiv måte. Noen ganger kan du ha behov for å bytte verdi mellom to variabler, og vanligvis skriver man det slik:

$midlertidig = $a
$a=$b
$b=$midlertidig

Eksemplet bytter verdiene i $a og $b. I PowerShell kan dette skrives på følgende måte:

$a,$b = $b,$a

La oss se på et eksempel som utnytter dette på en effektiv måte. Fibonacci rekken er en populær del av matematikken . Dette er en rekke med tall, hvor hvert element er summen av de to foregående.

Fibonacci rekken: 1 1 2 3 5 8 13 21

$c=$p=1;while ($c -lt 1000) {$c;$c,$p=($c+$p),$c}

Eksemplet skriver ut Fibonacci rekken til 1000. Hvert tall som skrives ut er lik summen av de to foregående tallene i rekken. Semikolonet ( ; ) benyttes til å avslutte en setning på lik linje med linjeskift. Vi starter med å sette $c og $p lik 1. Deretter lager vi en løkke (while) som kjører så lenge c er mindre enn 1000. Deretter skriver vi ut $c, og setter $c lik ($c+$p), og vi setter $p lik c$ (altså som verdien til $c før vi legger til $p).

Dette kan du også teste på en enkel måte:

$a=$b=1 # denne linjen setter bade $a og $b til 1
$a,$b = ($a+$b),$a # setter $a lik ($a+$b) og $b settes lik $a
$a
$b

Regular Expressions

Regular expressions er “wildcards” på steroider. Det er med andre ord vesentlig mer kraftfullt en standard “wildcard”.

Regular Expressions (heretter kalt for regex) er kraftfullt, og vi skal her se på hvordan du kan komme igang med det. De operatørene som virker med regex er –match og –replace, og varianter av disse, slik som –cmatch,-imatch,-notmatch,-cnotmatch,-inotmatch, -creplace og –ireplace. C variantene står for case sensitiv, altså følsomme for store og små bokstaver, mens i variantene er ikke sensitive på store og små bokstaver.

Et godt eksempel på en problemstilling regex løser er å hente ut alle ip-adressene fra for eksempel ei logfil. Vi vet ikke nødvendigvis hvor i dokumentet ip-adressene er lagret, men vi vet hvilken form de har, og kan benytte regex til å gjenkjenne dette mønsteret, for så å hente det ut.

For å forstå regex trenger du å kjenne til noen spesialtegn som benyttes :

Tegn

Beskrivelse

\w

Tilsvarer alfanumeriske tegn eller underscore ( _ )

\d

Tilsvarer siffer (0-9)

\t

Tilsvarer TAB (tabulator)

\s

Tilsvarer mellomrom, tabulator eller newline

Ved å benytte stor bokstav istedet for liten blir meningen motsatt. Altså, \D betyr ikke siffer, og \W betyr ikke et alfanumerisk tegn eller underscore. Merk at dette ikke er et fullstendig uttrekk av spesialtegn, men de du oftest får behov for å kunne.

I tillegg til tegnidentifikatorene må du kjenne noen formateringsregler.

Format

Beskrivelse

Eksempel

Verdi

Matcher eksakt tegnene i sammenligningsverdi hvor som helst i den orginale verdien vi sammenligner med

”PowerShell” –match ”Shell”

.

Matcher et enkelt tegn

 

[verdi]

Matcher minst et av tegnene i verdi

”PowerShell” –match ”[def]”

[range]

Matcher minst et av tegnene i området som er oppgitt

 

[^]

Matcher alle tegn, bortsett fra de i klammeparentes

 

^

Matcher starten av orginal verdi

”PowerShell” –match ”^power”

$

Matcher slutten av orginal verdi

”PowerShell” –match ”ell$”

*

Matcher null eller flere forekomster av etterfølgende tegn

”PowerShell” –match ”\w*”

?

Matcher null eller en forekomster av etterfølgende tegn

 

\

Matcher etterfølgende tegn som et ”escape” tegn

 

+

Matcher repeterende forekomster av angitte mønster

 

{n}

Spesifiserer eksakt n forekomster

 

{n,}

Spesifiserer minst n forekomster

 

{n,m}

Spesifiserer minst n, men ikke mer enn m forekomster

 

Resultatet av en regex operasjon lagres automatisk i variablen $matches.

“PowerShell rules!” –match “\w* \w*”
$matches

image

Følgende eksempel krever at det er to ord for å gi true (gir false på ett ord og mer enn to):

“PowerShell rules!” –match “^\w* \w*$”

La oss benytte PowerShell til å sjekke om teksten vår er tall:

“PowerShell rules!” –match “\d”

Prøv nå følgende:

“123” –match “\d”

Det første eksemplet skal returnere false, da det ikke er et tall. I det andre eksemplet får du returnert true, ettersom at det er tall.

La oss nå sjekke om noe er en ip-adresse. VI begynner enkelt med å sjekke for 4 grupper med tall, adskilt med punktum:

"10.1.1.200" -match "^\d+\.\d+\.\d+\.\d+$" 
"10.1.1" -match "^\d+\.\d+\.\d+\.\d+$" 

image

Videre vet vi at en IP-adresse kun kan bestå at tre tall i hver gruppe. La oss erstatte + med {1.3}. Som ser av tabellen over betyr {1,3} minst en forekomst, og maks 3. Med \d{1,3} sier vi altså tall, minimum et tegn, og maksimum 3 tegn langt.

"10.1.1.200" -match "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$" 

image

La oss anvende dette i praksis med følgende eksempel.

Vi kjører kommandoen net config workstation og oppdager at linje 2 i resultatet inneholder maskinnavnet. Net config workstation er en gammel ”cmd.exe” kommando, og er ikke en PowerShell kommando som gir oss objekter å jobbe med. Vi får kun tekst i resultatet. La oss nå benytte regex til å hente ut maskinnavnet :

Først kjører vi kommandoen for å se på utdataene.

image

Deretter bestemmer vi oss for å lese ut linje nr 2. Reultatet er allerede et array med strenger for hver linje, og vi vet at alle indekser i PowerShell starter med 0. Det betyr at linje nr 2, adresseres med 1 i indeksen:

image

La oss opprette regex uttrykket vi skal sjekke mot i en variabel:

Hvis maskinen er medlem i et domene benytte du følgende uttrykk:

$expr = ‘^Full Computer.* [^.]+\.[^.]+’

Hvis maskinen ikke er medlem i et domene, benytter du følgende uttrykk:

$expr = ‘^Full Computer.* [^.]+’

Ved å benytte uttrykket vi nettopp opprettet ($expr) så trenger vi ikke å vite hvilken linje det ligger på. Vi sender inn uttrykket, og får linjen vi søker tilbake.

(net config workstation) –match $expr

image

Ved å benytte regex uttrykk kan vi unngå å måtte ”lete igjennom” en tekst for det vi ønsker å finne. En tradisjonell krevende måte å gjøre slike operasjoner på er å ”løkke” igjennom linjen, og sammenligne på leting, eventuellt så regner man seg frem til posisjon, og leser teksten basert på posisjon. Når vi jobber med variable lengder på det vi skal ha er det krevende.

En annen typisk operasjon er å finne bestemte data i en samling med ustrukturerte data. Med ustrukturert mener jeg slik som en tekst, hvor ikke all informasjon ligger i dedikerte felt, slik som for eksempel i en database.

La oss si at vi ønsker å finne IP adressen i følgende setning

Finn IP adressen min 210.12.34.19 hvis du kan

"Finn IP adressen min 210.12.34.19 hvis du kan" -match "\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}" 

Sjekk nå om hva som ligger i $matches variabelen:

$matches

Du vil da finne IP-adressen.

Løkker og valg

Et sentralt konsept innen script og programmering er løkker og valg. I mange tilfeller har vi behov for å iterere over flere verdier, gjerne også for å sammenligne verdier med en bestemt verdi for å avgjøre hva vi skal gjøre. Etterhvert som et script utføres må det ofte gjøre valg for hva det skal gjøre basert på sammenligninger.

For løkke

La oss starte med en enkel løkke som itererer over 0 til 9:

for ( $i = 0; $i -lt 10; $i+=1 ) { $i }

Formatet er slik : for (initsiering av verdi; tilstand for å utføre løkken; endring av verdi)

Vi lager oss en for løkke med følgende egenskaper:

Variabelen $i settes til 0.

Utfør løkken så lenge $i er mindre enn 10

Øk $i med 1 for hver iterasjon

Med andre ord kjøres løkken ti ganger, fra 0 til 9. Vi kunne fått den til å kjøre 11 ganger, fra 0 til 10 ved å endret –lt til –le.

La oss ta eksemplet videre og lage en multiplikasjonstabell (skriv alt på en line):

for ( $i = 1; $i -lt 10; $i+=1 ) { for ($x=1;$x -lt 10;$x+=1){ write-host `t($i*$x) -nonewline} write-host }

image

Her kjører vi to for løkker, en inne i den andre.Den ytre løkken teller fra 1 til 9. For hver av tallene som telles opp, teller den indre løkken fra 1 til 9, og vi multipliserer dermed hver av de ytre verdiene med 1 til 9. Jeg bruker også –nonewline for at tallene skal komme fortløpende på samme linje, og ikke skrives ut på hver sin linje. For formateringens skyld kjører jeg også `t foran hver, slik at det blir en tabulator mellom hvert resultat.

While løkke

En annen løkke vi har er while. Der for løkken er kjekk å bruke når du vet hvor mange ganger du skal kjøre løkken (hvor mange ganger du skal iterere), så er while løkkens fordel at den står friere i antall kjøringer. Den kan for eksempel kjøre til noe blir sant eller noe kommer til enden.

While løkken er på mange måter den enkleste å mestre, og på mange måter den mest kraftfulle.  Hver type loop har sin egen oppbygning, og While løkkens oppbygning inneholder to elementer; betingelse og kode. Som ellers bruker vi ulike typer parenteser, vanlig parenteser () for betingelse og klammeparentesene { } for koden.

I en while løkke blir betingelsene sjekket før starten av hver gjennomkjøring, og hvis betingelsen er sann, blir koden utført.

Eksempel på while løkke

$i =7
while ($i -le 85) { $i; $i +=7}

Eksemplet skriver ut syvgangen opp til 85.

Merk at kodeblokken { $i ; $i +=7 }benytter semikolon (;) for å skille kodelinjer fra hverandre. Det betyr med andre ord at kodeblokken består av to separate linjer, linje 1 med $i og linje 2 med $i+=7. Den første linjen skriver ut verdien av $i, og den andre øker $i med syv.

Do…While løkke

En Do … While løkke skiller seg fra While løkken med at betingelsen sjekkes på slutten av løkken. Dette sikrer at en Do … While løkke alltid blir utført minst en gang, da while kommer etter do

$i = 7; do { $i; $i +=7 } while ($i -le 85) 

Do … While løkken over skriver også ut syvgangen til 85.

Do Until løkke

Do .. Until løkken er en variant av Do..While løkken hvor logikken er endret.En Do..Until løkke utføres til betingelsen er sann, da avslutter den. En Do…While løkke utføres så lenge betingelsen er sann, men avslutter i det øyeblikket den ikke er sann.

$i = 7; do { $i; $i +=7 } until ($i -gt 85) 
Foreach løkke

Foreach løkker inneholder flere valgmuligheter enn de andre, og benyttes ofte i PowerShell.

Hovedfunksjonaliteten i en foreach løkke er at den gjennomgår alle elementene i et array (collection, eller samling med flere verdier om du vil). Legg spesielt merke til bruken av ordet in.

Foreach($element in $collection) { utfør dette }

Syvgangen i en foreach løkke presenteres på følgende måte:

foreach ($number in 1,2,3,4,5,6,7,8,9,10,11,12 ) { $number * 7}

En annen måte å skrive dette på (vi snakker jo tross alt PowerShell) er som følger:

$arr=1..12
foreach($number in $arr){ $number *7 }

For å vise hvor kompakt dette kan skrives i PowerShell – se på dette eksempelet:

$o = 1..12 |% {$_ * 7 }
$o

Merk! % er et alias for foreach

Løkker i praksis

Her er et eksempel på løkke i pipeline. Vi henter ut alle filer med endelsen mp3, og itererer over dem. For hver fil erstatter vi mellomrom ” ” med underscore _ ,

get-childitem *.mp3 | foreach { rename-item $_ $_.Name.Replace(” “, “_”) }

Valg

Til å gjøre valg har vi to sentrale metoder, if og switch.

If sammenligner to verdier på den måten vi angir. Hvis utrykket vi sammenligner blir sant, kjøres koden i if setningen. Hvis ikke, går den videre. En if setning kan også ha en else del, som blir kjørt hvis if uttrykket blir usant.

La oss se på et enkelt eksempel:

IfDemo.ps1

[int]$i = Read-Host “Tast inn et tall”
if($i –le 10)
{
Write-host ”Mindre enn 10”
}
Elseif($i –le 50)
{
Write-host ”Mellom 10 og 50”
}
Else
{
Write-host ”Større enn 50”
}

If setninger er best egnet til å sammenligne noe med en eller veldig få verdier. Skal man sammenligne flere verdier bør man bruke switch:

[int]$var=read-host ”Tast inn et tall mellom 1 og 6”
switch ($var)
{
1 {”Option 1”}
2 {”Option 2”}
3 {”Option 3”}
4 {”Option 4”}
5 {”Option 5”}
6 {”Option 6”}
Default {“Ingen treff”}
}

Med switch har vi et sett med sammenligninger vi utfører ( i tilfellet over 1,2,3,4,5,6 – samt default som tar alle de verdiene vi ikke har tatt høyde for). Hvis uttrykket stemmer, for eksempel at vi har tastet inn 3, og vi faktisk har en sammenligning for 3, så kjøres kodeblokken som står bak 3. I dette tilfellet er det { ”Option 3” }.

Sammen med switch kan vi pgså bruke noen parametre:

Tabell 4 Switch parametre

Parameter

Beskrivelse

-regex

Gjør at tekststrengen vi sender inn blir behandlet som en regular expression string, og at vi kan benytte regex uttrykk for å sammenligne verdiene. Merk at denne ikke kan kombineres med wildcard og exact

-wildcard

Matcher strengen vi sender inn som mot alternativene vi tester mot, men med wildcard (slik at det ikke trenger å være eksakt treff)

-exact

Krever at det er et eksakt treff

-casesensitive

Standard er at den IKKE skiller mellom store og små bokstaver. Hvis du ønsker at den skal skille, må du benytte –casesensitive

-file

Tar input fra fil istedet for direkte. Hver linje i fila blir sjekket opp mot sammenligningsgrunnlaget i switch setninga.

La oss se på et eksempel med regex :

SwitchRegex.ps1

$var=”PowerShell123”,”PowerShell”,”123”,”PowerShell 123”
Switch –regex ($var)
{
“^\w+[a-zA-Z]$” { write-host $_” er et ord “}
”^\d+$” { write-host $_” er et tall ”}
”\s” { write-host $_” har et mellomrom ” }
Default { write-host ”Ingen treff for ”$_}
}

Hvis det kan være flere treff i sammenligningene, kan man påvirke om man skal fortsette å sjekke etter å ha fått et treff, eller om man skal avslutte. Dette gjøres med Break og Continue.

Dette merkes med ; Continue eller ; Break. Følgende endringer i scriptet medfører at det fortsetter:

SwitchRegexContinue.ps1

$var=”PowerShell123”,”PowerShell”,”123”,”PowerShell 123”
Switch –regex ($var)
{
“^\w+[a-zA-Z]$” { write-host $_” er et ord “; continue}
”^\d+$” { write-host $_” er et tall ” ; continue}
”\s” { write-host $_” har et mellomrom ” ; continue}
Default { write-host ”Ingen treff for ”$_}
}

Nå skal vi se hvordan switch kan benyttes sammen med –file parameteren til å finne alle linjer med ei IP-adresse i teksten.

Opprett fila adresser.txt med følgende innhold:

Dette er ei linje med ip 12.19.54.123
På denne linja har jeg 76.3.122.19
Denne linja har ingen IP
og denne linja har 10.10.10.10
Denne linja derimot har 201.201.233.24
Hva skal vi med alle disse linjene?

Sørg for at du har lagret fila, og kjør nå følgende kommando i PowerShell:

switch –file addresser.txt –regex {
“\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}” { $_ }
}

Resultatet skal nå se slik ut:

image

Ønsker du å kun se IP-adressene?

switch -file ustrukturert.txt -regex {
"\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}" {$_ -match "\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}" | out-null;$matches.values }
}

image

I dette eksemplet kjører vi to regular expressions – først for å hente ut de linjene som inneholder en IP-adresse, deretter en for å hente kun IP-adressen ut av disse. Jeg kjører pipe to null (out-null) for å skjule true/false som kommer ut av uttrykket ved kjøring (prøv å ta det bort –så ser du hva jeg mener).

Vi har altså hentet ut de linjene som inneholder IP-adresser. Kraftfullt, eller skal jeg heller si Powerfull?

Vi har i denne delen sett litt på variabler, datatyper, løkker og valg. I tillegg har vi sett litt på regular expressions.

Guide/Powershell

Kom igang med Powershell – del 3

Posted by ragnar harper on

Dette er del 3 av Kom igang med Powershell guiden min.

Del 1: Kom igang med Powershell

Del 2: Kom igang med Powershell

Sikkerhetsegenskaper

Et miljø som PowerShell møter store utfordringer sikkerhetsmessig, og disse er ivaretatt på flere måter. Det er tenkt sikkerhet hele veien gjennom utviklingsløpet av PowerShell, og i nå skal vi se nærmere på disse.

Merk at denne oppgaven krever at du er administrator. Hvis du kjører Vista eller nyere, start Powershell som administrator ved å høyreklikke på Powershell ikonet og velg Run as administrator.

Problemer med scriptkjøring

Hvis du dobbeltklikker på ei fil med endingen ps1 vil du åpne Notepad, istedet for at scriptet kjøres.Faktisk vil vi også oppleve problemer hvis vi skriver inn scriptnavnet fra kommandolinjen også…

For at ikke noen skal kunne ersatte kjente programmer og cmdlets, krever PowerShell at du angir mappenavnet for å kjøre et script. Hvis du kun taster inn scriptnavnet, vil PowerShell gi deg feilmelding om at scriptet ikke finnes, som vist i figuren under.

image

For å kjøre et script i samme mappe som du står, må du legge til .\ foran scriptnavnet, som i \.scripttest.ps1.

Den andre sikkerhetstskonfigurasjonen som har påvirkning for kjøring av dine script er PowerShell Execution Policy.

Følgende fire execution policy’s er definert:

  1. Restricted standardvalget. Ingen script kan kjøres – uansett.
  2. AllSigned Alle script som er signert med en sertifikat, og hvor vi har tillit til sertifikatet kan kjøre.
  3. RemoteSigned Alle lokale script kan kjøres, også de som ikke er signert. Remote script (som lastes ned fra Outlook, Internet Explorer osv), må være signert med et sertifikat vi har tillit til for å kunne kjøre.
  4. Unrestricted Alle script kjøres, om de er signerte eller ikke.

For mer informasjon kjør kommandoen

help about_signing.

Ønsker du å se hvilken ExecutionPolicy du har, kjør følgende kommando:

Get-Executionpolicy

For å endre ExtecutionPolicy til å tillate lokale script uten signering, men krev signering fra nedlastede script, kjør følgende kommando

Set-ExecutionPolicy RemoteSigned

Bruk av digitale signaturer

Det anbefales å signere alle script, slik at du kan kjøre med en restriktiv sikkerhetspolicy i PowerShell. Vi går her igjennom en måte å signere script for bruk på utviklermaskiner. Denne fremgangsmåten gjør at du slipper å kjøpe et sertifikat for utvikling. For kjøring i bedrift anbefaler vi at man går til innkjøp av et code-signing certificate, eller utsteder et code-signing sertifikat fra egen PKI infrastruktur.

Vi kommer til å benytte verktøyet makecert.exe fra .NET Framework SDK. Dette kan lastes ned fra http://msdn.microsoft.com/netframework/downloads/updates/default.aspx . Eventuellt finnes også verktøyet i Windows Platform SDK.

Deretter kan du navigere deg til stedet hvor makecert er installert, og kjøre følgende kommando for å opprette et rotsertifikat.

.\makecert -n "CN=PowerShell Local Root" -a sha1 -eku 1.3.6.1.5.5.7.3.3 -r -sv root.pvk root.cer -ss Root -sr localMachine

Når du kjører kommandoen vil du få et dialogvindu som spør deg om passord. Du kan angi et passord her for den private nøkkelen. For vår del  angi ett passord du husker.

Rotsertifikatet er den utstedelsesmyndigheten vi velger å ha tillit til. I tillegg til et rotsertifikat trenger vi en code-signing sertifikat som vi kan bruke på våre PowerShell script. For å utstede dette sertifikatet kjører vi følgende kommando:

 .\makecert -pe -n "CN=PowerShell Developer" -ss MY -a sha1 -eku 1.3.6.1.5.5.7.3.3 -iv root.pvk -ic root.cer

Under denne operasjonen får du også en dialogboks som spør deg om passord. Angi igjen ett passord du husker.

Disse sertifikatene skal nå ligge i maskinens certificate store. Dette kan man naturligvis sjekke via PowerShell:

dir cert:\CurrentUser\My -codesigning | fl

Du skal nå se noe som ligner på følgende:

Subject : CN=PowerShell Developer

Issuer : CN=PowerShell Local Root

Thumbprint : 5F4C985FFCC51AF1A2E0626686BFBD883177280A

FriendlyName :

NotBefore : 01.05.2007 17:26:47

NotAfter : 01.01.2040 00:59:59

Extensions : {System.Security.Cryptography.Oid, System.Security.Cryptography.Oid}

La oss nå signere et script. Først trenger vi å lage et enkelt script.

Opprett scriptet mittscript.ps1 med følgende innhold:

$navn = Read-Host("Hva heter du?")
Write-Host "Hei der..$navn"

Dette kan du for eksempel gjøre i notepad. Husk å lagre fila med etternavnet ps1. I Notepad kan du gjøre dette i Save as dialogboksen ved å legge ” ” rundt filnavnet, eller endre Save As Type til Allfiles. Lagre fila med navnet mittscript.ps1.

Forsikre deg nå om at ExecutionPolicy er AllSigned med Get-ExecutionPolicy. Hvis den ikke er AllSigned, setter du den på følgende måte:

Set-ExecutionPolicy AllSigned

Prøv å kjøre scriptet:

.\mittscript.ps1

File C:\temp\mittscript.ps1 cannot be loaded. The file C:\temp\mittscript.ps1 is not digitally signed. The script will not execute on the system. Please see "get-help about_signing" for more details..

At line:1 char:16

+ .\mittscript.ps1 <<<<

Scriptet er ennå ikke signert, og vil derfor produsere en feilmelding når du forsøker å kjøre det.

La oss signere scriptet!

Først, la oss legge codesigning sertifikatet i en variabel, deretter forsikrer vi oss om at du har fått lagt riktig sertifikat i variabelen $cert.:

 $cert = @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]

Deretter kjører vi følgende kommando for å forsikre oss om at du har riktig innhold i variabelen $cert:

$cert

Du skal da ha ett resultat som ligner på følgende:

Directory: Microsoft.PowerShell.Security\Certificate::CurrentUser\My

Thumbprint Subject

———- ——-

5F4C985FFCC51AF1A2E0626686BFBD883177280A CN=PowerShell Developer

Tips: Hvis du har opprettet flere sertifikater kan det være du må endre [0] til [1] eller en annen verdi. Du kan liste ut alle mulige sertifikater ved å kjøre kommandoen

Get-ChildItem cert:\CurrentUser -codesigning

Deretter kjører vi kommandoen Set-AuthenticodeSignature kommandoen for å signere fila., som anvist i linje 31 under.

Set-AuthenticodeSignature mittscript.ps1 $cert

Prøv nå å kjøre scriptet:

.\mittscript.ps1

Du får nå opp en advarsel om at du ikke har tillit til sertifikatet som er benyttet.

image

Ved å svare A (Always) på spørsmålet (under forutsetningen at vi har tillit til oss selv), så slipper vi denne dialogboksen seinere.

Men hva skjedde med scriptet?

Ta en titt i fila mittscript.ps1. Du kan gjerne gjøre dette i PowerShell med kommandoen get-content på følgende måte:

[33] » get-content mittscript.ps1

Du vil nå finne at det er lagt til ekstra informasjon i fila. I mitt tilfelle ser denne ekstra informasjonen ut slik;

# SIG # Begin signature block

# MIIEFAYJKoZIhvcNAQcCoIIEBTCCBAECAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB

# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR

# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUmQ9ec2cWO48xOLDpsvAtUabg

# 8hOgggIqMIICJjCCAZOgAwIBAgIQh7ANpUqeMZRF/QepIQRyIDAJBgUrDgMCHQUA

# MCAxHjAcBgNVBAMTFVBvd2VyU2hlbGwgTG9jYWwgUm9vdDAeFw0wNzA1MDExNTI2

# NDdaFw0zOTEyMzEyMzU5NTlaMB8xHTAbBgNVBAMTFFBvd2VyU2hlbGwgRGV2ZWxv

# cGVyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCslEI1W+iqe0BTKL8TUSzD

# Uv6ZZbnUk46wzwJ9uHNggfjGEtLiVKWxvFTM1BgM+/5mYtYFz5Vssoo84VI7EuGf

# umeIU1DWyIh4J1q4Md6/Hn/NHkDQTINfCsi7+IM2BgLBk2I8KOqeweLq5F0rgcfE

# h/GmaQS6UT2hPjYyGF4vdwIDAQABo2owaDATBgNVHSUEDDAKBggrBgEFBQcDAzBR

# BgNVHQEESjBIgBBtQRksbGaKclauFeJPoqQkoSIwIDEeMBwGA1UEAxMVUG93ZXJT

# aGVsbCBMb2NhbCBSb290ghDCpdCfKLjirEFA1TvQWmFhMAkGBSsOAwIdBQADgYEA

# sO0IXieIH8Ke+t8XNH61ZJkrNXP3tClGR1Y4wErxBDdvHAw4zN3CCz2x/JjF30/h

# /SADj0keE+LVjojWg5EbSZdY3gdFu8WTBHiK0eh+g9F4XCV71SN2VYbc6wMf1BSc

# leAxAPUwzq0BDXSPbKXo2exUhK3zRZRZ7jdwqVZi0+cxggFUMIIBUAIBATA0MCAx

# HjAcBgNVBAMTFVBvd2VyU2hlbGwgTG9jYWwgUm9vdAIQh7ANpUqeMZRF/QepIQRy

# IDAJBgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG

# 9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIB

# FTAjBgkqhkiG9w0BCQQxFgQUL8LCtPpgpJi4d7Jm+Hs2K4aBRf4wDQYJKoZIhvcN

# AQEBBQAEgYCBopCZvbkxsEh3ZUzlTQQef2UqmmHhhK5QEqLtY3VChYfCAIa4XexK

# 9/KHz9EOBcx8tk0PzqkD2Kqe3UGSYAAGf5xwTfeXGtrOyOoPCD2shKAyb7eivp++

# J4CgYwptBgoD/9P0rG1UiXFYkhWKhMUeYV0Y1KZQlPnDqaM6fjM8sw==

# SIG # End signature block

En bedre måte å lese ut informasjon på vil for de fleste være å kjøre get-authenticodesignature kommandoen :

get-authenticodesignature mittscript.ps1 | fl

Vi har nå opprettet et sertifikat vi kan bruke for test og utvikling. I produksjon anbefaler jeg at du benytter eventuell intern PKI infrastruktur eller et kjøpt code-signing sertifikat.

Etter at du har installert code-signing sertifikatet på din maskin, kan du da laste det inn, og benytte Set-AuthentiCodeSignature med det sertifikatet.

Før vi nå går videre kan det være smart å endre ExecutionPolicy tilbake til RemoteSigned

Set-ExecutionPolicy RemoteSigned

Vi har i denne artikkelen sett på signering av script i Powershell.

Guide/Powershell

Kom igang med Powershell – del 2

Posted by ragnar harper on

Du finner del 1 her.

Bruk av moduler i Powershell

Den primære måten å utvide funksjonaliteten i Powershell 2.0 er gjennom bruk av moduler. En modul er en pakke som inneholder Powershell kommandoer, slik som cmdlets, funksjoner, variabler, alias og såkalte providers. Providers gjør det mulig å aksessere datakilder gjennom stasjonsalias.

Moduler lar utviklere og administratorer dele opp og organisere Powershell koden i gjenbrukbare, komplette pakker. Kode fra en modul utføres i sin egen kontekst, og affekterer ikke tilstanden utenfor modulen.

Der snapins må installeres (dll basert installasjon) og registreres i registry, kan moduler enkelt kun kopieres inn uten noen form for installasjon.

Fordi moduler ikke må installeres, kan man bruke disse uten å være administrator.

Du kan altså benytte både moduler og snapins for å legge til kommandoer i ditt Powershell miljø. Moduler kan legge til alle typer kommandoer, cmdlets, providers, funksjoner, variabler, aliase og stasjoner. Snapins kan kun legge til cmdlets og providers.

Hvis du ønsker å se hvor en cmdlet er definert, kan du utføre følgende kommando:

get-command <cmdlet-name> | format-list -property verb, noun, pssnapin, module

For eksempel, hvis du ønsker å se hvor Get-Process er definert:

get-command get-process | format-list -property verb, noun, pssnapin, module

Moduler kan lastes fra hvor som helst, men det er enklest å benytte erklærte modulområder. Ved å bruke erklærte modulområder er det lettere å oppdage modulene, samt at de kan aktiveres uten at hele stien til modulen må angis. Det er i utgangspunktet to erklærte områder hvor moduler kan ligge:

· %System%\WindowsPowershell\1.0\Modules ($PSHome\Modules)

· %Userprofile%\Documents\WindowsPowershell\Modules

Du kan sjekke hvilke stier som er erklærte modulområder på ditt system ved å kjøre følgende kommando:

$env:psmodulepath

image

Modulfilene kan kopieres til brukerens modulområde, eller til systemets modulområde. Man kan også laste moduler ved å eksplisitt angi banen til modulen.

For å aktivere modulen bruker man kommandoen Import-Module og modulens navn. Man kan få en oversikt over tilgjenglige moduler ved å bruke kommandoen Get-Module –ListAvailable.

Redirection

I alle kommandolinjer er redirection en sentral funksjon, hvor man styrer output dit man vil ha det. For eksempel ønsker du å lage deg etn oversikt over alle cmdlets som er tilgjengelig. Denne oversikten ønsker du å ha i ei fil.

Get-command > commandref.txt

Ved å erstatte > med >> legger du til teksten, hvis fila finnes fra før med innhold.

Senere vil du se at det også er flere måter å oppnå dette på, også for å styre output andre steder.

Hvis du ønsker å skrive ut alle kommandoene grupper etter subjektivet, så kan du kjøre følgende kommando:

Get-command | sort-object noun |format-table –group noun

Spesialtegn

Noen ganger har du behov for skrive ut tegn som egentlig ikke skrives ut synlig, slik som linjeskift, tabulator eller lage en lyd.

Tegn

Escape sekvens

Null

`0

Alert

`a

Backspace

`b

Form Feed

`f

Ny linje (Linjeskift)

`n

Carriage Return (Enter)

`r

Tab

`t

Vertical quote

`v

Prøv følgende kommando for å bygge din egen tre kolonners rapport.

[20] » write-host "Kolonne1 `t Kolonne2 `t Kolonne3 `nRekke1-1 `tRekke1-2 `tRekke1-3 `nRekke2-1 `tRekke2-2 `tRekke2-3"

Kolonne1 Kolonne2 Kolonne3

Rekke1-1 Rekke1-2 Rekke1-3

Rekke2-1 Rekke2-2 Rekke2-3

[21] » write-host `a`a`a`a

Scope

Funksjoner og variabler har en begrenset synlighet og levetid i Poweshell. Dette betyr at verdier vi setter eller funksjoner vi oppretter ikke nødvendigvis er tilgjengelig i hele systemet. Man kan se på scope i et foreldre-barn (parent-child) perspektiv, hvor det første og øverste leddet heter global. Childscopes kan aksessere verdier i et parentscope, men ikke motsatt. Scopet til det kjørende scriptet er navngitt script, og når vi kommer til variabler skal vi se litt nærmere på dette. Men jeg ønsker å presentere begrepet dot sourcing; når vi starter script fra PowerShell benytter vi ofte et punktum (dot) før scriptnavnet. Dette betyr at scriptet skal kjøre i samme scope som kommandolinja kjører i, og gir samme funksjonalitet som om du skulle skrevet alle kommandoene i kommandolinja direkte.

Funksjoner

Funksjoner er små rutiner med kildekode. Dette betyr kodelinjer satt sammen til å utføre en bestemt oppgave. Funksjoner har sin egen scope. Det betyr at variabler som deklareres og finnes i en funksjon kun er tilgjengelig til funksjonen. Hvis funksjonen kjører som en del av et script, har funksjonen adgang til scriptetes scope, fordi scriptet er funksjonens foreldre scope.

Eksempel på funksjon:

Function foo {write-host “bar”}

image

Pipelining

En av Powershells kraftigste fordeler er pipelining funksjonaliteten. Pipelining betyr å flytte data og objekter fra en kommando (cmdlet) til en annen.

Et eksempel mange kjenner seg igjen i fra cmd.exe verden er more

dir | more

Denne kommandolinjen tar resultatet fra dir kommandoen og ”piper” det til more.

Tradisjonelt pipes data mellom kommandoer i tekst format. Dette er endret med PowerShell, hvor data pipes som objekter. Dette er en meget sterk måte å håndtere data mellom objekter på, som gir flotte muligheter for avanserte script. Vi kommer til å bruke pipelining mye i resten av kurset.

Tegnet for pipe er |

Kjør følgende kommando:

Get-process | where { $_.handlecount –gt 400 } | format-list

Denne kommandoen henter en liste med kjørende prosesser ( get-process). Deretter så piper den resultatet inn i where . Fordi vi flytter objekter over til where kommandoen kan vi lese av attributter på objektet. Et process objekt har flere egenskaper, men vi leser av egenskapen handlecount. $_ er en standardangivelse for resultatet av foregående operasion, så med $_ mener vi resultatet fra foregående kommando. –gt står for større enn (greater than). Etter at vi har plukket ut alle processobjekter som har handlecount større enn 400, formaterer vi dette som en liste før vi skriver ut (format-list).

Tips:

Når man benytter where kan man også sette sammen flere uttrykk:

-and Logisk and

-or Logisk or

-bor Bitwise or

-band Bitwise and

-xor XOR operator

For å se en liste over alle egenskapene processene har som vi kan jobbe med, kjør følgende kommando:

get-process | get-member -membertype property

I lista vil du nå finnes egenskapen responding, som er satt til en boolsk egenskap. Vi kan nå liste ut alle prosesser som ikke svarer (not responding) med følgende kommando:

Get-process | where { $_.responding –eq 0 } | format-list

Merk at overstående kommando mest sannsynlig ikke returnerer noen treff i din test – den returnerer kun applikasjoner som henger!

Eller alle prosesser som svarer:

Get-process | where { $_.responding –eq 1 } | format-list

Vi kan også endre formateringen, og bestemme hvilke felt som skal være med I utdata på følgende mate:

get-process | where { $_.responding -eq 1 } | format-table ProcessName,Id,Responding

Vi kan også bygge videre på et tidligere eksempel hvor vi lister ut filer, og ønsker å formatere resultatet av dir kommandoen (en linje) :

Dir –exclude *.old,*.bak,*.tmp –recurse | select-object FullName,Length,LastWriteTime | format-table –auto

Denne kommandoen lister ut alle filer i mappen vi står i, samt undermapper. Den tar ikke med filer med endelsen old, bak eller tmp. For hver av filene skriver den ut fullt navn, størrelsen, og siste gang den ble skrevet til. Dette formateres i en tabell.

Format-Table skal vi se nærmere på seinere også ,men den har også mulighet for å bestemme hvilke felt som skal vises eller ikke. Fordelen med å bruke Select-Object er at vi kan sende utdataene andre steder enn til skjermen (for eksempel til fil) og kun få med de utvalgte feltene.

Hjelpesystemet

PowerShell har et kraftig hjelpesystem, som baseres på kommandoen get-help og get-pagedhelp. Det er også opprettet alias som help og man for Get-PagedHelp.

For å lage deg en oversikt over hvilke hjelpefiler som er tilgjengelig kan du kjøre kommandoen help *_*

Help *_*

Disse hjelpefilene begynner med about_ og omhandler emner du kan slå opp i hjelpesystemet.

Wildcards er også støttet i oppslagene, for eksempel kan du slå opp hjelp for logiske operatører med følgende kommando:

[56] Get-help about_logi*

Du kan hente fullstendig hjelp ved å benytte parameteren –full

Get-help new-item –full

De fleste av oss leter etter eksempler når vi prøver å benytte en kommando. Du kan hente kun eksemplene på følgende måte:

Get-help new-item -examples