Показать полную графическую версию : [решено] PS: Синхронизация контактов Outlook`a с AD
dosperados
06-09-2011, 11:36
Пишу скрипт по синхронизации Email адресов, которые хранятся в АД и контактов в Outlook`е.
Смысл в том, что скрипт по добавлению Email адресов из АД в Outlook уже есть он описан на форуме тут (http://forum.sysadmins.su/index.php?showtopic=10957)
Но при каждом запуске скрипта в Outlook`e появляются дубликаты одних и тех же записей.
Я хочу написать скриптик который бы делал вот что:
1) При импорте проверял бы есть такой контакт в Outlook`e, если есть то повторно не импортировать, если же нету то импортировался но с дополнительным полем которое бы указывало на то, что этот объект импортирован из АД
2) Потом бы проверялись контакты в Outlook`e если контакт имеет поле импортирован то такойже объект ищется в АД если его там нету то этот контакт удаляется из Outlook`а, если же контакт создал сам пользователь и у него нету поля которое показывает что он создан при импорте то этот контакт остается без изменения.
так вот я не знаю как правильно реализовать то что я хочу и я пошел обходным путем (если кто знает как сделать правильней и лучше подскажите!!!):
Я сначала удаляю контакты из Outlook`а в которых присутствуют поля означающие что этот контакт импортирован (у меня за это отвечает два поля $_.Mileage и $_.BusinessHomePage) контакты созданные пользователем не трогаем. Потом необходимо проделать импорт из АД в Outlook с полями означающими импорт.
так вот у меня неправильно работает удаление контактов с полем означающим импорт.
я делаю это так:
#Подключаемся к Outlook
$outlook = New-Object -ComObject Outlook.Application
$mapi = $outlook.GetNamespace("MAPI")
#Получаем папку контактов
$Contacts = $mapi.GetDefaultFolder(10).Items
$Contacts | ForEach {
if ($_.Mileage -match "1" )
{if ($_.BusinessHomePage -match "http://company.com/" )
{Write-Host " Импортированный контакт " $_.LastName $_.Email1Address -ForegroundColor blue ; $_.delete() }
}
else { Write-Host " Пользовательский контакт " $_.LastName $_.Email1Address -ForegroundColor Red}
}
когда запускаешь этот скрипт без метода $_.delete() то все проходит как положено все контакты правильно показываются какие импортированы а какие пользовательские, а когда же ставим метод $_.delete() то контакты как бы делятся на две части и удаляются только половина импортированных контактов. И так чтобы удалить все импортированные контакты надо несколько раз запустить скрипт на удаление…
Почему так, помогите!!! Или предложите другой метод, всем предложения решения задачи буду рад!!!
dosperados
07-09-2011, 05:51
Что-то ни кто даже слово не напишет) что все боятся запустить у себя этот скрипт!? Он ничего не удалит если не будет в контакте особых полей ($_.Mileage и $_.BusinessHomePage) с нужными значениями. только если два этих поля удовлетворили условию тогда этот контакт удалиться...
Мне нужен совет гуру, почему при тесте без использования $_.delete() все работает как положено, а с ним неправильно!!!
Ну или вообще как подругому сделать)
dosperados, возможно, это как-то связано с перемещением по коллекции. Я с чем-то подобным при работе с коллекциями сталкивался и под WSH.
Попробуйте работать не с коллекцией, а с выборкой по условию:
$outlook = New-Object -ComObject Outlook.Application
$mapi = $outlook.GetNamespace("MAPI")
$Contacts = $mapi.GetDefaultFolder(10).Items
$Contact = $Contacts.Find("[Mileage] = ""1"" AND [BusinessHomePage] = ""http://company.com/""")
while ($Contact -ne $null) {
Write-Host $Contact.LastName $Contact.Email1Address $Contact.EntryID -ForegroundColor blue
$Contact.Delete()
$Contact = $Contacts.FindNext()
}
dosperados
07-09-2011, 18:47
Iska, Спасибо твой метод работает как положенно, но кто знает как реализовать мою задумку не через попу как сейчас, а правильно!?
dosperados
08-09-2011, 11:26
Такой вопрос: я создаю в папке "\\Outlook\Контакты" подпапку "Контакты моей компании" саму папку я успешно создаю, но если начинаешь создавать контакты в ней, они сохраняется в папке "Контакты", а мне надо чтобы он сохранился в подпапке "Контакты моей компании".
Кто решал такую проблему подскажите...
#Подключаемся к Outlook
$outlook = New-Object -ComObject Outlook.Application
$mapi = $outlook.GetNamespace("MAPI")
#Получаем папку контактов для сохранения новых
$Contacts = $mapi.GetDefaultFolder(10)
# Проверяем создана ли подпапка "контакты фирмы" если не создана, то создаем ее.
$CompanyContFolder = $Contacts.Folders.Item("Контакты моей компании")
if ($CompanyContFolder -eq $null) {
$CompanyContFolder = $Contacts.Folders.Add("Контакты моей компании")
$CompanyContFolder = $Contacts.Folders.Item("Контакты моей компании")
Write-Host "Папка компании создана и выбрана" -ForegroundColor DarkRed }
$CompanyContFolder = $outlook.Application.CreateItem(2)
$CompanyContFolder.LastName = "Test_LastName"
$CompanyContFolder.Email1Address = "test@email.ru"
$CompanyContFolder.CompanyName = "Моя комания"
$CompanyContFolder.Department = "test_Department"
$CompanyContFolder.BusinessHomePage = "http://company.com/"
$CompanyContFolder.Mileage = "1"
#Сохраняем контакт
$CompanyContFolder.Save()
dosperados, попробуйте так:
$oOutlook = New-Object -ComObject Outlook.Application
$oNameSpace = $oOutlook.GetNamespace("MAPI")
$oMAPIFolder = $oNameSpace.GetDefaultFolder(10)
try {
$oMyMAPIFolder = $oMAPIFolder.Folders.Item("Контакты моей компании")
} catch {
$oMyMAPIFolder = $oMAPIFolder.Folders.Add("Контакты моей компании")
}
$oContact = $oMyMAPIFolder.Items.Add(2)
$oContact.LastName = "Test_LastName"
$oContact.Email1Address = "test@email.ru"
$oContact.CompanyName = "Моя комания"
$oContact.Department = "test_Department"
$oContact.BusinessHomePage = "http://company.com/"
$oContact.Mileage = "1"
$oContact.Save()
dosperados
09-09-2011, 06:58
Iska, Ты гений так легко и просто решил две мои проблемы! Огромное тебе, человеческое спасибо!
Iska, Можно ещё один глупый вопрос зачем буковка o в переменных $oContact, она что-то значит или просто для красоты?
dosperados
09-09-2011, 10:59
Iska, Будь добр подскажи ещё раз! По отдельности все что ты мне помогал работает, а вот когда совмещаю все в одно, то работает не совсем так как нужно... папку создает и в ней контакты тоже, но удалить из папки контакты не получается.
#Подключаемся к Outlook
$oOutlook = New-Object -ComObject Outlook.Application
$oNameSpace = $oOutlook.GetNamespace("MAPI")
#Получаем папку "Контакты"
$oMAPIFolder = $oNameSpace.GetDefaultFolder(10)
#Получаем папку контактов для удаления
$oContact = $oMyMAPIFolder.Items.Find("[Mileage] = ""1"" AND [BusinessHomePage] = ""http://company.com/""")
while ($oContact -ne $null) {
Write-Host $oContact.LastName $oContact.Email1Address $oContact.EntryID -ForegroundColor blue
$oContact.Delete()
$oContact = $oContact.FindNext()
}
зачем буковка o в переменных $oContact, она что-то значит или просто для красоты? »
С точки зрения PoSH — да, для красоты. Для меня — что эта переменная предназначена для хранения ссылки на объект.
работает не совсем так как нужно... папку создает и в ней контакты тоже, но удалить из папки контакты не получается. »
Где, в каком месте и что именно «не работает»?
И на что мне ориентироваться? На код в предыдущем посте или тот, что Вы прислали в личку? Определитесь.
dosperados
10-09-2011, 13:20
Не работает вот эта часть скрипта, когда контакты созданы в подпапке т.е. ("\\Outlook\Контакты\контакты компании") невозможно их удалить.
В этой части скрипта я пытался получить папку "контакты компании" и методом Find найти все содержимое и в цикле удалить каждый найденный элемент, но мне возвращается ошибка что метода FindNext() нет для данного объекта. и что я делаю неправильно я непойму...
#Получаем папку контактов для удаления
$oMAPIFolder = $oNameSpace.GetDefaultFolder(10).Items("контакты компании")
$oContact = $oMyMAPIFolder.Items.Find("[Mileage] = ""1"" AND [BusinessHomePage] = ""http://company.com/""")
while ($oContact -ne $null) {
Write-Host $oContact.LastName $oContact.Email1Address $oContact.EntryID -ForegroundColor blue
$oContact.Delete()
$oContact = $oContact.FindNext()
}
Удалить содержимое этой папки я пытался разными способами: Другой вариант удалить саму папку "контакты компании" такой вариант тоже мне подойдет... Ну или удалять содержимое этой папки по фильтрам. Но ни так у меня не получается.
Спасибо, теперь ясно. Посмотрим.
Смотрите, как это работает в целом:
$oOutlook = New-Object -ComObject Outlook.Application
$oNameSpace = $oOutlook.GetNamespace("MAPI")
$oMAPIFolder = $oNameSpace.GetDefaultFolder(10)
# Подключаемся или создаём папку «Контакты моей компании»
try {
$oMyMAPIFolder = $oMAPIFolder.Folders.Item("Контакты моей компании")
} catch {
$oMyMAPIFolder = $oMAPIFolder.Folders.Add("Контакты моей компании")
}
$cContacts = $oMyMAPIFolder.Items
# Добавляем Контакт №1
$oContact = $cContacts.Add(2)
$oContact.LastName = "Test_LastName"
$oContact.Email1Address = "test@email.ru"
$oContact.CompanyName = "Моя компания"
$oContact.Department = "test_Department"
$oContact.BusinessHomePage = "http://company.com/"
$oContact.Mileage = "1"
$oContact.Save()
# Добавляем Контакт №2
$oContact = $cContacts.Add(2)
$oContact.LastName = "Test_LastName2"
$oContact.Email1Address = "test2@email.ru"
$oContact.CompanyName = "Моя компания"
$oContact.Department = "test_Department"
$oContact.BusinessHomePage = "http://company.com/"
$oContact.Mileage = "1"
$oContact.Save()
# Добавляем Контакт №3
$oContact = $cContacts.Add(2)
$oContact.LastName = "Test_LastName3"
$oContact.Email1Address = "test3@email.ru"
$oContact.CompanyName = "Не моя компания"
$oContact.Department = ""
$oContact.BusinessHomePage = "http://non-my-company.com/"
$oContact.Mileage = "1"
$oContact.Save()
# Перечисляем все контакты из папки «Контакты моей компании»
$cContacts | ForEach-Object -process {
Write-Host $oContact.LastName $oContact.Email1Address $oContact.EntryID -ForegroundColor Blue
}
# Удаляем контакты из папки «Контакты моей компании»
$oContact = $cContacts.Find("[Mileage] = ""1"" AND [BusinessHomePage] = ""http://company.com/""")
while ($oContact -ne $null) {
Write-Host $oContact.LastName $oContact.Email1Address $oContact.EntryID -ForegroundColor Red
$oContact.Delete()
$oContact = $cContacts.FindNext()
}
dosperados
13-09-2011, 07:40
Iska, Ты крут! так работает... подскажи книжки по PS чтобы поизучать, желательно рускоязычные) Ещё раз хочу выразить тебе свою огромную презнательность!!! Спасибо за помощь!!!
Iska, Ты крут! »
Нет. Я сам неспешно учусь этому языку.
подскажи книжки по PS чтобы поизучать, желательно рускоязычные »
Windows PowerShell: Коллекция ссылок (http://forum.script-coding.com/viewtopic.php?id=35). Там есть и про книги. На русском мало. Читайте русскоязычные блоги Гусева, Сотникова и других специалистов.
Бетке Сергей Сергеев
26-10-2012, 23:29
Накидал модуль для PowerShell - ITG.Outlook. Пока в нём только обработку контактов и реализовал. Примеры кода с применением модуля привёл у себя в блоге - http://sergey-s-betke.blogs.novgaro.ru/scripts/ps/create-outlook-contacts-from-csv-or-ad.
Пример кода:
Get-ADUser `
-Filter * `
-SearchBase $OU `
-SearchScope Subtree `
-Properties `
displayName, givenName, sn, initials, title, userPrincipalName, info, `
manager, `
company, department, `
co, countryCode, postalCode, st, l, streetAddress, `
telephoneNumber, facsimileTelephoneNumber, homePhone, ipPhone, mobile, otherTelephone, wWWHomePage, mail `
| New-OutlookContact -Force -PassThru `
| Select-Object Subject, EMail1DisplayName, EMail1Address `
| Out-GridView `
;
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.