When I attempt to query AD for users I receive the following error:
Cannot fetch a row from OLE DB provider "ADsDSOObject" for linked server "ADSI".
I assume the issue due to the 1000 row limit (or 901 rows in SqlServer 2008). I can page the query but I am looking for workaround that would allow me to retrieve more than 1000 at a time.
In case it helps, I am using SqlServer 2008 R2. and here is my query
SELECT samaccountname AS Account, ISNULL(givenName, '''') AS givenName, ISNULL(SN, '''') AS SN, ISNULL(DisplayName, '''') as DisplayName, ISNULL(Title, '''') AS Title
FROM OpenQuery(ADSI,
'SELECT SamAccountName, givenName, SN, DisplayName, Title
FROM ''LDAP://corpdomain.corp''
WHERE objectClass = ''User'' and (SN = ''*'' or givenName = ''*'')')
Any ideas?
EDIT - Upon further inspection I realized I am not able to properly page this query either. Does anyone have any tips on a solution that will allow me to page the results or a workaround that will allow me to return more than 901?
I hit this problem too, and didn't like the usual solution posted of paging by the first letter of the account name. This would mean 26 separate calls to AD, and also could still potentially fail because with a large domain its very possible to have more than 901 accounts starting with the same first letter - particularly if you are looking at computer accounts, which likely follow some systematic naming convention using the same first letter...
I did some playing around and I found that if you order the openquery by uSNCreated and put a TOP 901 clause on the outer query it doesn't blow up.
So, here is my SQL which fetches ALL active directory objects (computers, domain controllers, users and contacts) into a temp table in chunks of 901 records and gives you some useful information on each object.
CREATE TABLE #ADData(
Login NVARCHAR(256)
,CommonName NVARCHAR(256)
,GivenName NVARCHAR(256)
,FamilyName NVARCHAR(256)
,DisplayName NVARCHAR(256)
,Title NVARCHAR(256)
,Department NVARCHAR(256)
,Location NVARCHAR(256)
,Info NVARCHAR(256)
,LastLogin BIGINT
,flags INT
,Email NVARCHAR(256)
,Phone NVARCHAR(256)
,Mobile NVARCHAR(256)
,Quickdial NVARCHAR(256)
, usnCreated INT
)
DECLARE @Query VARCHAR (2000)
DECLARE @Filter VARCHAR(200)
DECLARE @Rowcount INT
select @Filter =''
WHILE ISNULL(@rowcount,901) = 901 BEGIN
SELECT @Query = '
SELECT top 901
Login = SamAccountName
, CommonName = cn
, GivenName
, FamilyName = sn
, DisplayName
, Title
, Department
, Location = physicalDeliveryOfficeName
, Info
, LastLogin = CAST(LastLogon AS bigint)
, flags = CAST (UserAccountControl as int)
, Email = mail
, Phone = telephoneNumber
, Mobile = mobile
, QuickDial = Pager
, usnCreated
FROM OPENROWSET(''ADSDSOObject'', '''', ''
SELECT cn, givenName, sn, userAccountControl, lastLogon, displayName, samaccountname,
title, department, physicalDeliveryOfficeName, info, mail, telephoneNumber, mobile, pager, usncreated
FROM ''''LDAP://[ldap-query-string]''''
WHERE objectClass=''''Person''''
AND objectClass = ''''User''''
' + @filter + '
ORDER BY usnCreated'')'
INSERT INTO #ADData EXEC (@Query)
SELECT @Rowcount = @@ROWCOUNT
SELECT @Filter = 'and usnCreated > '+ LTRIM(STR((SELECT MAX(usnCreated) FROM #ADData)))
END
SELECT LOGIN
, CommonName
, GivenName
, FamilyName
, DisplayName
, Title
, Department
, Location
, Email
, Phone
, QuickDial
, Mobile
, Info
, Disabled = CASE WHEN CAST (flags AS INT) & 2 > 0 THEN 'Y' ELSE NULL END
, Locked = CASE WHEN CAST (flags AS INT) & 16 > 0 THEN 'Y' ELSE NULL END
, NoPwdExpiry = CASE WHEN CAST (flags AS INT) & 65536 > 0 THEN 'Y' ELSE NULL END
, LastLogin = CASE WHEN ISNULL(CAST (LastLogin AS BIGINT),0) = 0 THEN NULL ELSE
DATEADD(ms, (CAST (LastLogin AS BIGINT) / CAST(10000 AS BIGINT)) % 86400000,
DATEADD(day, CAST (LastLogin AS BIGINT) / CAST(864000000000 AS BIGINT) - 109207, 0)) END
, Type = CASE WHEN flags & 512 = 512 THEN 'user'
WHEN flags IS NULL THEN 'contact'
WHEN flags & 4096 = 4096 THEN 'computer'
WHEN flags & 532480 = 532480 THEN 'computer (DC)' END
FROM #ADData
ORDER BY Login
DROP TABLE #ADData
When I attempt to query AD for users I receive the following error:
Cannot fetch a row from OLE DB provider "ADsDSOObject" for linked server "ADSI".
I assume the issue due to the 1000 row limit (or 901 rows in SqlServer 2008). I can page the query >but I am looking for workaround that would allow me to retrieve more than 1000 at a time.
In case it helps, I am using SqlServer 2008 R2. and here is my query >
SELECT samaccountname AS Account, ISNULL(givenName, '''') AS givenName, ISNULL(SN, '''') AS SN, ISNULL(DisplayName, '''') as DisplayName, ISNULL(Title, '''') AS Title
FROM OpenQuery(ADSI,
'SELECT SamAccountName, givenName, SN, DisplayName, Title
FROM ''LDAP://corpdomain.corp''
WHERE objectClass = ''User'' and (SN = ''*'' or givenName = ''*''
Any ideas?
EDIT - Upon further inspection I realized I am not able to properly page this query either. Does >anyone have any tips on a solution that will allow me to page the results or a workaround that will >allow me to return more than 901?
I just solved the same problem faced by me, by applying paging optimally (and I am successfully able to retrieve around 50k logins from the AD and it is not missing to fetch a single login account from the AD domains):
You need to work around the ADSI query limitation by looping through the characters of the attributes. See a solution here: http://www.sqlservercentral.com/Forums/Topic231658-54-1.aspx#bm1249991
The error was resolved by writing SELECT TOP 901 ...
IN PLACE OF JUST SELECT
.
And yes, this problem is related to using SqlServer 2008 R2. This problem occurred to me after migration of the database from 2005 to 2008, because in SQL Server 2008, there is a limit of 901 rows which was 1000 in SQL Server 2005 (the difference is we need to write select TOP 901, which was not required in the SQL Server 2005, else the program fails with error)
From your reply to my comment it sound like an SSIS package fired by a SQL Agent job would be an ideal way to go. Here's how you can access Active Directory in SSIS:
<LDAP://DC=domain,DC=tld>;(&(objectClass=User)(objectCategory=Person));distinguishedName,displayName,sn,givenName,middleName,mail,telephoneNumber;subtree
.You may also want to do the steps below, but be aware that if you do this and have an Active Directory attribute longer than 4000 characters, it will be truncated in the data flow.
Note that this query format is also supported:
SELECT distinguishedName, displayName, sn, givenName, middleName, mail, telephoneNumber
FROM 'LDAP://DC=domain,DC=tld'
WHERE objectClass = 'User' AND objectCategory = 'Person'
See the MSDN article Microsoft OLE DB Provider for Microsoft Active Directory Service for more information on the query formats supported by the provider.
This exact same Cannot fetch a row from OLE DB provider "ADSDSOObject" error message can also occur when you have less than 1000 rows in the resultset, but something else prevents SQL from fetching the records. We recently had a situation where the SQL Service account password was out of date, and this seems to have caused this error. Updating the password in the Log on details of the service and restarting SQL Server fixed it.
Just thought I would tack this answer on here so if someone googles this error message in future this might also help!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With