?
Solved

How do I enumerate GPOs linked to an OU in Active Directory?

Posted on 2008-10-08
16
Medium Priority
?
1,235 Views
Last Modified: 2013-12-24
How would I find a computer object in AD, determine the computer object's OU, and enumerate the GPOs that are specifically linked to that OU?

I received an audit script request from Management that I've been able to translate into the following request.
"Write a script that can do the following:
1.  Search AD for a computer object
2.  Identify the OU of the computer object
3.  Enumerate the GPOs linked to the identified OU
4.  Determine the Global Group(s) designated in the security filter of the GPO
5.  Verify that the members of the Administrator group belong to one of the identified Global Groups"

This was a fairly liberal translation and is significantly less ambiguous than the original request.  Steps 1 and 2 are fairly simplistic by my standards, as well as step 5.  It is those pesky steps 3 and 4 that have me browsing the web, watching webcasts, and finally pandering to those who have more scripting mojo than myself.

Simply put, how do I use a computer object's ADsPath to query AD to find GPOs linked to the computer object's OU?  I'm only interested in the GPOs linked directly to the OU and none of the GPOs linked higher up in AD.  Thanks!
0
Comment
Question by:Fieos
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 5
  • 3
  • +1
16 Comments
 
LVL 71

Expert Comment

by:Chris Dent
ID: 22676696

I can't help but wonder exactly what an audit like this is expected to show... To me it's approaching GP application from the wrong direction and ignores the existing tools (such as RSOP.msc, GPResult and the Group Policy Management Console) which can easily retrieve much of the above.

Still... I know where the items you're after are set.

The Policies linked to a specific OU are defined in the GpLink attribute on an OU. That attribute contains the LDAP paths for each explicitly linked policy (but doesn't account for inheritance). Unless I find a better way that leaves you checking that up the tree as well.

Using each of those paths would let you get back to the policy name, the displayName attribute on the linked policy.

The security filter is based on all objects that have the "Apply Group Policy" right on the policy meaning you'd need to read and interpret the security descriptor. By default that's just Authenticated Users.

Chris
0
 

Author Comment

by:Fieos
ID: 22678438
Chris-Dent,

I was instructed to write a script that reads a list of host names, for each host it determines which OU in which the host resides, it determines what GPOs are linked to that OU, it then enumerates the Administrators group on the server and verifies that the account is a member of one of the groups identified in the security filter of the applied GPO.  Example output to an XLS would look like this:

Hostname     OU                    Linked GPO                Account         GPO applied to user
ServerA       Infrastructure   Admin_Lockdown      User01           Yes

If you know of a better way to provide this information, I appreciate any feedback.  Your GpLink information should be a help already as I don't have a good understanding of AD schema.  Right now I'm pulling the distinguished name and I figure I'll have to clean that string up to query OU information.  I hope this is a report that they actually use!

Thanks again!

0
 
LVL 71

Expert Comment

by:Chris Dent
ID: 22678788

Fair enough :) My opinion on the approach isn't really relevant if you have to produce the script regardless.

The OU is a bit of a tricky one to get, in quite a lot of cases it does end up being easier parsing the name out of the string. The only way we have of getting that explicitly in code is by calling a "Parent" method on an object.

e.g.:

Set objComputer = GetObject("LDAP://CN=MyPC,OU=Somewhere,DC=mydomain,DC=com")
strOU = objComputer.Parent

Not exactly neat, and quite heavy on AD connections if you have a lot to check.

I'd like a little time to think about this one, it's a long way from being trivial.

Chris
0
Visualize your virtual and backup environments

Create well-organized and polished visualizations of your virtual and backup environments when planning VMware vSphere, Microsoft Hyper-V or Veeam deployments. It helps you to gain better visibility and valuable business insights.

 

Author Comment

by:Fieos
ID: 22686813
Well, I've made a fair amount of progress.  I can find the OU of the computer and enumerate the linked GPOs.  I'm trying to figure out how to enumerate the members of the security filter.  I see the GetSecurityInfo( ) Function but I'm not sure how to enumerate the data.  I believe that is the function that contains the accounts in the security filter, but I've also seen that it holds the access lists to modify the GPO.  Do you happen to know what information is contained?  I've seen the .add and the .remove but I don't see anything to enumerate the contents.
0
 
LVL 71

Expert Comment

by:Chris Dent
ID: 22687179

Hmm, I wonder. Would it be bad to attempt to convince you to switch to PowerShell for writing this kind of thing?

It's just permissions in VbScript are a lot of hard work. In PowerShell we can create some really pretty reports.

That might fall apart if the script has to be portable.

Chris
0
 

Author Comment

by:Fieos
ID: 22687286
I haven't played with PowerShell scripting.  I was under the impression I couldn't use it against 2003 servers.  Is that not the case?   We have a MS trainer coming in a few weeks to train us on the wonders of PowerShell; perhaps I should get a head start.
0
 
LVL 71

Expert Comment

by:Chris Dent
ID: 22687322

You can, I used it extensively against my domain which is also 2003 :)

If you go down that road it would probably also be a good idea to get this:

http://www.quest.com/powershell/activeroles-server.aspx

They're free, and we could use something like the Get-QADPermission cmdlet for this.

Chris
0
 
LVL 71

Expert Comment

by:Chris Dent
ID: 22687329

If we're going to look at that path I think I'll see if one of the other experts is available to take a look at this. He's much better at PowerShell than I and might have some insights that will make this a lot less bother :)

Chris
0
 

Author Comment

by:Fieos
ID: 22687364
I appreciate the help, and your continued support.  
0
 
LVL 18

Expert Comment

by:BSonPosh
ID: 22687578
Using powershell with the free GPO cmdlets from www.sdmsoftware.com and the free AD cmdlets from www.quest.com/powershell this task is trivial. If you would like I can post an example.
0
 

Author Comment

by:Fieos
ID: 22688690
I would definitely appreciate an example if you have one available.  I'm completely new to powershell.
0
 
LVL 18

Expert Comment

by:BSonPosh
ID: 22689255
Can you clarify point 5?
0
 

Author Comment

by:Fieos
ID: 22689323
5.  Verify that the members of the Administrator group belong to one of the identified Global Groups"

Pull the members/groups of the local administrators group on the server.  Identify (Yes/No) as to if the members of the local administrators group on the server are members of the group(s) identified in the security filter of a GPO.

Example:
Server = Myserver has two groups in the administrators group:  Group1 and Group2
Determine in a yes/no manner if those groups are members of groups identified in a GPOs security filter.  

This is to basically verify that we do have this user/group in the administrators list, but they are a member of a group that is identified in the security filter of GPO applied to the OU of which the server resides.  

That help?
0
 
LVL 18

Expert Comment

by:BSonPosh
ID: 22689779
I will work on part 5... I am still not sure I get the point, but here is something to play with
Param($Computer)
 
add-pssnapin SDMSoftware.PowerShell.GPMC -ea 0
add-pssnapin Quest.ActiveRoles.ADManagement -ea 0
 
#1.  Search AD for a computer object
$CompObj = Get-QADComputer $Computer
 
#2.  Identify the OU of the computer object
$OU = invoke-expression "'$($CompObj.distinguishedName)' -replace 'CN\=$Computer,',''"
 
#3.  Enumerate the GPOs linked to the identified OU
$GPLinks = Get-SDMgplink -scope $OU -native
 
#4.  Determine the Global Group(s) designated in the security filter of the GPO
foreach($link in $GPLinks)
{
 
    $groups = Get-SDMgpo -GPOID $link.GPOID | Get-SDMgpoSecurity | %{$_.ToArray()} | %{$_.Trustee}
    $groups
}

Open in new window

0
 
LVL 1

Accepted Solution

by:
gustavwind earned 2000 total points
ID: 22876654
Not pretty or robust but gets the job done.  Give the vbScript the DN of the OU you need to check.  Enclose it in quotes if it has spaces.  Outputs a comma delimited list of the GPO name, the GUID, and shows whether the link is active.  
strOU = WSCript.Arguments(0)	' DN of the OU enclosed in quotes
 
' Configure ADODB ADsDSO connection
'
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open "Provider=ADsDSOObject;"
Set objCommand = CreateObject("ADODB.Command")
objCommand.ActiveConnection = objConnection
objCommand.Properties("Page Size") = 3000
 
' Find the OU
'
objCommand.CommandText = _
    "<LDAP://" & strOU & ">;(objectClass=organizationalUnit)" & _
        ";gpLink,distinguishedName;base"  
Set objRecordSet = objCommand.Execute
 
strGpLinks = objRecordSet.Fields("gpLink").Value
intCnt = 0
 
' Parse the gpLink
'
Do until strGpLinks = ""
	i = instr(strGpLinks,"]")
	strGpoDn = mid(strGPlinks,2,i-2) 'DN for LDAP query
	strGpLinks = mid(strGPLinks,i+1) 'strip it off the gpLink string
 
	' Use the DN to find the GPO object
	'
	objCommand.CommandText = "<" & mid(strGpoDn,1,len(strGpoDn)-2) & ">;" & _
		"(objectClass=groupPolicyContainer);displayName;base"
	set objRecordSet = objCommand.Execute
	strGPOName = objRecordSet.Fields("displayName").Value
	strGPOGuid = mid(strGpoDn,11,38)
	if mid(strGpoDN,len(strGpoDn),1)="0" then
		strGpoLinked = "*Linked*"
	else
		strGpoLinked = "unlinked"
	end if
 
	wscript.echo chr(34) & strGPOName & chr(34) & "," & strGpoLinked & "," & strGpoGuid
	intCnt = intCnt + 1
Loop
wscript.echo intCnt

Open in new window

0
 

Author Closing Comment

by:Fieos
ID: 31504324
Thanks, sorry for the late follow-up
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Microsoft Office 365 is a subscriptions based service which includes services like Exchange Online and Skype for business Online. These services integrate with Microsoft's online version of Active Directory called Azure Active Directory.
Active Directory can easily get cluttered with unused service, user and computer accounts. In this article, I will show you the way I like to implement ADCleanup..
This tutorial will walk an individual through the steps necessary to join and promote the first Windows Server 2012 domain controller into an Active Directory environment running on Windows Server 2008. Determine the location of the FSMO roles by lo…
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…
Suggested Courses

800 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question