PowerShell for Windows Admins

February 11, 2012  5:09 AM

Tools for administering Active Directory

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

It was pointed out in a comment that in my series of posts on administering Active Directory (started with http://msmvps.com/blogs/richardsiddaway/archive/2012/01/03/get-ad-users-in-an-ou-tree.aspx and the posts coming forward)

I hadn’t actually discussed the tools I was using in the posts – in the spirit of better now then never I’ll put that right.

There are two areas of Active Directory administration we should think about:

  • Data – users, groups, OUs, computers (possibly plus domains and forests)
  • Service – sites, subnets, site links, replication, schema

Up to now I have concentrated on the data – mainly user administration. I will expand to other areas as we proceed.

Any one who has spent any time administering AD soon becomes familiar with AD Users and Computers and the associated tools. These are great for doing the odd ad hoc job but for bulk investigation or processing we need scripts. In years gone by this would have been VBScript but the world has moved on and PowerShell is the scripting tool of choice for the savvy Windows administrator.

If you need to get started with PowerShell look a the books available at www.manning.com. PowerShell in a month of lunches is a great starter. PowerShell in Practice and PowerShell and WMI will extend that knowledge to actually using PowerShell in the real world.

Now that we’ve decided PowerShell is our admin tool of choice – how do we work with AD. The starting point is that there are no AD admin cmdlets built into PowerShell v2 (or v3 for that matter). However, we do have access to a number of tools that we can use through PowerShell.

The Quest AD cmdlets have been available for a number of years. First issued in 2007  they are a free download in 32 and 64 bit versions from http://www.quest.com/powershell/activeroles-server.aspx. A pdf manual is also available.  They install as a snapin on your workstation.

These cmdlets have a good coverage of AD data administration and also include PKI and Quest’s Active Roles administration.  They have a  number of advantages – especially the fact that you don’t have to install anything on your domain controllers and that they work with AD versions from Windows 2003 to Windows 2008 R2 out of the box. The main draw back is that they are non-Microsoft which is a big negative in some organisations.

Microsoft introduced a set of cmdlets for administering AD and a provider with Windows 2008 R2. If your domain controllers are running an earlier version of WIndows you can download versions of the cmdlets for Windows 2003 and Windows 2008 from the links provided at ttp://blogs.msdn.com/b/adpowershell/archive/2009/09/18/active-directory-management-gateway-service-released-to-web-manage-your-windows-2003-2008-dcs-using-ad-powershell.aspx.

The Microsoft cmdlets work through a web service that runs on the domain controllers. This is installed by default on Windows 2008 R2 but needs a specific install for older versions. I find this a drawback for legacy versions as I like to keep my domain controllers as clean as possible.  If your domain is Windows 2008 R2 then install the RSAT tools on your workstation and you will get the AD cmdlets and provider.

Having looked at the Microsoft provider in a fair amount of detail recently I have to admit that it is better than I thought. I don’t like the navigational requirement to use ou = xxx  to determine path but it is liveable with especially in scripts.

Scripting has a venerable tradition for AD administration. In PowerShell we use the [adsi] type accelerator which is a shortcut to System.DirectoryServices.DirectoryEntry. The class is a wrapper for standard ADSI access to AD. ADSI is COM based to add another level of complexity.  All of these wrappers modify the  objects returned to a greater or lesser extent. This can create some confusion as the methods you are used to from VBScript are available but not visible. You need to know how to use these objects to get the most from them – which is where the posts come in.

Searching AD in VBScript was painful but in PowerShell we get [adsisearcher] which is a type accelerator for System.DirectoryServices.DirectorySearcher. We have seen this in a number of posts – and will see it in the future.

Also available in the .NET fold for access through scripts is the System.DirectoryServices.ActiveDirectory namespace. This provides access to a number of classes that make it easier to deal with the service side – sites etc as we will see later.  The latest addition with .NET 3.5 (needed for ISE and out-gridview) is System.DirectoryServices.AccountManagement. This namespace provides access to users and groups. The syntax is more complex but it supplies easy access to a number of pieces of functionality that we can’t do using other .NET classes.

Finally the System.DirectoryServices.Protocols supplies access to some deep level aspects of AD – for instance we can use it to return an object from being tombstoned. This namespace is not well documented and is not easy to decipher its usage.


I still turn to the Quest cmdlets – I’ve been using them since I was involved with the original beta testing. if you have Windows 2008 R2 you have the Microsoft cmdlets which provide analogous functionality. I would recommend using one (or better still both) sets of cmdlets. Use scripting to fill in the gaps and leave the provider alone except for specific jobs – it is very good for bulk creation of OUs!



I have been asked if I will be pulling all of the code I’m publishing on AD into a book.  I hadn’t thought about it up to now.  Is there enough interest for such a book?

February 9, 2012  1:48 PM

February PowerShell group meeting–SQL server and PowerShell

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

When: Tuesday, Feb 28, 2012 7:30 PM (GMT)

Where: Virtual


SQL Server forms the core of many of our systems – how can we administer and access it using PowerShell


Richard Siddaway has invited you to attend an online meeting using Live Meeting.
Join the meeting.
Audio Information
Computer Audio
To use computer audio, you need speakers and microphone, or a headset.
First Time Users:
To save time before the meeting, check your system to make sure it is ready to use Microsoft Office Live Meeting.
Unable to join the meeting? Follow these steps:

  1. Copy this address and paste it into your web browser:
  2. Copy and paste the required information:
    Meeting ID: B4N68M
    Entry Code: 38-s+N7W4
    Location: https://www.livemeeting.com/cc/usergroups

If you still cannot enter the meeting, contact support

Microsoft Office Live Meeting can be used to record meetings. By participating in this meeting, you agree that your communications may be monitored or recorded at any time during the meeting.

February 6, 2012  6:28 AM

Inbound replication

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Continuing round the MicrosoftActiveDirectory namespace we get to the MSAD_ReplCursor class which provides inbound replication state information about all replicas of a Naming Context


Get-WmiObject -Namespace root\MicrosoftActiveDirectory -Class MSAD_ReplCursor  |
Format-Table -GroupBy NamingContextDN -Property SourceDsaDN, SourceDsaInvocationID,
@{N="LastSuccessfulSync"; E={$_.ConvertToDateTime($_.TimeOfLastSuccessfulSync)}}, USNAttributeFilter –AutoSize

The interesting properties are the TimeofLastSuccessfulSync and the USNAttributeFilter.  The latter – to quote from the documentation  “gets the maximum update sequence number to which the destination server can indicate that it has recorded all changes originated by the given server at update sequence numbers less than, or equal to, this update sequence number. This property is used to filter changes that the destination server has already applied at replication source servers”.


Between the WMI classes we have the basis of a good test of replication  for our AD domain.  All we have to do is put it together in a coherent picture.

February 6, 2012  5:00 AM

Automating replication testing

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Building on the recent post about testing replication I though a bit more automation was needed. Lets create a function to discover the domain controllers

function get-DomainControllerNames {            
 $dom = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()             
 $dom.FindAllDomainControllers() | select -ExpandProperty Name            


We then use a simple pipeline to produce a nicely formatted report


get-DomainControllerNames |

foreach { test-replication -computername $_ } |

Format-Table -Property SourceDsACN, NamingContextDN, Last* -GroupBy DomainController –AutoSize 


   DomainController: DC02.Manticore.org

SourceDsaCN NamingContextDN                                LastSyncAttempt     LastSyncSuccess   
———– —————                                —————     —————   
SERVER02    DC=Manticore,DC=org                            06/02/2012 10:53:45 06/02/2012 10:53:45

SERVER02    CN=Configuration,DC=Manticore,DC=org           06/02/2012 10:01:46 06/02/2012 10:01:46

SERVER02    CN=Schema,CN=Configuration,DC=Manticore,DC=org 06/02/2012 10:01:46 06/02/2012 10:01:46

SERVER02    DC=DomainDnsZones,DC=Manticore,DC=org          06/02/2012 10:22:17 06/02/2012 10:22:17

SERVER02    DC=ForestDnsZones,DC=Manticore,DC=org          06/02/2012 10:07:02 06/02/2012 10:07:02

   DomainController: SERVER02.Manticore.org

SourceDsaCN NamingContextDN                                LastSyncAttempt     LastSyncSuccess   
———– —————                                —————     —————   
DC02        DC=Manticore,DC=org                            06/02/2012 10:03:17 06/02/2012 10:03:17

DC02        CN=Configuration,DC=Manticore,DC=org           06/02/2012 10:02:01 06/02/2012 10:02:01

DC02        CN=Schema,CN=Configuration,DC=Manticore,DC=org 06/02/2012 09:59:38 05/02/2012 19:48:03

DC02        DC=ForestDnsZones,DC=Manticore,DC=org          06/02/2012 10:07:17 06/02/2012 10:07:17

DC02        DC=DomainDnsZones,DC=Manticore,DC=org          06/02/2012 10:22:00 06/02/2012 10:22:00


If you have a very large number of domain controllers this may take a while to run. In that case split the domain controller list into a number of CSV files and work from those.

February 5, 2012  3:22 PM

Passing no parameters

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

This was interesting question on the forum – user wants to retrieve something by name or id and if neither are given then return all objects.  This is similar to

Get-Process powershell
Get-Process -Id 1568

In the first two we filter on a name or id – in the last one we get everything


This is what I arrived at using processes as an example

function test-proc{             
param (             
switch ($psCmdlet.ParameterSetName) {            
 "ByName"  {Get-Process -Name $name }            
 "ById"  {Get-Process -Id $id }            
 "XXXXX" {Get-Process }            

The trick is to define a default parameter set with no parameters – then when you don’t use any parameters it kicks in at the switch statement and your code can run as required

Be interested if this gets broken in any scenarios as it seems to simple to be correct – but it works

February 5, 2012  2:06 PM

Testing replication

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

We’ve seen a few things we can do with the WMI provider for Active Directory. One of the most useful is testing replication

function test-replication{            
Get-WmiObject -Namespace root\MicrosoftActiveDirectory -Class MSAD_ReplNeighbor -ComputerName $computername|            
select SourceDsaCN, NamingContextDN,             
@{N="LastSyncAttempt"; E={$_.ConvertToDateTime($_.TimeOfLastSyncAttempt)}},            
@{N="LastSyncSuccess"; E={$_.ConvertToDateTime($_.TimeOfLastSyncSuccess)}}             

A simple call to the MSAD_ReplNeigbor and we can test the last times the DCs attempted to synchronise and the last time they were successful

February 5, 2012  6:40 AM

PAM release February 2012

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I have added another module to the PowerShell Admin Modules – http://psam.codeplex.com/


Release 0.7 adds a PAMHostsFile module with the following members



A release notes document is also available which includes a listing of all modules and members together with a history of releases.

February 5, 2012  3:59 AM

Training for the Scripting Games

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Like all sporting events you need to train before participating – as part of your training follow the links on the sites in my previous post


and also use these resources


Good luck

February 4, 2012  9:31 AM

Scripting Games 2012–link page

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

The 2012 Scripting Games were announced


They will start on 2 April – with events released to schedule after that. The usual Advanced and Beginner categories will be available

An all links page is available


This is worth book marking.

If you didn’t compete last year – follow the links to see the type of fun that is in store.

Last year there were some amazing PowerShell scripts submitted – looking forward to this years games already.

And just to add to the fun – this year you can use PowerShell v3

January 28, 2012  2:51 PM

Naming Contexts

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Continuing our quick look at The ActiveDirectory name space lets have a look at the MSAD_NamingContext  class

Get-WmiObject -Namespace root\MicrosoftActiveDirectory -Class MSAD_NamingContext |

Format-Table DistinguishedName, IsFullReplica –AutoSize


DistinguishedName                              IsFullReplica
—————–                              ————-
DC=DomainDnsZones,DC=Manticore,DC=org                   True
DC=ForestDnsZones,DC=Manticore,DC=org                   True
CN=Schema,CN=Configuration,DC=Manticore,DC=org          True
CN=Configuration,DC=Manticore,DC=org                    True
DC=Manticore,DC=org                                     True


This is equivalent to the information you see in the root of the AD provider

PS> Get-ChildItem -Path AD:\

Name                 ObjectClass          DistinguishedName
—-                 ———–          —————–
Manticore            domainDNS            DC=Manticore,DC=org
Configuration        configuration        CN=Configuration,DC=Manticore,DC=org
Schema               dMD                  CN=Schema,CN=Configuration,DC=Manticore,DC=org
ForestDnsZones       domainDNS            DC=ForestDnsZones,DC=Manticore,DC=org
DomainDnsZones       domainDNS            DC=DomainDnsZones,DC=Manticore,DC=org

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: