Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] PS: Синхронизация контактов Outlook`a с AD (http://forum.oszone.net/showthread.php?t=214936)

dosperados 06-09-2011 11:36 1747193

PS: Синхронизация контактов Outlook`a с AD
 
Пишу скрипт по синхронизации Email адресов, которые хранятся в АД и контактов в Outlook`е.
Смысл в том, что скрипт по добавлению Email адресов из АД в Outlook уже есть он описан на форуме тут
Но при каждом запуске скрипта в Outlook`e появляются дубликаты одних и тех же записей.
Я хочу написать скриптик который бы делал вот что:
1) При импорте проверял бы есть такой контакт в Outlook`e, если есть то повторно не импортировать, если же нету то импортировался но с дополнительным полем которое бы указывало на то, что этот объект импортирован из АД
2) Потом бы проверялись контакты в Outlook`e если контакт имеет поле импортирован то такойже объект ищется в АД если его там нету то этот контакт удаляется из Outlook`а, если же контакт создал сам пользователь и у него нету поля которое показывает что он создан при импорте то этот контакт остается без изменения.

так вот я не знаю как правильно реализовать то что я хочу и я пошел обходным путем (если кто знает как сделать правильней и лучше подскажите!!!):
Я сначала удаляю контакты из Outlook`а в которых присутствуют поля означающие что этот контакт импортирован (у меня за это отвечает два поля $_.Mileage и $_.BusinessHomePage) контакты созданные пользователем не трогаем. Потом необходимо проделать импорт из АД в Outlook с полями означающими импорт.

так вот у меня неправильно работает удаление контактов с полем означающим импорт.
я делаю это так:
PHP код:

#Подключаемся к 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 1747736

Что-то ни кто даже слово не напишет) что все боятся запустить у себя этот скрипт!? Он ничего не удалит если не будет в контакте особых полей ($_.Mileage и $_.BusinessHomePage) с нужными значениями. только если два этих поля удовлетворили условию тогда этот контакт удалиться...

Мне нужен совет гуру, почему при тесте без использования $_.delete() все работает как положено, а с ним неправильно!!!
Ну или вообще как подругому сделать)

Iska 07-09-2011 08:37 1747765

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 1748255

Iska, Спасибо твой метод работает как положенно, но кто знает как реализовать мою задумку не через попу как сейчас, а правильно!?

dosperados 08-09-2011 11:26 1748661

Такой вопрос: я создаю в папке "\\Outlook\Контакты" подпапку "Контакты моей компании" саму папку я успешно создаю, но если начинаешь создавать контакты в ней, они сохраняется в папке "Контакты", а мне надо чтобы он сохранился в подпапке "Контакты моей компании".
Кто решал такую проблему подскажите...
PHP код:

#Подключаемся к 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() 


Iska 08-09-2011 23:44 1749275

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 1749348

Iska, Ты гений так легко и просто решил две мои проблемы! Огромное тебе, человеческое спасибо!

Iska, Можно ещё один глупый вопрос зачем буковка o в переменных $oContact, она что-то значит или просто для красоты?

dosperados 09-09-2011 10:59 1749464

Iska, Будь добр подскажи ещё раз! По отдельности все что ты мне помогал работает, а вот когда совмещаю все в одно, то работает не совсем так как нужно... папку создает и в ней контакты тоже, но удалить из папки контакты не получается.
PHP код:

#Подключаемся к 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()
                            } 


Iska 10-09-2011 00:11 1750009

Цитата:

Цитата dosperados
зачем буковка o в переменных $oContact, она что-то значит или просто для красоты? »

С точки зрения PoSH — да, для красоты. Для меня — что эта переменная предназначена для хранения ссылки на объект.

Цитата:

Цитата dosperados
работает не совсем так как нужно... папку создает и в ней контакты тоже, но удалить из папки контакты не получается. »

Где, в каком месте и что именно «не работает»?

И на что мне ориентироваться? На код в предыдущем посте или тот, что Вы прислали в личку? Определитесь.

dosperados 10-09-2011 13:20 1750224

Не работает вот эта часть скрипта, когда контакты созданы в подпапке т.е. ("\\Outlook\Контакты\контакты компании") невозможно их удалить.
В этой части скрипта я пытался получить папку "контакты компании" и методом Find найти все содержимое и в цикле удалить каждый найденный элемент, но мне возвращается ошибка что метода FindNext() нет для данного объекта. и что я делаю неправильно я непойму...
PHP код:

#Получаем папку контактов для удаления 
$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() 
                            } 

Удалить содержимое этой папки я пытался разными способами: Другой вариант удалить саму папку "контакты компании" такой вариант тоже мне подойдет... Ну или удалять содержимое этой папки по фильтрам. Но ни так у меня не получается.

Iska 10-09-2011 13:59 1750249

Спасибо, теперь ясно. Посмотрим.

Iska 13-09-2011 02:59 1751853

Смотрите, как это работает в целом:
Код:

$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 1751876

Iska, Ты крут! так работает... подскажи книжки по PS чтобы поизучать, желательно рускоязычные) Ещё раз хочу выразить тебе свою огромную презнательность!!! Спасибо за помощь!!!

Iska 13-09-2011 15:06 1752085

Цитата:

Цитата dosperados
Iska, Ты крут! »

Нет. Я сам неспешно учусь этому языку.


Цитата:

Цитата dosperados
подскажи книжки по PS чтобы поизучать, желательно рускоязычные »

Windows PowerShell: Коллекция ссылок. Там есть и про книги. На русском мало. Читайте русскоязычные блоги Гусева, Сотникова и других специалистов.

Бетке Сергей Сергеев 26-10-2012 23:29 2013014

Накидал модуль для PowerShell - ITG.Outlook. Пока в нём только обработку контактов и реализовал. Примеры кода с применением модуля привёл у себя в блоге - http://sergey-s-betke.blogs.novgaro....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 `
;



Время: 07:55.

Время: 07:55.
© OSzone.net 2001-