Archive for October, 2010

Today I’m going to show an example of a quick script to create Organisational Units (OU). I wrote this script over a year ago when I needed to create an OU structure for a hosted Active Directory (AD) domain and it was successfully used to create thousands of OUs. I have chosen to use the Quest tools because this domain is 2008 and I didn’t have the option of using Microsoft’s new AD cmdlets.

The required structure was the following:

\---<Site Code>
 |   +---Resource Groups
 |   |   +---Printers
 |   |   \---Shares
 |   \---User Groups

This particular hosted AD was going to be used by a large number of Schools. As above, the variable “Site Code” of each school will used as the name for the parent OU and each OU will have the “School Name” added as the description. I first created a CSV file with the necessary data, an example:

Site Code School Name
AFCPS Alford Primary School
ALLIN Allington and Sedgebrook CE Primary
AMTOF Amber Hill Toftstead Primary School
ANCAS Ancaster CE Primary School
BASSI Bassingham Primary School
BBCPS Brant Broughton CE and Methodist Primary School
BDJOI Bardney CE and Methodist Primary School
BKNAL Bucknall Primary School
BLYTO Blyton Cum Laughton CE Primary School
BMBER Baumber Primary School

I first need to load the above CSV files into a variable for easy access:

$DomainLookup = Import-Csv C:\Scripts\DomainLookup.csv

As I planned to only create half the OUs in the CSV file and I wanted the flexibility to create OUs ad-hoc I decided it would be best to make a scripted function that accepted data from the pipeline , here’s is the code:

function New-SchoolsOUs{


	$SchoolOU = ''
	New-QADObject -Type OrganizationalUnit -ParentContainer $SchoolOU -Name $_."Site Code" -Description $_."School Name" -OutVariable Parent
	New-QADObject -Type OrganizationalUnit -ParentContainer $Parent[0].dn -Name 'Groups' -Description $_."School Name" -OutVariable Groups
	New-QADObject -Type OrganizationalUnit -ParentContainer $Groups[0].dn -Name 'Resource Groups' -Description $_."School Name" -OutVariable ResourceGroups
	New-QADObject -Type OrganizationalUnit -ParentContainer $ResourceGroups[0].dn -Name 'Printers' -Description $_."School Name"
	New-QADObject -Type OrganizationalUnit -ParentContainer $ResourceGroups[0].dn -Name 'Shares' -Description $_."School Name"
	New-QADObject -Type OrganizationalUnit -ParentContainer $Groups[0].dn -Name 'User Groups' -Description $_."School Name"
	New-QADObject -Type OrganizationalUnit -ParentContainer $Parent[0].dn -Name 'LFTs' -Description $_."School Name"
	New-QADObject -Type OrganizationalUnit -ParentContainer $Parent[0].dn -Name 'Users' -Description $_."School Name" -OutVariable UsersOU
	New-QADObject -Type OrganizationalUnit -ParentContainer $UsersOU[0].dn -Name 'Pupils' -Description $_."School Name"
	New-QADObject -Type OrganizationalUnit -ParentContainer $UsersOU[0].dn -Name 'AdminStaff' -Description $_."School Name"
	New-QADObject -Type OrganizationalUnit -ParentContainer $UsersOU[0].dn -Name 'Staff' -Description $_."School Name"
	New-QADObject -Type OrganizationalUnit -ParentContainer $Parent[0].dn -Name 'Computers' -Description $_."School Name"
END {}


This allows me the flexibility to for example create the first 5 Schools:

$DomainLookup[0..4] | New-SchoolsOUs

Or if needed Schools by name:

$DomainLookup | ? { $_.’Site Code’ -eq ‘BKNAL’ } | New-SchoolsOUs

Now I understand that the above function is quite specific for this task but I’m sure if you are in a similar situation you can edit it as you see fit.

The objective of this post is to provide instruction on enabling PowerShell 2.0 remoting capabilities in non 2008 R2 domains. In this example I will demonstrate in a 2003 domain environment.


To complete this work instruction you will need the following:

1.     PowerShell version 2.0 will need to be installed on all systems that will be used for remoting. On down level clients PowerShell 2.0 is bundled into the Windows Management Framework.

The Windows Management Framework makes some updated management functionality of Windows 7 and Windows Server 2008 R2 available on Windows XP, Windows Server 2003, Windows Vista, and Windows Server 2008.

Windows Management Framework contains the following three components:

  • Windows Remote Management (WinRM) 2.0
  • Windows PowerShell 2.0
  • Background Intelligent Transfer Service (BITS) 4.0.

I recommend that WSUS is used as the deployment method for the Windows Management Framework on down level clients and it will be assumed from this point that this is already installed as this was released some time ago.

2.     The ‘Windowsremotemanagement.adm’ file will need to be imported into the GPO later in the process. This will need to be downloaded as part of the ‘WS-Management v1.1 Package’ at the following link . Once downloaded install onto the system you will be using to create and edit GPO’s.

Create the Group Policy Object (GPO)

Launch the Group Policy Management (GPMC) and create a new GPO titled ‘Windows Remote Management’.

Edit the newly created GPO and add both the ‘Windowsremoteshell.adm’ and ‘Windowsremotemanagement.adm’ Templates, if either of the adm files cannot be found please ensure that the ‘WS-Management Package’ is downloaded and installed as advised in the prerequisites.

Now Expand trough the Computer Configuration policy structure to ‘Administrative Templates > Windows Components > Windows Remote Management (WinRM) > WinRM Service’ and select ‘Allow automatic configuration of listeners’

This policy setting allows you to manage whether the Windows Remote Management (WinRM) service automatically starts and listens on the network for requests on HTTP over port 5985 and if enabled HTTPS on 5986.

Note: The above ports are correct as of WinRM 2.0. The previous version WinRM 1.1 used the default HTTP and HTTPS ports 80 and 443 respectively, the documentation on TechNet and also on the help section for this GPO have not been updated to reflect this at the time of writing.

Enable the GPO and complete the IPv* filters text boxes, an example of a relaxed configuration can be seen in Figure 1

Figure 1

The service listens on the addresses specified by the IPv4 and IPv6 filters. IPv4 filter specifies one or more ranges of IPv4 addresses and IPv6 filter specifies one or more ranges of IPv6addresses. If specified, the service enumerates the available IP addresses on the computer and uses only addresses that fall within one of the filter ranges.

You can use asterisk (*) to indicate that the service listens on all available IP addresses on the computer. When * is used, other ranges in the filter are ignored. If the filter is left blank, the service does not listen on any addresses.

For example, if you want the service to listen only on IPv4 addresses, leave the IPv6 filter empty.

Ranges are specified using the syntax IP1-IP2. Multiple ranges are separated using ‘,’ (comma) as the delimiter.

Example IPv4 filters:,

Example IPv6 filters:


Confirm WinRM Listener

Assuming the GPO in now Enabled and Linked to an OU containing the computers targeted for remoting, log onto one of the client machines in the domain, run “gpupdate /force” or wait for the group policy to be deployed to the client machine.

To enumerate the currently applied GPO use the “gpresult” command and confirm that the GPO titled ‘Windows Remote Management’ is listed in the ‘Applied Group Policy Objects’ section.

To enumerate the WinRM listener(s) and confirm the GPO configuration successfully applied use the following command:

winrm e winrm/config/listener

A new GPO source listener should have been created automatically and the output should resemble Figure 2

Figure 2

Open up a PowerShell console on a system connected to the same domain and create an array of computers to which you have just enabled remoting e.g.

$Servers = 'SERVER01','SERVER02','SERVER03','SERVER04',’SERVER05’

Using the Invoke-Command cmdlet I will demonstrate running a simple script block to collect the last boot time:

icm -ComputerName $Servers -ScriptBlock { [System.Management.ManagementDateTimeConverter]::ToDateTime((gwmi Win32_OperatingSystem).LastBootUpTime) } | ft -a pscomputername,datetime

The output of the above command should resemble Figure 3

Figure 3

Over the last year I have been using PowerShell 2.0 remoting capabilities extensively and I will follow up with a few example over the coming weeks.

For those interested I recommend the following for further reading:

Microsoft help documentation on ‘about_Remote_Troubleshooting’

Windows Management Framework Core package (Windows PowerShell 2.0 and WinRM 2.0)

Windows Remote Management feature for Windows Server 2003 and in Windows XP

Thanks for reading,