Archive for the ‘Active Directory’ Category

Powershell: Update Active Directory Permissions

September 1, 2009

If you’re new to manipulating Active Directory in Powershell and you want to answer a question like ‘How do I give domain user prod\bruce write access to AD object LDAP://adserver.prod.com/cn=MegaServer, cn=Computers, cn=prod, cn=net’, then this brilliant article by Richard Siddaway ‘Windows Server 2008 Protection from Accidental Deletion’ is just what you need.

I’m just linking it here because its title makes it a bit difficult to find and it deserves more exposure.

Here’s the guts of it

$ou = [ADSI]"LDAP://ou=Thunderbirds,dc=starking,dc=org"

$sec = $ou.psbase.ObjectSecurity

## set the rights and control type

$act = [System.Security.AccessControl.AccessControlType]::Deny

$adrights = [System.DirectoryServices.ActiveDirectoryRights]::Delete

$adrights2 = [System.DirectoryServices.ActiveDirectoryRights]::DeleteTree

## who does this apply to

$who = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList "", "prod\bruce"

# stop delete

$newrule1 = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $who, $adrights, $act

$sec.AddAccessRule($newrule1)

$ou.psbase.CommitChanges()

# stop deletetree

$newrule2 = New-Object -TypeName System.DirectoryServices.ActiveDirectoryAccessRule -ArgumentList $who, $adrights2, $act

$sec.AddAccessRule($newrule2)

$ou.psbase.CommitChanges()

Advertisements

Powershell: Updating a MultiValued Active Directory Property

August 30, 2009

This one took me a little big of digging around for because the typical scenario for updating a multi-valued AD property is that a SysAdmin is adding a new email address to a list of email addresses in some property i.e. an Append Operation.

Whereas, what I wanted to do was overwrite one of the values in a multivalued property with an updated value i.e. an Update operation.

First thing you need to know is to use PutEx instead of Put when updating Multi-valued properties. Most simple examples on the Greater Google are about updating single-valued properties – integers or strings or whatever. These are updated using Put. MultiValued properties use PutEx.

Second thing is that you need to use the methods for the correct AD Provider and not to mix them up. Where you are using PutEx, then you commit that change to the actual AD database server using SetInfo() instead of CommitChanges(). I’ll get some more detail on that in here before long.

Next thing you need to realise is that the type of a MultiValued AD property in .NET is PropertyValueCollection, but that the PutEx method takes an Array Of Object (i.e. Object[]) as its parameter. You have to convert from PropertyValueCollection to Array. Fortunately that’s easy.

Finally, and obviously, you need to make sure that the account you are using to bind to Active Directory has Write Privileges to the entry you’re trying to update, otherwise you will get AD’s equivalent of the Blue Screen Of Death, ‘General Access Denied Error’.

To get started, here’s a great page on updating a MuliValued AD property with an Append from The Scripting Guy on TechNet. Digest this and you’ll know most of what you need to know.

Now, here’s how I did my Update operation on the Multivalued property. Probably the code is a bit clunky but it works and we can refine it a bit later. Hopefully the comments in the code provide enough explanation.

The objective is to search for the key ‘Fruit’ in the MultiValued property ‘keywords’ and update its value from ‘Banana’ to ‘Kumquat’

# The account Place\myaccount must have write privs to the LDAP Path specified.
$entry = new-object DirectoryServices.DirectoryEntry (“LDAP://MyLDAPServer/dc=place, dc=room, dc=net”, “place\myaccount”, “mypassword”)
$keywords = $entry.Keywords
# Convert keywords propertyValueCollection to a fixed-length array
# because the DirectoryEntry update function takes an Array, not
# a PropertyValueCollection as a parameter
$length = $keywords.Count
[Array]$keywordsArray = 1..$length
# This CopyTo moves the propertyValueCollection to an array.
$entry.Keywords.CopyTo($keywordsArray, 0)

# Search for ‘Fruit’ entry in keywords
$foundKey = $false
for($i=0; $i -lt $keywordsArray.Length; $i++)
{
$keyword = $keywordsArray[$i]
Write-Debug “$keyword”
if ($keywordsArray[$i].ToLower().Contains(“fruit”))
{
$foundKey = $true
# Retain index of Fruit property so it can be updated below
$fruitIdx = $i
break
}
}

#Check if we found Fruit Entry
if ($foundFruit -eq $false)
{
throw (“Did not find Fruit keyword in Active Directory object”)
}

# Extract Fruit Value from KeywordValue pair
# Fruit entry is “Fruit:
$fruitParts = $keyword.Split(“:”)
Write-Debug “Fruit is $fruitParts[1]”

# Change “Fruit” key. Update the value to ‘Kumquat’
$newFruitEntry = $fruitParts[0] + “Kumquat”
Write-Debug “Updated keyword entry is $newFruitEntry”
$keywordsArray[$FruitIdx] = $newFruitKey

# Update DirectoryEntry
# PutEx, instead of Put required for multivalued AD entries such as keyword
# First parameter denotes type of PutEx i.e. Append, Update or Delete In our case its an Update.
$ADS_PROPERTY_UPDATE = 2
$entry.PutEx($ADS_PROPERTY_UPDATE, “Keywords”, $keywordsArray)
Write-Debug “committing AD Change…”
# Commit to AD database on server
$entry.SetInfo()
Write-Debug “committed”