я ударил эту проблему тоже, и не нравится обычное решение размещенного пейджинговой по первой букве имени учетной записи. Это будет означать 26 отдельных вызовов AD, а также может по-прежнему потенциально потерпеть неудачу, потому что с большим доменом у него может быть более 901 учетных записей, начинающихся с того же первого письма, особенно если вы смотрите на учетные записи компьютеров, которые, вероятно, следуют некоторым систематическим именования с использованием той же первой буквы ...
Я немного поиграл, и я обнаружил, что если вы закажете openquery с помощью uSNCreated и поместите предложение TOP 901 во внешний запрос, он не взорвется.
Итак, вот мой SQL, который извлекает ВСЕ активные объекты каталога (компьютеры, контроллеры домена, пользователи и контакты) во временную таблицу в кусках 901 записей и дает вам полезную информацию по каждому объекту.
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
Какая у вас конечная цель в этом отношении? Лучшим решением может быть вовсе не делать этого. Например, я работал над проблемами с этим типом запросов в некоторых наших системах, заменив его пакетом SSIS в одном случае и источником данных отчета, который напрямую связан с AD в SSRS в другом случае. – JamieSee
Спасибо Джеймсу, я переоценил конечную цель и нашел лучший способ. Мы хотели добавить атрибуты пользователю AD для целей нашего приложения, поэтому теперь мы просто используем пакетное задание для извлечения пользователей AD и хранения их в БД. – SDeezy
Возможный дубликат [Получить> 901 строк из связанного сервера SQL Server 2008 с Active Directory] (http://stackoverflow.com/questions/5661371/retrieve-901-rows-from-sql-server-2008-linked-server- to-active-directory) –