Zoho Banner September 2011

Archive for the 'Active Directory' Category

Powershell version of oidgen.vbs

For those of you planning to extend your AD DS or AD LDS schema, you will need to find a unique object identifier (OID) for each new schema class and attribute.  The process by which you can acquire the OIDs is described by Microsoft here:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms677619(v=vs.85).aspx

In summary, Microsoft suggests two methods for obtaining an OID:

1. Contact the International Standards Organisation (ISO) Name Registration Authority specific to your country; or

2. Use the oidgen.vbs script provided by Microsoft.  This method generates a random GUID and hangs it off an existing OID owned by Microsoft.

Another option not referred to by Microsoft is to contact the Internet Assigned Numbers Authority (IANA) and request a Private Enterprise Number (PEN).  The process is free an you will be able to acquire your very own root OID within 30 days of submitting a request.

Obviously, the scripted method is the quickest and simplest.  I guess the only downside is that there is a (very) remote possibility that the same OID can be generated twice.  Hidden away on the Q&A page of the oidgen.vbs script is a really nice little Powershell script that does the equivalent.  The script is written by Jiri Formacek of Microsoft and I take absolutely no credit for it. :-)

 I’ve seen a number of instances where people advise only to use the script in lab environments.  Personally, I can’t help thinking that this is being overly cautious.  Here are two examples of the OID generated by the script:

1.2.840.113556.1.8000.2554.42674.65268.53389.19984.33499.1679051.15164681

1.2.840.113556.1.8000.2554.18604.18900.32048.18847.40527.6505812.1002390

Microsoft’s root OID is shown in bold.  As you can see the remaining portion is fairly long.  I’m no mathematician, but what are the chances of the same OID being generated twice?  I guess it depends a little on the algorithm used to generated the new GUID.  Even if that scenario were to occur, what are the chances of the same schema extensions using the identical OID being used in more than one organisation? 

Your approach will depend on your attitude to risk, but if you are not a software vendor then I would think it fairly safe to use the scripted approach for your custom extensions.

ADManager Plus – Review

I’ve been having a look at the free ADManager Plus software from the team at ManageEngine. The product is designed to simplify AD management and provide useful reports. It falls under the category of “freemium” software whereby the basic offering is free, but premium features incur a licence cost. There are three variants available: Standard (free), Professional and Premium. For a comparison of the features available and pricing look here.

My initial impression of the product is that it offers quite a wide range of features, even with the free offering. The target market is likely to be small to medium size organisations that currently use the native Microsoft UI tools and fall foul of their limitations. Large organisations and those that have either developed their own AD management tools (e.g. using Powershell), or have an existing 3rd party toolset in place are unlikely to derive any significant benefit from AD Manager Plus.

The other thing that struck me immediately is that ManageEngine is really very keen for you to move away from the Standard (free) version to one that you have to pay for. This is evident from highly visible reminders all over the web-based UI and from the fact that you are only able to manage 100 user objects with the Standard version. The 100 user limitation can be quite confusing when working with domains that have a higher number of users.

admplus_1

admplus_2

admplus_3

For me, the pick of the features include:

· Easy set-up

· Intuitive user interface

· Integration of AD object and Exchange recipient management

· Customisable object provisioning templates

· Bulk object creation using CSV import

· Large number of built-in reports

It would be nice to see a fully customisable UI (e.g. similar to Quest/Dell’s ActiveRoles Server Web Interface) that allows you to display only those components and menus relevant to your role, but I’m not going to quibble too much with a free (or low cost) tool.

In summary, if you’re an admin in a small to medium-sized organisation it is definitely worthwhile having a look at this tool to make your life easier. From my perspective the free variant of the tool introduces too many limitations/annoyances, so it would be worth splashing out a few thousand (USD) for the Professional or Premium versions.

Powershell method to find when your Domain Controllers were promoted

I recently came across an old blog post by fellow MVP Joe Richards.  In the post Joe points out that whenChanged is not a replicated attribute, which makes it a poor candidate for accurately determining when an object was last modified.  He does however indicate that the whenChanged attribute provides a handy way to report when your Domain Controllers were promoted.  This is possible because the whenChanged attribute is stamped with the date and time each object is initiated on that specific DC as part of DCPROMO.  It means we can query the whenChanged attribute on, for example, any object in the default AD schema to determine the date on which that DC was promoted.  Cool, eh?  Here’s a Powershell sample using the adminDescription attribute class object in the schema partition.

$admind = "CN=Admin-Description," + (Get-ADRootDSE).schemanamingcontext
$dcs = Get-ADDomainController -Filter * | sort name
foreach ($dc in $dcs) {
    $name = $dc.name
    $wc = (Get-ADObject $admind -Server $name -Properties whenchanged).whenchanged.ToShortDateString()
    write-host "Domain Controller $name was created on $wc `n"
} # end foreach

Powershell search for Active Directory objects excluding an OU

If you’re familiar with LDAP searches you will probably at some point have been frustrated at the inability to exclude objects in a specific Organisational Unit, i.e “Give me all User objects in the domain, except those in the Sales OU”.   To workaround the problem you typically need to do some scripting. There are several methods by which you exclude objects using Powershell, but I really like the one published by fellow MVP Ilya Sazonov.

Here’s an example using Ilya’s method. In this scenario the goal is to move all Contact objects not currently in the Contacts OU to the Contacts OU. To do this we have to first find all Contacts excluding those in the Contacts OU.

$conou = "OU=Contacts,DC=mydomain,dc=com"

$exclcons = Get-ADObject -LDAPFilter "(objectclass=contact)" -SearchBase $conou `
| select -ExpandProperty distinguishedname 

$tomove = Get-ADObject -LDAPFilter "(objectclass=contact)" `
| ? {$exclcons -notcontains $_.DistinguishedName}

foreach ($con in $tomove) {
    Move-ADObject -Identity $con -TargetPath $conou -Confirm:$false
} # end foreach

Replacing legacy Domain Controller Certificates

Something you may have noticed in your journey on the road to AD enlightenment is that if you deploy a new Microsoft Enterprise Certificate Authority (CA) and publish the default templates, your Domain Controllers will automatically enroll for a certificate.  The template used is the DomainController V1 certificate, which has been around since Windows 2000 days.

cert3

But what if you wanted to assign a different certificate based on the most recent template designed for use with DCs (KerberosAuthentication)? Easy, you would think, given that the DCs have this in-built autoenrollment capability. All I would need to do is unpublish the old DomainController template, publish the new KerberosAuthentication template, ensure that DCs have autoenroll permissions on the template and then perform a Certutil –pulse command on the DCs. Right? Wrong. It’s actually not that straightforward. From what I have managed to infer (no one will provide me with a definitive answer) it seems the in-built auto-enrollment feature of Domain Controllers is tied specifically to the legacy DomainController template. In other words it will only work with the DomainController template and no other.

The only way I can get the DCs to successfully autoenroll for a certificate based on the KerberosAuthentication template is to follow the steps shown below.

1. Ensure the Domain Controllers group has permissions on the KerberosAuthentication template (it has by default).

cert4

2. Modify the properties of the KerberosAuthentication template to add the DomainController, DirectoryEmailReplication and DomainControllerAuthentication templates to the list of superseded templates

cert5

3. Publish the KerberosAuthentication template

4. Modify a GPO linked to the Domain Controllers OU to enable the “Certificate Services Client – Auto-Enrollment setting as shown below.

cert1

cert2

5. Wait for policy to apply to the DCs (or run gpupdate /force).

6. Run certutil –pulse from an elevate CMD prompt to force re-enrollment.

7. Confirm that a new certificate has been issued based on the KerberosAuthentication template and that the old certificate based on the DomainController template has been automatically removed.

The directory service can perform the requested operation only on a leaf object

If you come across this error when using Powershell to delete an object, it is most likely because the object has child objects associated with it.  The most obvious example is computer objects that have print queue, service connection point, RRAS or various other types of child objects.  The workaround is to determine the child object (to see if it might be required) and then to delete the objects recursively as shown below.

In this example we have a computer object named “Foo”.  If we try and delete it using the Powershell AD cmdlet Remove-ADComputer we see the “leaf object: error.

leaf1

We can then use some other Powershell goodness to determine the type of child object that we have.  In this case a service connection point object.

leaf2

Once we’re happy that deleting the child object won’t cause any other issues, we can use the Remove-ADObject cmdlet together with the –Recursive switch to delete both the computer and the service connection point objects.

leaf3

Powershell: Using the whenCreated attribute in LDAP Filters

It is sometimes helpful to be able to search for objects in AD by their creation date.  The whenCreated attribute is useful for this as it is a replicated attribute (i.e. is consistent across all DCs).  The challenge for using whenCreated in LDAP filters is the syntax.  The attribute uses the GeneralizedTime syntax to represent the date and time (see X.680 for more details regarding the syntax).  I haven’t found an standard method within Powershell to obtain GenerlizedTime format, so it involves some custom formatting. 

Here’s an example of using whenCreated in a LDAP filter to find all user objects created in the past 90 days. 

$wcdate = "{0:yyyMMddHHmmss}.Z" -f (Get-Date).adddays(-90) 

Get-ADUser -LDAPFilter "(whencreated>=$wcdate)" -pr * | fl samaccountname, whencreated

Wellington Windows Infrastructure User Group

After an absence of a couple of years, the Wellington Windows Infrastructure User Group has been brought back to life!  If you’re in Wellington on Wednesday 4th July, come along and watch me and Daniel Bowbyes presenting on some Windows Server 2012 goodness.

http://www.mscommunities.co.nz/Events/Wellington-Windows-Infrastructure-User-Group—Win.aspx

Using the AD Powershell cmdlets to find inactive accounts

For a number of years now I have been using OldCmp  to find and remove inactive user and computer accounts.  The other day I thought I would have a crack at using the AD Powershell cmdlets to at least do the finding part.  It wasn’t as difficult as I thought.  Here’s an example looking for enabled accounts that have been inactive for 90 days or more:

# Find inactive user accounts

$now = Get-Date
$old = $now.AddDays(-90)
Get-ADUser -Filter * -Properties lastlogondate `
| ? {($_.enabled -eq $true) -and ($_.lastlogondate -le $old)} `
| select samaccountname, lastlogondate `
| Export-Csv .\inactive_users.csv -NoTypeInformation

# Find inactive computer accounts

$now = Get-Date
$old = $now.AddDays(-90)
Get-ADComputer -Filter * -Properties lastlogondate `
| ? {($_.enabled -eq $true) -and ($_.lastlogondate -le $old)} `
| select name, lastlogondate `
| Export-Csv .\inactive_computers.csv -NoTypeInformation

I normally use LDAP filters for all searches, but in this case I used a standard Powershell filter.  Why? Well, because the cmdlets expose two pseudo attributes: “enabled” and “lastlogondate”.  I call these pseudo attributes because you won’t find them anywhere in the AD schema.  They are provided to make life easier.   The alternative would be to query userAccountControl with a bitwise filter  to find the enabled/disabled state and to do some formatting with lastLogonTimestamp, which is stored in AD as a large integer value.

I hope you find these useful.

Powershell script to move FSMO roles

I’ve had the script shown below for quite a while, but as I recently tested it successfully against Windows Server 2012 AD (Release Candidate), I thought I would share it with the community.

Note that I have only tested it with single domain forests.

Import-Module activedirectory

[string] $menu = @'

    Active Directory FSMO Role Holder mover script
    Please select an option from the list below

    1) Move all roles
    2) Move the Schema Master (forest)
    3) Move the Domain Master (forest)
    4) Move the Infrastructure Master (current domain)
    5) Move the PDC Emulator (current domain)
    6) Move the RID Master (current domain)

Select an option.. [1-6]?
'@

Write-host "Last command: " $opt -foregroundcolor Blue
$opt = Read-Host $menu
$target = Read-Host "Target DC for the role(s)?"

switch ($opt)    {
    1 { Move-ADDirectoryServerOperationMasterRole $target DomainNamingMaster, SchemaMaster, PDCEmulator, InfrastructureMaster, RIDMaster -confirm:$false }
    2 { Move-ADDirectoryServerOperationMasterRole $target SchemaMaster -confirm:$false }
    3 { Move-ADDirectoryServerOperationMasterRole $target DomainNamingMaster -confirm:$false }
    4 { Move-ADDirectoryServerOperationMasterRole $target InfrastructureMaster -confirm:$false }
    5 { Move-ADDirectoryServerOperationMasterRole $target PDCEmulator -confirm:$false }
    6 { Move-ADDirectoryServerOperationMasterRole $target RIDMaster -confirm:$false }
    default { write-host "You haven't selected any of the available options."; exit }
} # End switch loop

Next Page »