Identify writeable AD attributes with PowerShell

You should be able to retrieve easily the list of attributes which are writeable by using the constructed attribute allowedAttributesEffective (http://msdn.microsoft.com/en-us/library/ms675218(v=vs.85).aspx).

{codecitation style= »brush: PowerShell »}

$ADObject = New-Object system.DirectoryServices.DirectoryEntry (« LDAP://CN=alexandre augagneur,CN=Users,DC=corpnet,DC=net »)

$ADObject.RefreshCache(« allowedAttributesEffective »)

$ADObject.properties.allowedAttributesEffective

{/codecitation}

However, the constructed attribute returns some attributes which can’t be changed… So we have to do something more.

The best way I found is to retrieve all attributes which are protected by the system (http://msdn.microsoft.com/en-us/library/ms680025(v=vs.85).aspx). When it’s done, i’m just removing each of them from the list of allowed attributes returned by the constructed attribute allowedAttributesEffective.

{codecitation style= »brush: PowerShell »}

$SystemOnlyAttributes = @()

$TrulyAllowedAttributes = @()

 

 

# Get the desired object based on its distinguishedName

$ADObject = New-Object system.DirectoryServices.DirectoryEntry (« LDAP://CN=alexandre augagneur,CN=Users,DC=corpnet,DC=net »)

 

# Retrieve the constructed attribute ‘allowedAttributesEffective’

$ADObject.RefreshCache(« allowedAttributesEffective »)

 

# Store the list of allowed attributes  in a variable

$allowedAttributesEffective = $ADObject.properties.allowedAttributesEffective

 

# Retrieve the list of attributes in the schema which are protected

$ObjRootDSE = [ADSI] « LDAP://RootDSE »

$ADSearcher = new-object system.DirectoryServices.DirectorySearcher

$ADSearcher.SearchRoot = [ADSI] « LDAP://$($ObjRootDSE.schemaNamingContext) »

$ADSearcher.PropertiesToLoad.AddRange(@(« ldapdisplayname », »systemonly »))

$ADSearcher.Filter = « (systemonly=TRUE) »

$ADSearcher.FindAll() | %{ $SystemOnlyAttributes += $_.Properties.ldapdisplayname }

 

# Compare the list of allowed attributes returned by the constructed attribute

# with the list of protected attributes collected in the schema

foreach ( $Attribute in $allowedAttributesEffective )

{

if ( $SystemOnlyAttributes -notcontains $Attribute )

{

$TrulyAllowedAttributes += $Attribute

}

}

# The most efficient list of writeable attributes

$TrulyAllowedAttributes

{/codecitation}

 

If you have a better way… you are welcome !

Gérer efficacement la création des snapshots AD

Sommaire

 

 

Introduction

Les clichés instantanés de la base NTDS est une fonctionnalité Windows Server s’appuyant sur NTDSUTIL (un simple front end du VSS shadow copy en réalité) et l’outil DSAMAIN. Le premier permet la création de clichés instantanés du fichier « ntds.dit », le deuxième permet d’instancier la base de données depuis un des clichés réalisés.

J’avais d’ailleurs déjà traité le sujet il y a quelques temps au sein de deux articles :

 

Depuis lors, j’ai gagné un petit peu en expérience et je vais vous montrer comme optimiser la création de vos clichés Active Directory.

 

 

Les problématiques

La première grosse contrainte lorsque vous créer vos clichés instantanés à l’aide de NTDSUTIL est qu’il crée automatiquement un cliché instantané de l’ensemble de vos volumes. D’une part ça ne sert strictement à rien, d’autre part ça peut poser rapidement des problèmes sur la gestion des rotations de vos clichés ainsi que des problèmes d’espace disque.  Cela s’avère d’autant plus vrai lorsque le volume système est impacté…

Ci-dessous, vous voyez un exemple de création d’un cliché à l’aide de NTDSUTIL. Comme je dispose de deux volumes (C:\ et D:\), l’outil prend un cliché de chacun d’entre eux…

 

Le deuxième problème est la gestion des rotations… en effet, on pourrait essayer de fixer un nombre de clichés instantanés cependant cela peut s’avérer rapidement complexe car il faut tenir compte de l’évolution de l’espace disque utilisé sur la partition de votre base Active Directory mais également les autres volumes depuis que NTDSUTIL ne fait pas la différence.

 

 

Problématique 1 : réaliser un cliché d’un seul volume

La première chose à faire est de limiter la réalisation du cliché au seul volume contenant la base Active Directory. Cela induit donc de ne plus utiliser NTDSUTIL. Ça ne pose pas réellement de problème en réalité car les clichés instantanés réalisés par NTDSUTIL n’ont rien de plus que ceux réalisés depuis l’explorateur Windows. La seule chose que réalise NTDSUTIL et qu’il ajoute un TAG supplémentaire pour des besoins de gestion. En effet, lorsque vous utilisez NTDSUTIL pour lister, monter ou supprimer les clichés instantanés Active Directory, il s’appuie sur le TAG « SNAPAD » apposé sur chaque cliché instantané.

La solution que je propose est donc de passer par l’outil DISKSHADOW pour réaliser le cliché instantané qui permet premièrement de se focaliser uniquement sur le volume hébergeant la base NTDS. En second, il permet de continuer de gérer les clichés instantanés depuis NTDSUTIL.

Le script est disponible depuis le lien suivant : http://gallery.technet.microsoft.com/scriptcenter/Script-to-create-Active-2d389218

Ci-dessous, je lance le script pour réaliser un cliché et je liste le cliché créée à l’aide de NTDSUTIL. Nous voyons bien que non seulement il apparait bien depuis NTDSUTIL mais surtout que seul le volume stockant la base Active Directory est concerné.

 

 

Problématique 2 : gestion efficace de la rotation de vos clichés instantanés

Evaluer la taille d’un cliché est quasiment impossible surtout si vous en réalisez plusieurs à la suite. Vous pourriez y arriver au fur à mesure avec un peu de patience et une surveillance soutenue mais ça reste assez inefficace.

Le mieux est de s’appuyer sur ce que Microsoft propose déjà en matière de clichés instantanés. En effet, vous avez la possibilité de réserver un espace dédié à vos clichés et du coup de gérer de manière optimisée le nombre de clichés que vous pouvez conserver.

Pour cela, rien de plus simple. Faites un clic droit sur le volume contenant la base Active Directory et sélectionnez « Configurer les clichés instantanés… ».

 

Depuis la fenêtre « Clichés instantanés », cliquez sur le bouton « Paramètres… ». Une fois dans la fenêtre « Paramètres », définissez une limite pour le stockage des clichés instantanés à l’aide de l’option « Utiliser cette limite : ».

 

De manière automatique, Windows va désormais gérer la rotation tout en garantissant de ne pas dépasser un volume d’espace disque. En clair, lorsque la limite définie sera dépassée, le plus ancien cliché sera supprimé et ainsi de suite.

Identifier les groupes de l’utilisateur courant avec PowerShell

Je vais vous montrer rapidement comment vérifier qu’un utilisateur appartient à un groupe en PowerShell. Cela vous sera sans doute utile pour la mise en place de login script en PowerShell et abandonner les .bat, .kix et tutti quanti.

Premièrement on récupère l’utilisateur Windows courant :

{codecitation style= »brush: PowerShell »}

$CurrentWinId = [System.Security.Principal.WindowsIdentity]::GetCurrent()

{/codecitation}

 

L’objet WindowsIndentity contient la propriété « Groups » listant l’ensemble des appartenances de l’utilisateur. Par contre,  la liste retourne uniquement les groupes par leur SID.

 

Du coup, vous avez deux solutions. La première solution consiste à réaliser une translation SID/Nom à l’aide de la méthode Translate et de stocker le résultat dans un tableau.

{codecitation style= »brush: PowerShell »}

$arrTranslatedGroups = @()

Foreach ($Group in $CurrentWinId.Groups)

{

$arrTranslatedGroups += $Group.translate([System.type]::GetType(« System.Security.Principal.NTAccount »)).Value

}

{/codecitation}

 

Il suffit de vérifier si un groupe est présent à partir du tableau généré à l’aide de l’opérateur « -contains » qui retournera « True » ou « False » :

{codecitation style= »brush: PowerShell »}

$arrTranslatedGroups -contains « NT AUTHORITY\Authenticated Users »

{/codecitation}

 

La deuxième solution consiste a converti dans un premier temps notre objet WindowsIdentity en WindowsPrincipal.

{codecitation style= »brush: PowerShell »}

$CurrentWindowsPrincipal = new-object System.Security.Principal.WindowsPrincipal($CurrentWinId)

{/codecitation}

 

L’objectif étant de pouvoir utiliser la méthode « IsInRole ».

{codecitation style= »brush: PowerShell »}

$CurrentWindowsPrincipal.IsInRole(« CORPNET\group123 »)

$CurrentWindowsPrincipal.IsInRole(« NT AUTHORITY\Authenticated Users »)

{/codecitation}