PowerShell Remoting, ADSI, CDOEXM и не только: решаем неявные проблемы авторизации через Kerberos
В рамках одного из сценария powershell потребовалось выполнить код на удалённом сервере. Причём код использует ADSI и CDOEXM (собственно говоря, ради CDOEXM и потребовалось использовать powershell remoting). И возникли проблемы, причина которых никак не вытекала из сообщений powershell.
Материал данной статьи касается не только ADSI. Если Вы используете powershell remoting – рекомендую прочитать. Вы можете использовать и ADSI, и CDOEXM в пределах powershell remoting. О том, что этому мешает и что с этим делать и пишу.
Идея в голову пришла следующая. Сценарий мы будем исполнять, скажем, на Windows Server 2008 R2, который “ничего не знает” о MS Exchange Server 2003, другими словами, на нём не будет CDOEXM. Соответственно, функционала CDOEXM и метода MailEnable в том числе не будет. Но кто нам мешает в рамках нашего сценария использовать удалённую сессию powershell на Windows Server 2003, на котором установлен MS Exchange Server 2003 и CDOEXM, само собой? (подобный “костыль” нам требуется только потому, что наш сценарий мы не сможем использовать на windows 2003 server, так как используем командлеты ADpowershell). Такая идея мне нравится, проста в эксплуатации, не требует установки на “новые” серверы устаревших средств управления (типа CDOEXM) с неизвестными последствиями. Будем пробовать ради теста исполнить на удалённом windows 2003 сервере следующий ADSI+CDOEXM код:
$testDG = [ADSI]"LDAP://CN=Подписка,OU=555,OU=По телефонным номерам,OU=Контакты,OU=iTg,DC=novgaro,DC=ru"; $testDG.MailEnable(); $testDG.SetInfo();
Данный код обеспечивает необходимый нам результат при исполнении на exchange 2003 хосте на базе windows 2003 server. Теперь попробуем выполнить его удалённо.
invoke-command ` -computerName server-12 ` -scriptBlock { $testDG = [ADSI]"LDAP://CN=Подписка,OU=555,OU=По телефонным номерам,OU=Контакты,OU=iTg,DC=novgaro,DC=ru"; $testDG.MailEnable(); $testDG.SetInfo(); }
Однако, несмотря на то, что локально на exchange server 2003 хосте код работает успешно, при его удалённом исполнении получаем следующие ошибки:
Исключение при извлечении элемента "MailEnable": "An operations error occurred. " + CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException + FullyQualifiedErrorId : CatchFromBaseGetMember Исключение при извлечении элемента "SetInfo": "An operations error occurred. " + CategoryInfo : NotSpecified: (:) [], ExtendedTypeSystemException + FullyQualifiedErrorId : CatchFromBaseGetMember
И причины такого поведения мне не были ясны из полученной информации. После того, как потерял день, разместил вопрос на форуме technet. Однако на ответ натолкнула серия экспериментов. Задумаемся над авторизацией. Мы с некоего хоста pshost открываем сессию на server-12, авторизация в моём случае – kerberos. Что принимает сессию на server-12? WinRM примет, служба. И WinRM на server-12 будет действовать от моего имени. Но как действовать? Я же прошу создать объект ADSI. Для успешного выполнения инструкции WinRM, действуя от моего имени по билету с хоста pshost, должна выполнить LDAP запрос к DC, а это уже третий хост. Естественно, запрос на DC должен уйти от моего имени.
Вот он, ключевой момент. Служба на хосте server-12, действуя по моему билету с pshost, должна авторизоваться на DC. Но мои полномочия были подтверждены на pshost, server-12 доверился подтверждённым полномочиям в рамках взаимного доверия членов одного домена. Но DC уже должен доверить моим полномочиям, полученным от server-12, хотя подтверждены они были для pshost! По умолчанию, транзитивность доверия действительна только для DC.
Чтобы исполнить наш код, мы должны предоставить хосту server-12 право делегирования, установив для его учётной записи в ADUC опцию “Доверять компьютеру делегирование”. После чего перезагружаем server-12. И вуаля – приведённый выше код прекрасно работает!
Вот так вот всё просто, проблема была в делегировании полномочий при попытке выполнения LDAP запроса. Надеюсь – и Вам пригодиться данная информация.
Отзывы » (1)
RSS комментарии
Обратная ссылка
Всем привет, оставлю это здесь, так как потратил много времени на поиск ошибки. Если кто-то сталкнется с такой же, ответ будет тут же ) (Конечно, велика вероятность что уже давно не актуальна проблема, но все же)Строчка с MailEnable не должна содержать скобок, иначе будет ошибка…
$testDG
.MailEnable;