Ошибка: не удается получить строку от поставщика OLE DB "ADsDSOObject" для связанного сервера "ADSI" - PullRequest
4 голосов
/ 21 декабря 2011

Когда я пытаюсь запросить AD для пользователей, я получаю следующую ошибку:

Невозможно получить строку от поставщика OLE DB "ADsDSOObject" для связанного сервера "ADSI".

Я предполагаю, что проблема связана с ограничением в 1000 строк (или 901 строк в SqlServer 2008). Я могу отобразить запрос, но я ищу обходной путь, который позволил бы мне получить более 1000 одновременно.

Если это поможет, я использую SqlServer 2008 R2. и вот мой запрос

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 = ''*'')')

Есть идеи?

РЕДАКТИРОВАТЬ - После дальнейшего осмотра я понял, что не могу правильно отобразить этот запрос. У кого-нибудь есть какие-либо советы по решению, которые позволят мне публиковать результаты, или обходной путь, который позволит мне вернуть более 901?

Ответы [ 6 ]

4 голосов
/ 29 марта 2017

Я тоже столкнулся с этой проблемой, и мне не понравилось обычное решение о пейджинге по первой букве имени учетной записи. Это будет означать 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
3 голосов
/ 23 апреля 2013

Проблема

Когда я пытаюсь запросить AD для пользователей, я получаю следующую ошибку:

Невозможно получить строку от поставщика OLE DB "ADsDSOObject" для связанного сервера "ADSI".

Я предполагаю, что проблема связана с пределом в 1000 строк (или 901 строк в SqlServer 2008). Я могу отобразить запрос>, но я ищу обходной путь, который позволил бы мне получить более 1000 одновременно.

Если это поможет, я использую SqlServer 2008 R2. и вот мой запрос >

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 = ''*''

Есть идеи?

РЕДАКТИРОВАТЬ - После дальнейшей проверки я понял, что я не могу правильно страницы этого запроса. Есть ли у кого-нибудь какие-либо советы по решению, которые позволят мне публиковать результаты, или обходной путь, который> позволит мне вернуть более 901?

Мой обходной путь

Я только что решил ту же проблему, с которой столкнулся, путем оптимального применения подкачки страниц (и я успешно могу получить около 50 тыс. Логинов из AD, и не исключено, что можно получить одну учетную запись для входа в домены AD):

Необходимо обойти ограничение запросов ADSI, просматривая символы атрибутов. Смотрите решение здесь: http://www.sqlservercentral.com/Forums/Topic231658-54-1.aspx#bm1249991

Ошибка была устранена путем написания SELECT TOP 901 ... В МЕСТО ТОЛЬКО SELECT.

И да, эта проблема связана с использованием SqlServer 2008 R2. Эта проблема возникла у меня после переноса базы данных с 2005 по 2008 год, поскольку в SQL Server 2008 существует ограничение в 901 число строк, равное 1000 в SQL Server 2005 (разница состоит в том, что нам нужно написать select TOP 901, который не был требуется в SQL Server 2005, иначе программа завершится с ошибкой)

3 голосов
/ 26 января 2012

Из вашего ответа на мой комментарий это звучит так, будто пакет SSIS, запущенный заданием агента SQL, был бы идеальным вариантом. Вот как вы можете получить доступ к Active Directory в SSIS:

  1. Создание нового проекта SSIS
  2. Добавление задачи потока данных в поток управления.
  3. Перейдите на вкладку «Поток данных».
  4. Перетащите источник ADO NET с панели инструментов в поток данных.
  5. Дважды щелкните источник ADO NET.
  6. Нажмите кнопку «Создать» рядом с диспетчером соединений OLE DB.
  7. Нажмите кнопку «Создать» в диспетчере соединений ADO.NET. Диалог.
  8. Щелкните стрелку, указывающую вниз, в раскрывающемся списке «Поставщик».
  9. Найдите в списке поставщиков .Net для OleDb и дважды щелкните по нему.
  10. Найдите в списке поставщика OLE DB для служб каталогов Microsoft. и дважды щелкните по нему.
  11. Нажмите кнопку ОК.
  12. В имя сервера или файла положить ActiveDirectory.
  13. Выделите ActiveDirectory в соединениях данных.
  14. Нажмите кнопку ОК.
  15. Измените режим доступа к данным на команду SQL.
  16. В текстовом поле команды SQL введите <LDAP://DC=domain,DC=tld>;(&(objectClass=User)(objectCategory=Person));distinguishedName,displayName,sn,givenName,middleName,mail,telephoneNumber;subtree.
  17. Измените домен и tld на соответствующие идентификаторы для вашего домена и добавьте любые другие подходящие элементы пути LDAP.
  18. Добавьте любые другие соответствующие атрибуты ActiveDirectory в запрос.
  19. Нажмите кнопку ОК.
  20. Вы увидите сообщения об ошибках, указывающие, что тип данных «System.Object» не поддерживается. Их можно игнорировать.
  21. Нажмите кнопку ОК в диалоговом окне предупреждения.
  22. Щелкните правой кнопкой мыши источник ADO NET.
  23. Нажмите Свойства.
  24. Измените ValidateExternalMetadata на False.

Возможно, вы также захотите выполнить следующие шаги, но имейте в виду, что если вы сделаете это и у вас атрибут Active Directory длиннее 4000 символов, он будет усечен в потоке данных.

  1. Щелкните правой кнопкой мыши источник ADO NET.
  2. Нажмите Показать расширенный редактор.
  3. Перейдите на вкладку Свойства ввода и вывода.
  4. Расширить выход источника ADO NET.
  5. Развернуть выходные столбцы.
  6. Для каждого столбца измените DataType на строку Unicode [DT_WSTR] и установите длину 4000.
  7. Нажмите кнопку ОК.
  8. Дважды щелкните Источник ADO NET, перейдите к «Вывод ошибок».
  9. Выберите все значения для строк в разделе Trunctation.
  10. Элемент списка
  11. В поле Установить это значение для выбранных ячеек выберите Игнорировать ошибку.
  12. Нажмите кнопку Применить.
  13. Нажмите кнопку ОК.

Обратите внимание, что этот формат запроса также поддерживается:

SELECT     distinguishedName, displayName, sn, givenName, middleName, mail, telephoneNumber
FROM         'LDAP://DC=domain,DC=tld'
WHERE     objectClass = 'User' AND objectCategory = 'Person'

См. Статью MSDN Поставщик Microsoft OLE DB для службы Microsoft Active Directory для получения дополнительной информации о форматах запросов, поддерживаемых поставщиком.

0 голосов
/ 02 января 2019

В точности то же самое Невозможно получить строку из поставщика OLE DB "ADSDSOObject" Сообщение об ошибке также может появляться, когда в наборе результатов меньше 1000 строк, но что-то еще мешает SQL извлекать записи. Недавно у нас была ситуация, когда пароль учетной записи службы SQL устарел, и это, похоже, вызвало эту ошибку. Обновление пароля в разделе «Сведения о службе» и перезапуск SQL Server исправили его.

Просто подумал, что я здесь добавлю этот ответ, так что, если кто-нибудь погуглит это сообщение об ошибке в будущем, это также может помочь!

0 голосов
/ 31 мая 2018

Существует еще одна причина, по которой вы можете получить эту ошибку.Если вы используете несколько доменов, вам может потребоваться изменить свойства Active Directory для этого SQL Server.Выбор «Доверять этот компьютер для делегирования какой-либо службе (только Kerberos)» должен устранить проблему, если причиной является «двойной переход» в многодоменной установке.

Active Directory Server Properties

0 голосов
/ 19 июля 2016

Я решил это, используя другой пост Магнуса Рейтера - просто подумал, что дал вам ссылку, потому что это просто и гениально!

Он сделал 2 запроса, присоединившись к ним с помощью UNION, но для первогоодин он выбрал все sAMAccountname m.Конечно, если вы обнаружите, что вашим средним значением является не буква «m», вы можете отрегулировать это соответствующим образом, но обычно, если у вас есть около 1000-2000 записей, это будет «m».

Retrieve> 901строки от связанного сервера SQL Server 2008 до Active Directory

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...