Kategoriarkiv: Active Directory

LDAP Connection string

Jeg har fået en del spørgsmål på det sidste om ovenstående. Jeg har set en del bruge ldap://domænenavn som en LDAP Connection String, men det er ikke korrekt.. Sådan en består typisk af 3 ting:

  1. En URI LDAP://
  2. Navnet på kataloget (hvis det er Active Directory er det domænets DNS navn)
  3. Stien til hvor man vil søge i kataloget

Hvis vi forestiller os at der skal søges i bruger-folderen skal vi pege på Users folderen. I et Active Directory med DNS navnet firmaet.dk, så ville strengen se således ud:

LDAP://Firmaet.DK/CN=Users,DC=Firmaet,DC=DK

Du kan nemt finde ud af hvor en bruger ligger i Active Directory ved at benytte powershell og hente ham frem med get-aduser og så kigge i attributten DistinguishedName. DistinguishedName returnerer også brugernavn, så det skal du lige huske at fjerne før du copy/paster den.

Hvis du bare skal søge fra roden kan du bruge:

LDAP://Firmaet.DK/DC=Firmaet,DC=DK

 

 

Billeder i Active Directory

Jeg har i et stykke tid benyttet CodeTwo´s program “Active Directory Photos” til at opdatere brugernes billeder i Active Directory, det er nemlig et fantastisk produkt, hvis man bare skal have opdateret en sjælden gang. Find det her. Det er dog rimeligt besværligt at benytte hvis man skal opdatere dagligt eller ugentligt fra en base af billeder. Jeg har derfor lavet nedenstående script der kan gøre det helt automatisk..

Billeder i Active Directory lægges i den attribut der hedder ThumbnailPhoto og for at lægge et billede i den skal vi først konvertere billedet til en struktur som powershell forstår. Og da der er mere end 1 billede lægger jeg dem selvfølgelig i en variabel form.

Billedet hentes ind i en variabel

$Photo = [Byte[]] (Get-Content “sti til billeder” -Encoding Byte)

Og dette lægges ind i attributten ThumbnailPhoto ved at gøre følgende:

Set-ADUser -Identity “Username” -Replace @{thumbnailPhoto=$photo}

Ovenstående er grundfunktionerne og for at gøre det for flere billeder skal vi selvfølgelig bruge lidt mere avancerede funktioner. I følgende eksempel kører jeg en 3-trins raket af et script, først hentes brugernavne i AD og dernæst hentes billeder på en sharepoint side (da det typisk er der man vil have et billede af de ansatte) og til sidst uploader vi billederne til AD. Bemærk at jeg ikke har angivet nogle bruger med rettigheder til at hente brugernavne fra AD, jeg forventer at dette er muligt for alle. Men hvis dit Active Directory har enablet ListObjectModeOnly og ikke tillader dette, skal du selvfølgelig også angive en bruger til at hente brugernavne med.

$Cred = Get-credential  – brugernavn og kode der giver rettigheder til at hente billederne

$Cred2 = Get-Credential - Brugernavn og kode der giver rettigheder til at uploade billederne

$A = (Get-ADUser -filter * | where {$_.samaccountname.length -eq 5}).samaccountname - Henter brugernes samaccountname

foreach ($item in $A)

{Invoke-WebRequest -Uri “hjemmeside url/$item.jpg” -Method “get” -OutFile folder\$item.jpg -Credential $cred} - Henter billederne

foreach ($item in $A)

{$photo = [byte[]](Get-Content folder\$item.jpg -Encoding byte) - Konverterer dem til byte

Set-ADUser $item -Credential $Cred2 -Replace @{thumbnailPhoto=$photo} } - Uploader billederne

Ovenstående vil selvfølgelig fejle hvis ikke der er et billede til brugeren på siden og det kræver at billederne er navngivet brugernavn.jpg og er måske ikke brugbart for alle, men det giver et meget godt indblik i hvad der skal til for at uploade billeder automatisk. Det er også muligt at man kan finde en bruger der har adgang til det hele og så er det selvfølgelig kun 1 $cred der skal bruges.

 

Restore af objekter i AD

Ved hjælp af værktøjer der bliver leveret med Active Directory er det muligt at restore objekter enkeltvis (såfremt man har en SystemState-backup.) Active Directory´s egen papirkurv er genial, men hvis man nu skal langt tilbage eller ikke har aktiveret papirkurven, så er nedenstående vejen frem. Jeg bruger Fredrik Lindströms værktøj DSCT for at gøre livet lidt nemmere for mig selv, det kan hentes her (download link er midt på siden.)

Først skal vi have en version af ntds.dit filen som indeholder det objekt vi gerne vil restore. Hvis du gerne vil lave en hurtig test, så kan dette gøres ved at køre følgende på en DC:

Ntdsutil “ac i ntds” Sn C Q Q

Ovenstående er den meget kort udgave af Ntdsutil | Active Instance NTDS | Snapshot | Create | Quit | Quit

Nu skal vi have vores snapshot “mounted” så vi kan få fat i databasen. Dette gøres ved at skrive følgende:

Ntdsutil sn “li a” “mo 1″ Q Q

Som er den meget korte udgave af Ntdsutil | Snapshot | List All | Mount 1 | Quit | Quit – jeg forventer at der kun er 1 snapshot, hvis ikke skal du selvfølgelig lige tjekke datoen på dine snapshots og mounte det relevante. Hvis det kun er for denne ene test du prøver det kan du også springe et trin over og køre:

Ntdsutil “ac in ntds” sn cr “li a” “mo 1″ Q Q

Så tager man et snaphot og mounter det i en kommando, husk at unmounte efterfølgende især hvis det er produktions data du sidder og leger med (det er det selvfølgelig IKKE.) Snapshot unmountes ved at køre:

Ntdsutil Sn “Li A” “Un 1″ Q Q

Så nu har vi et snaphot og det ligger klar i en folder på c-drevet der hedder noget lignende $Snap_ÅÅÅÅMMDDTTTT_VolumeC$. Folderstrukturen ligner den der er taget backup af og i mit tilfælde betyder det at databasen ligger under c:\$Snap_ÅÅÅÅMMDDTTTT_VolumeC$\windows\ntds\ntds.dit. Denne kan bruges fra denne lokation eller man kan kopiere den til en anden folder og bruge den derfra. Igen kal man huske på at dette er en backup af en bruger database og disse data kan være sensitive. For at mounte databasen skal vi have fat i Dsamain. I it tilfælde vil kommandoen se således ud:

Dsamain -dbpath c:\$Snap_ÅÅÅÅMMDDTTTT_VolumeC$\windows\ntds\ntds.dit -ldapport 11389 -allownonadminaccess

Nu har vi en kopi af vores Active Directory tilgængelig på port 11389, denne kan man forbinde sig til vha ldp og kigge ned i databasen som den så ud på tidspunktet for snapshottet. Hvis du ønsker at genkabe objekter fra den kan man trække dem ud med LDIFDE og CSVDE, men som sagt så er Fredrik Lindströms værktøj Directory Services Compare Tool så meget nemmere og hvem vil ikke gerne spare tid. ;)

Installer DSCT | Start en MMC | Add Remove Snap-Inn  |  Directory Services Compare Tool | Under Actions i højre side (ikke i menuen) vælges Datasoruce Settings | Øverst skrives sti til Live Active Directory | Nederst Snapshot | OK

 

 

Directory Services Compare Tool - datasources

Nu kan vi så se hvilke forskelle der er på vores snapshot og vores live AD.

Directory Services Compare Tool

Hvis du kigger under deleted kan du se hvilke objekter der er slettet siden og hvis du kigger under added.. Ja det giver mening ikke?

Directory Services Compare Tool - restore

Marker de slettede objekter og vælg reanimate.

Directory Services Compare Tool - reanimate

Tryk på ok tjek dit AD og konstater at dine objekter er tilbage. Husk at sætte protect from deletion og aktiver brugerne igen, men ellers er du kørende.

Hent champagnen og modtag folkets hyldest! ;)

Og kudos til Fredrik Lindström for et mega fedt tool!!

Active Directory backup

Backup af Active Directory er ganske simpelt på windows 2008 server og senere versioner, det svære er at restore objekter enkeltvis. Jeg har set flere der betaler for backup programmer der kan dette, men gætter på at det skyldes historiske årsager at de ikke er skiftet ud for længst!

Men lad os lave en backup af vores AD først så kan vi kigge på restore af det bagefter.

For at tage backup af AD skal man først installere Windows Backup. Dette gøres nemt ved at køre add-windowsfeature windows-server-backup fra en powershell prompt, jeg plejer at give den en -IncludeAllSubFeature også så jeg er sikker på at der ikke mangler en eller anden komponent. Det kan være utrolig tidskrævende at fejlfinde på den slags.. ;)

Add-WindowsFeature Backup-Features -IncludeAllSubFeature

-Name er en optional og kan derfor undværes og hvis man gør det fra powershell 2.0 skal man først loade modulet servermanager, det sker automatisk i 3.0.

Når Windows Backup er installeret kan man køre backuppen fra en prompt

WBAdmin Start SystemStateBackup -BackupTarget:D: -Quiet

Ovenstående kan scheduleres til at køre som man lyster, jeg kører den dagligt kl 21. Scheduleringen kan laves ved at køre følgende:

schtasks /create /SC DAILY /ST 21:00 /RU SYSTEM /TN BackupSystemstate /TR “wbadmin start systemstatebackup -backupTarget:C: -quiet -output:D:\WindowsImageBackup\Backup.txt”

Nedenstående sørger for at vi kun har 5 versioner efter hver backup er kørt. Den sletter alt andet end de sidste 4 og da backuppen så kører 15 min senere har vi 5 versioner. Det er selvfølgelig ikke nok for de fleste virksomheder, da brugere ofte opdager problemer senere end 5 dage og derfor kan man selvfølgelig rydde op som man lyster. Jeg har gjort det på denne måde da jeg så har 5 versioner online og vores backup system kommer så senere og tager en backup af disken og gemmer dem i 5 år. Så er jeg rimelig sikker på at kunne behage alle der måtte have lyst til at kigge i AD historik eller få deres bruger/grupper osv tilbage.

schtasks /create /SC DAILY /ST 20:45 /RU SYSTEM /TN BackupScavenge /TR “wbadmin delete systemstatebackup -keepversions:4 -quiet -output:D:\WindowsImageBackup\BackupScavenge.txt”

Såfremt backuppen der tages skal skrives til samme disk som Active Directory er installeret på er der lige en lille krølle. Windows Backup kan ikke tage backup til samme disk som den tager backup af, dette giver mening for en fuld disk-backup, men for systemstate burde det være ok at lægge den der midlertidigt. Derfor har MS også været så venlige at muliggøre dette ved en lille ændring i Registry. Windows Backup ligger under HKLM\System\CurrentControlSet\Services\WBEngine og hvis ikke den er der allerede, skal man oprette en nøgle der hedder SystemStateBackup og tilføje en 32-bit Dword værdi, navngive den AllowSSBToAnyVolume (Allow System State Backup To Any Volume) og give den værdien 1.

New-Item -Path HKLM:\SYSTEM\CurrentControlSet\Services\wbengine -Name SystemStateBackup

New-ItemProperty “HKLM:\SYSTEM\CurrentControlSet\Services\wbengine\SystemStateBackup” -Name “AllowSSBToAnyVolume” -Value 1 -PropertyType “DWord”

Eller hvis du vil være old-school

reg add HKLM\SYSTEM\CurrentControlset\Services\wbengine\SystemStateBackup /v AllowSSBToAnyVolume /t REG_DWORD /d 1 /f

Vend wbengine servicen og så er det muligt at smide en midlertidig backup af AD på samme drev som AD har sine database.

Nu har vi en backup og så håber vi selvfølgelig at vi aldrig kommer til at bruge den. Men hvis vi skal så kig på restore-artiklen for en nem vejledning i restore af objekter i AD.

Når rollerne skal byttes om..

Det har været en fantastisk start på ugen! 1 domæne hvor FSMO rolle-holderen blev smadret ved skift af noget hardware og 1 domæne hvor klienter har ventet længe på at logge på, fordi de kommer fra et ukendt subnet. Begge problemer kan nemt klares, men den sidste er lidt svær at gennemskue hvis ikke man kender sine værktøjer.

Lad os først kigge på overførsel af roller fra en “død” dc og oprydning efter dødsfaldet.

I 2008 er det jo nemt at flytte roller fra en dc til en anden. Hvis man sletter den i Users and Computers, så advarer gui´en om at den havde nogle roller og disse bliver flyttet til en anden dc. Tak til ms for den lille hjælp! Men hvad nu med os der ikke roder med gui´er?? Vi skal bruge ntdsutil!

Gør følgende for at flytte rollerne fra en off-line dc til en on-line dc.

I kommandoprompt skrives

Ntdsutil |Roles | Connections | Connect to Server >Servernavn på server der skal have rollerne< | q | Seize >navn på rolle der skal flyttes< * | q | q

* Hvis man vil have en liste over roller, kan man bare skrive ? så kommer der en liste frem over muligheder.

Mulige roller:

PDC | Infrastructure master | Naming master | RID master |Schema master

Nu er rollen/rollerne flyttet og almindelig drift kan genoptages. Bemærk at ovenstående er fuldstændig samme procedure som når rollerne skal flyttes fra en on-line DC til en on-line DC med den eneste undtagelse at det så er Transfer og ikke Seize i 6 linie.

Nu skal vi så have ryddet op efter den afdøde og det er kedeligt og der er IKKE en gui der gør det for os.

Igen skal vi have fat i Ntdsutil.

I en kommandoprompt skrives:

Ntdsutil | Metadata cleanup | Connections | Connect to server >Servername< (vælg rolleholderen for domænet) | q | Select operation target | List domain | Select domain 0 (vælg det nummer der repræsenterer det domæne den døde dc er i) | List sites | Select site 0 (vælg det nummer der repræsenterer det site den døde dc er i) | List servers in site | Select server >servernavn< (navn på den døde dc) | q | Remove selected server | yes | yes | q | q

Nu er vi godt på vej og mangler bare DNS og Sites and Services

Start DNS Management konsollen (DNSMGMT.MSC i en kør-boks)

På forward lookup og reverse lookup zonerne skal man højreklikke vælge “name servers” og fjerne dc´en fra listen af navne servere.

Under

_msdcs.>domainname< | DC | _tcp

fjernes dc´en fra listen af Ldap udbydere

_msdcs.>domainname< | DC | _sites | sitename | _tcp

fjernes dc´en fra listen af Kerberos udbydere

Nu mangler der kun Sites and Services og så er vi færdige.

Start Sites and Service ved at skrive dssite.msc i en kør-boks

Lokaliser sites dc´en er i og fjern den!

Og så tror jeg det er tid til en kop kaffe!! ;)

Domæne overblik fra powershell

Domæne class´en er ligesom forest class´en, dog indeholder den en masse information om domænet.. (Big surprise)

I domæne class´en finder man ejeren af domæne rollerne (og vi ved jo alle at det er PDC emulator, RID master og Infrastructure master), domæne controllere, domænets version (mode) og en masse andet. Igen kan vi trække disse informationer ud og modulere dem på kryds og tværs.

Vi skal have fat i class´en først og jeg vil som altid gerne undgå at skrive alt for meget, derfor smider jeg den i en variabel.

 

$Domain = [System.DirectoryServices.ActiveDirectory.Domain]::getcurrentdomain()

For så at få domæne controllere ud af denne liste, kan man skrive:

$Domain.get_domaincontrollers() | fl

Ydermere hvis man ønsker at få både en liste over domæne controllerne og deres operativ system kan man skrive:

$Domain.get_domaincontrollers() | fl name,OSVersion

Så er det trods alt nemmere at dokumentere sit AD. ;)

AD Sites fra powershell

Mangler du et hurtigt overblik over dine AD Sites? Jeg synes ofte jeg roder rundt i Sites and Services og leder. Og man kan sige meget om Sites and Services, men hvis man har 100+ sites så bliver det uoverskueligt. Med powershell er det muligt at trække information om dine sites ud sortere, filtrere og exportere data på kryds og tværs som det nu lyster dig.

For at trække data fra AD omkring dine sites skal vi have fat i forest class. Dette gør jeg normalt ved at lægge den i en variabel, på den måde slipper jeg for at skrive en meget lang class streng igen og igen.

$Forest = [System.DirectoryServices.ActiveDirectory.Forest]::getcurrentforest()

Nu indeholder variablen $Forest vores forest class. For at hente vores sites fra den skrives:

$Forest.get_sites() | fl

Forest class´en indeholder meget mere info, prøv bare at skrive $Forest, frem kommer navn, sites, domæner, gc, forest mode, rod domæne osv.

Kerberos problemer på webserveren?

Jeg har tidligere skrevet om problemer med kerberos´ tokenstørrelser i forhold til at logge på ADFS servere, men det gælder alle webservices der understøtter kerberos og jeg synes derfor jeg ville lave en uddybende forklaring og også give den helt rigtige opskrift på hvordan man retter sin egen http.

Problemet med et for stort kerberos token opstår når der er brugere der er medlem af så mange Active Directory grupper at deres token bliver for stort til at kunne overføres via http protokollen. Grundlæggende tillader http på en windows server at tokenet er 16384 Byte stort altså 16KB. Dette kan man rette ganske simpelt, men der er nogle overvejelser man skal gøre sig før man begiver sig ud i det. Den første er hvor meget ram man har i serveren kontra hvor mange brugere der tilgår serveren samtidig. Eksemplet i denne artikel omhandler en exchange server der reelt kun videresender brugere der leder efter deres exchange server (autodiscover) og i det tilfælde er der ingen fare ved at udvide til 64Kb altså en faktor 4 i forhold til det serveren accepterer ved installation. Men hvis ens server i forvejen er belastet eller er tæt på at være det, kan det betyde nedsatte svartider og dårligere service overfor ens brugere. Så vær varsom.

Selve tilretningen er simpel og bør ikke tage særlig lang tid, men husk på at når http servicen genstarter, afbryder den forbindelsen til alle brugere der er forbundet. Så alt efter forretningens politik for den slags, skal man nok forberede brugerne og foretage tilretningen udenfor perioder hvor serveren er tungt belastet.
For at rette størrelsen på det tilladte token skal vi have fat i nøglen HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters i registreringsdatabasen. Under denne skal vi lægge 2 nye parametre ind, mm de er der allerede så skal vi bare tilrette dem. ;) Parametrene er MaxFieldLength og MaxRequestBytes og de skal se ud som nedenstående for at øge værdien til 64K.

“MaxFieldLength”=dword:0000fffe
“MaxRequestBytes”=dword:0000fffe

Når disse er lagt ind skal vi have genstartet http servicen. Denne er ikke tilgængelig under services konsollen da det er en kernelservice. Den skal stoppes og startes fra en kommando prompt ved at skrive:

Net stop http

Bemærk at den forespørger om man nu er sikker og samtidig fortæller hvad den trækker med ned. De services den trækker med ned kommer ikke op igen når http servicen startes, de skal startes manuelt. Jeg gør det normalt fra en powershell prompt og så laver jeg et hurtigt lille script der starter de berørte services, på den måde kan jeg minimere mine nedetider til få minutter. I dette tilfælde meddeler http at den stopper 5 ekstra services:

net stop http

 

 

 

 

for at starte dem enkeltvis i powershell skrives:
start-service servicenavn

Efter gentart af http servicen og start af de 5 services er webserveren klar til at modtage brugere med token størrelser på op til 64k. Så kan man spørge sig selv hvorfor jeg ikke korrigerer for base64 encodingen og sætter grænsen til 48K? Det er fordi problemet her er hvor meget der kan overføres til serveren og der er base64 encodingen ikke et problem. Det er til gengæld meget vigtigt når man vælger MaxTokenSize på sine klienter. For hvis man tillader dem at benytte tokens der er større en 48K, risikerer de ikke at kunne logge på webservere når deres token er blevet base64 obfuskeret. ;)

Oprettelse af AD bruger fra Powershell

Nu er oprettelse af en bruger fra powershell ikke ligefrem hjernekirurgi, men der er alligevel nogle detaljer der kan besværliggøre det.

Oprettelse af en bruger er simpelt: New-Aduser “Michael Hovej”

Problemet med min nye bruger er at han ikke kan logge på, men det løser man vel ved at skrive: New-ADUser “Michael Hovej” -PassThru | Enable-ADAccount ikke?

Desværre er det ikke så simpelt. Min nye bruger har ikke fået defineret et kodeord og da AD ikke vil aktivere brugere der ikke har et kodeord, skal det sættes først. Men mon ikke det så bare er at skrive New-ADUser “Michael Hovej” -AccountPassword “Password01″ -PassThru | Enable-ADAccount? Igen nej. Powershell smider ikke et kodeord videre til AD i klar tekst. Kodeord skal skrives som såkaldte secure-strings. Der er 2 måder. Den ene måde er at samle det op i en variabel som vist her:       $Cred =  Read-Host “Indtast Password” -AsSecureString og så bruge variablen til at sætte kodeord med, som her: New-ADUser “Michael Hovej” -AccountPassword $Cred -Passthru | Enable-ADAccount Nu er brugeren oprettet og aktiveret.

Der er som sagt 2 måder og den anden muliggør at vi laver brugeren, sætter kodeord og aktiverer brugeren i en “one-liner” og det er jo så sexet som det kan blive. ;)

New-ADUser “Michael Hovej” -AccountPassword (ConvertTo-SecureString “Password01″ -AsPlainText -Force) -PassThru | Enable-ADAccount

Bemærk parameteren -PassThru som sender det objekt der lige er lavet videre til næste kommando, meget smart. Skal ovenstående bruges sammen med en csv import skal man bare køre den med en for-each som her:

Import-Csv “sti til csv fil” | ForEach-Object {New-ADUser $_.Name -AccountPassword (ConvertTo-SecureString “Password01″ -AsPlainText -Force) -PassThru | Enable-ADAccount

$_.Name er så “Michael Hovej” i csv filen og man kan selvfølgelig smide alle de variabler ind fra csv´en som det er muligt og så oprette en bunke brugere.

Voila er vist ordet. ;)

Installation af en ADFS Proxy server

Jeg har gennemsøgt nettet efter en guide til installation af en ADFS proxy server og jeg er endnu ikke lykkedes med at finde en der er komplet. Dette er så mit forsøg på at lave en guide der indeholder alle forudsætningerne for at installere en ADFS Proxy server.

Først en beskrivelse af mit miljø, da det kan være afgørende på et punkt. Jeg har et standard setup med en ADFS på et internt net og en proxy i en DMZ. Den interne Server benytter et certifikat fra mit eget PKI og den eksterne benytter (selvfølgelig) et certifikat fra en standard certifikat udbyder. Hvis man læser best practices for ADFS installationer, skulle dette være den helt rigtige og sikre måde at gøre det på.

En installation kræver følgende:

En windows server 2008 r2. Den behøver ikke være meldt ind i et domæne, men hvis det ønskes for nemmere administration af serveren, skal det være et andet domæne end det den interne ADFS server er meldt ind i.

ADFS v2 softwaren:
http://www.microsoft.com/en-us/download/details.aspx?id=10909

Update roll-up package 2.0:
http://support.microsoft.com/kb/2681584

Certifikater:
Rod CA for det certifikat der er benyttet på den interne ADFS server eller farm og det offentlige certifikat der skal benyttes på webserveren.

Trin for trin:

Installer ADFS softwaren

Installer certifikater i computerens CAPI store. (vejledning)

Installer certifikat på webserveren. (Vejledning)

Start Active Directory Federation Services Proxy Wizard. Når du kommer til establish trust delen, skal du være opmærksom på at brugeren der skal benyttes til at godkende med, er den bruger som ADFS servicen på den interne ADFS server benytter.

Dette er alt der skal til. Der hvor jeg mener der er afgørende mangler i de beskrivelser jeg har set online, er at ingen nævner Rod CA for certifikatet der er installeret på de interne ADFS servere og fejlbeskrivelsen der dukker op når det mangler, er ikke til at forstå.