Share/Bookmark

Featured Posts

Video Game Website Gives all it's profit to Charity Sometimes you read an article that just makes you smile, this is such one: http://www.ps3attitude.com/new/2010/02/no-fuss-reviews-4000-charity/ A video game review website that has given all of it's...

Read more

SQL AD Group membership Hi all, I have been working on a way to return Active directory group membership from a linked AD server in SQL. Its quite hard as you can`t return it from the group - you have to return it from...

Read more

Face Detection with PHP A very useful piece of PHP code that will highlight any pictures where a face has been detected. Heres the first piece of PHP code you will need, it would be best to make this an include: [sourcecode...

Read more

Basic Guide to Database Normalisation: First Normal... Before I start talking about the normal forms, I thought it would be best to explain what I am planning to write about, and what normalisation is. I am going to cover what normalisation is for beginners...

Read more

Sony: Synonymous with Innovation Sony have always been on the leading edge of innovation. From creating the WalkMan back in the 80's to popularising the CD, DVD and Blu-Ray with their PlayStation products. In this article we're discussing...

Read more

SQL AD Group membership

Posted by daniel | Posted in Code Snippets | Posted on 05-02-2010

Tags: , , , , , , , , ,

1

Hi all,

I have been working on a way to return Active directory group membership from a linked AD server in SQL.

Its quite hard as you can`t return it from the group – you have to return it from the user. What i wanted was to return every group within an OU and its members.

I first found this person and thier code:

http://blog.sdbonline.com/blog/?tag=/sql+server

So i used this code and modified it somewhat. It now takes many more parameters and returns all group membership from an OU. You obviously have to set up the linked SQL server first.

One of the hardest parts of this was the fact that it seemed to have some kind of limit to how much you can query the AD. To get round this i put a wait in after a certain amount of groups (configured by the parameters). I found that every 500 waiting 2 minutes was the safest root. It also waits 2 minutes to start, in case you have run it recently.

ALTER PROCEDURE [dbo].[sp_getADGroupUsers]
@LDAPRoot nvarchar(200),
@OUGROUP nvarchar(200),
@OUUSERS nvarchar(200),
@Waittime nvarchar(10),
@WaitGap integer,
@ServerName nvarchar(30)

AS

BEGIN
DECLARE @SQLString nvarchar(4000)
DECLARE @group_name nvarchar(500)
DECLARE @group_cursor CURSOR
Declare @GroupSamAccountname nvarchar(100)
declare @i integer

--Create a temp table to hold the results
CREATE TABLE #ADSI (
GroupCN nvarchar(500),
SamAccountname nvarchar(100))

--build an SQL string to return the ADsPath for the requested group
set @SQLString = N'SET @group_cursor = CURSOR STATIC FOR SELECT SUBSTRING(ADsPath,'+ cast(len(@ldaproot)+1 as varchar) + ',LEN(ADsPath))

FROM OPENQUERY('+ @ServerName +',''SELECT ADsPath FROM ''''' + @LDAPRoot + @ouGROUP + '''''
WHERE objectClass = ''''Group'''' '') FOR READ ONLY; OPEN @group_cursor'

--Execute the statement (will return the ADsPath in @group_cursor
EXECUTE sp_executesql @SQLString, N'@group_cursor CURSOR OUTPUT',
@group_cursor OUTPUT

set @i = 0

FETCH NEXT FROM @group_cursor INTO @group_name
WHILE @@FETCH_STATUS = 0
BEGIN

--work out account name
set @GroupSamAccountname = substring(@group_name, 4, (len(@group_name) - len( @OUGROUP))-4)

--Get data for group
SET @SQLString = N'INSERT INTO #ADSI SELECT ''' + @GroupSamAccountname + ''',SamAccountname
FROM OPENQUERY('+ @ServerName +',''SELECT ADsPath,
SamAccountname FROM ''''' + @LDAPRoot + @OUUsers + '''''
WHERE objectCategory = ''''Person'''' and objectClass = ''''user''''
and memberOf=''''' + @group_name + ''''' '') ';

--execute the statement
EXECUTE sp_executesql @SQLString;

set @i = @i + 1

IF @i = @waitgap
BEGIN
WAITFOR DELAY @waittime
set @i = 0
END

FETCH NEXT FROM @group_cursor INTO @group_name
END

--return the resultset
--(use DISTINCT as a user might be a member of several groups)
SELECT DISTINCT * FROM #ADSI

--explicitely drop the temp table
DROP TABLE #ADSI
END 

And here is how you call it:

DECLARE @RC int
DECLARE @LDAPRoot nvarchar(200)
DECLARE @FriendlyGroupName nvarchar(200)
DECLARE @OUGROUP nvarchar(200)
DECLARE @OUUSERS nvarchar(200)
declare @waittime nvarchar(10)
declare @waitgap integer
declare @ServerName nvarchar(30)

set @ldaproot = 'LDAP://DC.domain.com/'

--Where are the groups you want to return
set @OUGROUP = 'OU=groups,DC=Domain,DC=co,DC=uk'
--Where are the users you want to return
set @OUUSERS = 'OU=users,DC=domain,DC=co,DC=uk'
--Waiting time between groups
set @waittime = '00:02:00'
--How big are the groups
set @waitgap = 500
--Your AD linked server in SQL
set @ServerName = 'ADSI'

EXECUTE @RC = [SystemsIntegration].[dbo].[sp_getADGroupUsers]
@LDAPRoot

,@OUGROUP
,@OUUSERS
,@waittime
,@waitgap
,@ServerName

Hope this helps someone,

Dan

Comments (1)

[...] Cardboard Coder » Blog Archive » SQL AD Group membership Posted in Object. Tags: delicious, featured-posts, group, Object, random-thoughts, read-more, [...]

Write a comment