Скрипт Exchange Powershell, почему при запуске из планировщика задач не добавляются контакты?
Добрый день хабровчане.
Исходные данные:
Платформа: MS Exchange 2010
На сервере MS Exchange есть скрипт, который должен выполнять создание почтовых контактов, и их добавление в группу рассылки.
Механизм работы скрипта примерно следующий: В папку на сервере MS Exchange выкладывается файл со списком e-mail адресов
Скрипт подбирает выложенный файл
Далее приводится 2 основных действия данного скрипта:
Проходится циклом по строкам файла, и создает новые контакты используя командлет New-MailContact
Добавление контактов в группу рассылки командлетом Add-DistributionGroupMember
Для выполнения скрипта используется технологическая учетная запись, с достаточными правами, такими как: Разрешить вход как пакетное задание (Logon as a batch job) на сервере MS Exchange
Роли Exchange: Organization Management
Recipient Management
Беда в том, что при запуске скрипта из планировщика задач, не происходит ни создания контактов ни их добавления в группу рассылки (даже уже существующих контактов).
При выполнении скрипта в консоли Exchange Powershell, запущенной от имени данного технологического пользователя, все требуемые действия выполняются штатно, т.е. контакты создаются, и в группу рассылки добавляются.
Подскажите плиз куда копать дабы решить проблему выполнения скрипта из планировщика задач Windows.
Спасибо.
Start-Transcript в самом начале и Stop-Transcript в самом конце позволят вам понять что происходит во время исполнения скрипта. А история запуска scheduled task позволит увидеть запускался ли скрипт вообще. Может быть, что он просто не запускается и сбоит сам планировщик задач.
Start-Transcript и Stop-Transcript используются в данном скрипте.
В планировщике скрипт выполняется, т.к. другие действия отрабатывают на отлично.
В журнале Transcript, в тех местах где проблемные команды, попросту отсутствует вывод, хотя сегодня отключу директиву -ErrorAction SilentlyContinue и посмотрю вывод снова.
Попробуйте проблеммные места обрабатывать спомощью try/catch и делать дамп ошибки в файл.
Меня смущает ваше упоминание "тех местах где проблемные команды, попросту отсутствует вывод", это как?
Вы не хотите выложить скрипт в студию, чтобы можно было лучше понять проблемные места и попробовать у себя?
Ну и совсем конечно вы указываете -Confirm $false и домен контроллер, так?
Евгений, к сожалению не смог победить конструкцию try/catch
Вывод появился после очистки аргумента команды -ErrorAction SilentlyContinue в следующих блоках:
В цикле проверки/добавления новых контактов, появились записи об отказе в доступе
New-MailContact : Active Directory operation failed on DC2.DomainName.local. This
error is not retriable. Additional information: Access is denied.
Active directory response: 00000005: SecErr: DSID-031528D2, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0
At C:\scripts\powershell\mailgroup-update.ps1:402 char:19
+ New-MailContact <<<< -name $_.$SrcFileEmailColumnHeader -externalEmailAddress _.$SrcFileEmailColumnHeader -OrganizationalUnit $DstOUForMailContacts
+ CategoryInfo : NotSpecified: (0:Int32) [New-MailContact], ADOperationException
+ FullyQualifiedErrorId : DF61DE7E,Microsoft.Exchange.Management.Recipient
Tasks.NewMailContact
В цикле очистки целевой группы, появились записи свидетельствующие о нехватке прав:
Remove-DistributionGroupMember : Active Directory operation failed on DC2.DomainName.local. This error is not retriable. Additional information: Insufficient access rights to perform the operation.
Active directory response: 00002098: SecErr: DSID-03150F94, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0
At C:\scripts\powershell\mailgroup-update.ps1:431 char:112
+ foreach ($member in $(Get-DistributionGroupMember -identity $DstMailGroupName)) {remove-distributiongroupmember <<<< -identity $DstMailGroupName -member $member -Confirm:$false}
+ CategoryInfo : NotSpecified: (0:Int32) [Remove-DistributionGroupMember], ADOperationException
+ FullyQualifiedErrorId : 795FE5D6,Microsoft.Exchange.Management.Recipient
Tasks.RemoveDistributionGroupMember
Очевидно, что техпользователю банально недостаточно прав, но как же тогда скрипт отрабатывает в командной консоли от имени данного техпользователя, ясное дело что выполнение whoami выводит имя этого самого техпользователя.
Для полноты эксперимента осталось забить в задание моего админ пользователя (под которым админится сервер Exchange), с единственной ролью Organization Management, и посмотреть как отработает скрипт в данном случае.
Dmytro Yunh, попробуйте воспользоваться параметром -BypassSecurityGroupManagerCheck
Try/catch у вас не сработал поскольку здесь:
# try {
# Get-Recipient $_.$SrcFileEmailColumnHeader -ErrorAction SilentlyContinue
# }
# catch {
# Write-Host "�����-�� �������������" -ForegroundColor RED
# }
должен быть не SilentlyContinue, а Stop Попробуйте, у вас получится.
Вот такая конструкция в вашем скрипте меня очень смущает $_.$SrcFileEmailColumnHeader
Я бы избегал такой variable.
...Честно говоря, я вообще не понимаю зачем вам нужен SilentlyContinue где б это ни было, раз это скрипт из планировщика. наоборот, лучше ошибок побольше. логи стерпят, а проблемы победятся быстрее
Вы имеете ввиду применить его к проблемным командлетам: New-MailContact
Remove-DistributionGroupMember
Add-DistributionGroupMember
? $_.$SrcFileEmailColumnHeader
Не думаю что с данной переменной есть проблема, в ручном режиме все ведь работает. try/catch
Попробую сегодня победить.
MaxKozlov, с правами у техпользователя все не так плохо, вот вывод из сеанса консоли, имя техпользователя: svc.ex-hubcas
Ознакомился с приведенными Вами материалами по ссылкам, в рабочее время не рискну, возможно вечером или ночью буду пробовать.
Dmytro Yunh, в вышеприведённом примере надо $null использовать, а не приведение к строке ""
Это я ещё до ящика с помидорами не добрался :))))
Очень уж всё многословно, тыщи переменных, где достаточно одной.
MaxKozlov, на голом PS Exchange + AD? Как вы себя это видите, поделитесь сакральным знанием )))
А с замечанием что с общей концепцией, что всё уж слишком длинно, согласен )))
Евгений, Это значит что скрипт должен в первых строках сделать
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin
# И всё такое прочее что надо для 2010 конкретно
и то же самое для AD, Чтобы гарантированно исключить все проблемы с путями и умолчаниями
Я вовсе не имею ввиду что надо это делать на голой машине :)
А с EXCHANGE 2013+ проще - он может админиться удалённо. достаточно настроить ремотинг. но RSAT для AD всё равно понадобится, не мучаться же с ADSI
MaxKozlov, проблема действительно решилась правкой разрешений на OU и группу рассылки.
Осталось запилить отдельного пользователя, и выписать ему индивидуальный набор прав.
Над тыщей переменных я поработаю, сам понимаю что их там в избытке, но повторюсь, это лишь мои начальные шаги в PS, и для меня проще в отладке было использование переменных.
Благодарю всех участников за посильный вклад в решении проблемы.
Dmytro Yunh, тут даже не столько сами переменные мешают, сколько перекладывание данных туда-сюда по файлам, устаёшь следить куда что ушло
а по стилю, конечно Write-Host разноцветный это круто, но вместо
if ($Debugging {
Write-Host ...
}
Можно писать Write-Debug ...
А если там структура, то её можно Write-Debug ($struct | Out-Strng)
И больше функций, чтобы не заниматься самоповторением :)
Больше похоже на магию конечно. Если оно работает из консоли от имени пользователя специально созданного, просьба убедится все же whoami именно этот пользователь.
Второй вариант - поменять содержимое скрипта, или добавить отладочную строку в начале скрипта и сделать exit, что бы остановить выполнение скрипта и убедится, что скрипт реально запускается под юзером и выдает инфу в файл.
Больше посоветовать нечего, тут явно нет связи с Exchange -)
Конечно же в консоли whoami показывает технологического юзера, а в скрипте есть отладочные команды, он формирует отчёт, в котором в т.ч. и имя запустившего скрипт пользователя. Толковых мыслей пока не добавилось
модули-то на 2010 может сами и подгружаются, а вот Snapin's - нет. Скорее всего это - причина. проверять надо бы на голом PS, а не Exchange Powershell
Поэтому для начала можно запустить из планировщика простейший скрипт Get-ExCommand >c:\temp\log
Чтобы убедиться что команды доступны.
Не помню как там на 2010, если Get-ExCommand недоступна, то сделать Add-PSSnapin нужный и потом Get-Command
Если всё что нужно доступно, логов добавить после каждой подозрительной строки
В скрипте помимо описанных 2-х проблемных командлетов, используется огромная масса других операций, в т.ч. и работа с файлами, их архивирование, как итог скрипт самостоятельно формирует отчёт с ключевыми значениями и отлично справляется с его отправкой по почте, и письмо от скрипта приходит со всеми в него заложенными параметрами отчёта.
Командлеты доступны, т.к. вызов выполнятся из чистого PS, с подгрузкой Snapin самого Exchange, рядом в планировщике крутится скрипт, выполняющийся аналогичным образом, который еженедельно отправляет по почте список участников одной из групп рассылок, автор скрипта, тот же Дмитрий :)