Quantcast
Channel: Windows PowerShell Forum
Viewing all articles
Browse latest Browse all 2314

Script zum auslesen einer ActiveSync Gruppe und erstellen von entsprechenden Kontakten

$
0
0

Hallo,

ich habe ein Script, welches mir alle meine Kontakte aus einer Gruppe ausliest und diese dann per ActiveSync, die ganzen Kontake hinzufügen lässt. Leider läuft dieses  nicht gerade performant. Es dauert länger als 4 Stunden bis dieses einmal komplett durchlaufen wird. Und das obwohl es sich hier nur um ca. 350 Kontakte handelt. 

Habt ihr hier irgendwelche Verbesserungen, um das Script schneller zu gestalten? Evtl. Abfragen an bestimmten Stellen etc.

Extrem lange braucht das Script beim durchlaufen der Kontakte an dieser Stelle:

 immer nur Maximal 50 Elemete aus dem Kontakordner holen
# maximale Anzahl die eine Itemsuche zurückliefern soll
$ItemPageSize = 50
 
# wenn weniger als 50 Elemente vorhanden sind, dann wird die Anzahl
# auf die Elemente im Kontakordner reduziert
If($ContacsFolder.TotalCount -lt 50) {
    $ItemPageSize = $ContacsFolder.TotalCount
}
 
# Startpunkt der Itemsuche
$ItemOffset = 0
 
# Schleife um Elemente aus dem Kontaktordner zu holen beginnen
Do {
    
    # Den Item-View einrichten um einen beschränkte Anzahl an Items zu holen
    $itemView = New-Object Microsoft.Exchang

System: Exchange 2010 SP3

param([string]$Group="ActiveSync",[string]$FolderName="Kontakte",$AddContact=0,$LogPath="C:\log");
#
# Parameters
#  -Group: Group to sync Contacts
#  -FolderName: FolderName displayed in Outlook
#  -GroupDelete: Group to delete Contacts
#  

###################################
# Function to write Logfile
###################################
function Write-Log ($Inhalt)
{
    $DateNow = Get-Date -Format "dd.MM.yyyy HH:mm:ss" # Ermittelt das aktuelle Datum mit diesem Syntax 01.10.2013 10:00
    $date = Get-Date -Format "yyyy-MM-dd"
    $Logfile = "$LogPath\$date.log"
    $FileExists = Test-Path $LogFile
    $FileInp = $DateNow + ' | ' + $Inhalt                          # Setzt die Zeile für unser Logfile zusammen
    If ($FileExists -eq $True){ # Wenn dir Datei existiert reinschreiben
        Add-Content $LogFile -value $FileInp  # Zeile hinten an die vorhanden Einträge anhängen
    } else {
       New-Item $Logfile -type file # Wenn dir Datei nicht existiert anlegen
       Add-Content $LogFile -value $FileInp # und reinschreiben
    }
}


Import-Module ActiveDirectory
add-pssnapin Microsoft.Exchange.Management.PowerShell.E2010

$EwsUrl = ([array](Get-WebServicesVirtualDirectory))[0].InternalURL.AbsoluteURI

$ContactMapping=@{
    "FirstName" = "GivenName";"LastName" = "Surname";"Company" = "CompanyName";"Department" = "Department";"Title" = "JobTitle";"WindowsEmailAddress" = "Email:EmailAddress1";"Phone" = "Phone:BusinessPhone";"MobilePhone" = "Phone:MobilePhone";"HomePhone" = "Phone:HomePhone";"Fax" = "Phone:BusinessFax";
}
# Alle Benutzer aus einer Gruppe auslesen - Auswahl des Namen
$Mailboxes = Get-ADGroupMember $Group | select -ExpandProperty name
foreach($Mailbox in $Mailboxes)
{

    $UserMailbox  = Get-Mailbox $Mailbox -ErrorAction
    
    
    if (!$UserMailbox)
    {
    	#throw "Mailbox $($Mailbox) not found";
    	exit;
    }
    else 
    {
        Write-Log("Mailboxsync: $Mailbox")
    }

    $EmailAddress = $UserMailbox.PrimarySMTPAddress

    # Load EWS Managed API
    [void][Reflection.Assembly]::LoadFile("C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll");

    $service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP3)
    $service.UseDefaultCredentials = $true;
    $service.URL = New-Object Uri($EwsUrl);

    # Search for an existing copy of the Folder to store Org contacts 
    $service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $EmailAddress);
    $RootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot)
    $RootFolder.Load()

    $service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $EmailAddress);
    $FolderView = new-Object Microsoft.Exchange.WebServices.Data.FolderView(1000)
    $ContactsFolderSearch = $RootFolder.FindFolders($FolderView) | Where {$_.DisplayName -eq $FolderName}
    if ($ContactsFolderSearch)
    {
    	# Empty if found
    	$service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $EmailAddress);
    	$ContactsFolder = [Microsoft.Exchange.WebServices.Data.ContactsFolder]::Bind($service,$ContactsFolderSearch.Id);
    } 
    
    # Add contacts
    $Users = get-user -Filter {WindowsEmailAddress -ne $null -and (MobilePhone -ne $null -or Phone -ne $null) -and WindowsEmailAddress -ne $EmailAddress} 
    $Users = $Users | select DisplayName,FirstName,LastName,Title,Company,Department,WindowsEmailAddress,Phone,MobilePhone,HomePhone,Fax

    foreach ($ContactItem in $Users)
    {
        $service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $EmailAddress);       
        $ExchangeContact = New-Object Microsoft.Exchange.WebServices.Data.Contact($service);
        if ($ContactItem.FirstName -and $ContactItem.LastName)
        {
            $ExchangeContact.NickName = $ContactItem.FirstName + " " + $ContactItem.LastName;
        }
        elseif ($ContactItem.FirstName -and !$ContactItem.LastName)
        {
            $ExchangeContact.NickName = $ContactItem.FirstName;
        }
        elseif (!$ContactItem.FirstName -and $ContactItem.LastName)
        {
            $ExchangeContact.NickName = $ContactItem.LastName;
        }
    	elseif (!$ContactItem.FirstName -and !$ContactItem.LastName)
        {
            $ExchangeContact.NickName = $ContactItem.DisplayName;
    		$ContactItem.FirstName = $ContactItem.DisplayName;
        }
        $ExchangeContact.DisplayName = $ExchangeContact.NickName;
        $ExchangeContact.FileAs = $ExchangeContact.NickName;
        $ExchangeContact.CompanyName = $ContactItem.Company
        # This uses the Contact Mapping above to save coding each and every field, one by one. Instead we look for a mapping and perform an action on
        # what maps across. As some methods need more "code" a fake multi-dimensional array (seperated by :'s) is used where needed.
        foreach ($Key in $ContactMapping.Keys)
        {
            # Only do something if the key exists
            if ($ContactItem.$Key)
            {
                # Will this call a more complicated mapping?
                if ($ContactMapping[$Key] -like "*:*")
                {
                    # Make an array using the : to split items.
                    $MappingArray = $ContactMapping[$Key].Split(":")
                    # Do action
                    switch ($MappingArray[0])
                    {"Email"
                        {
    						$ExchangeContact.EmailAddresses[[Microsoft.Exchange.WebServices.Data.EmailAddressKey]::($MappingArray[1])] = $ContactItem.$Key.ToString();
                        }"Phone"
                        {
                            $ExchangeContact.PhoneNumbers[[Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::($MappingArray[1])] = $ContactItem.$Key;
                        }
                    }                
                } else {
                    $ExchangeContact.($ContactMapping[$Key]) = $ContactItem.$Key;            
                }
            }    
        }
           $ContacsFolder = [Microsoft.Exchange.WebServices.Data.ContactsFolder]::Bind($Service,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Contacts,(New-Object -TypeName 'Microsoft.Exchange.WebServices.Data.PropertySet' -ArgumentList ([Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly),([Microsoft.Exchange.WebServices.Data.FolderSchema]::TotalCount)))
# immer nur Maximal 50 Elemete aus dem Kontakordner holen
# maximale Anzahl die eine Itemsuche zurückliefern soll
$ItemPageSize = 50
 
# wenn weniger als 50 Elemente vorhanden sind, dann wird die Anzahl
# auf die Elemente im Kontakordner reduziert
If($ContacsFolder.TotalCount -lt 50) {
    $ItemPageSize = $ContacsFolder.TotalCount
}
 
# Startpunkt der Itemsuche
$ItemOffset = 0
 
# Schleife um Elemente aus dem Kontaktordner zu holen beginnen
Do {
    
    # Den Item-View einrichten um einen beschränkte Anzahl an Items zu holen
    $itemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView($ItemPageSize,$ItemOffset,[Microsoft.Exchange.WebServices.Data.OffsetBasePoint]::Beginning)
 
    # Die ItemView Suche mit Shallow, sucht alle nicht gelöschten Items
     $itemView.Traversal = [Microsoft.Exchange.WebServices.Data.ItemTraversal]::Shallow
 
     # um die zurückgelieferte Datenmenge zu reduzieren, fordern wir in dem ItemView nur den Vornamen, Nachnamen und die 3 E-mail felder an
     $itemView.PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.ContactSchema]::GivenName,
                        [Microsoft.Exchange.WebServices.Data.ContactSchema]::Surname,
                        [Microsoft.Exchange.WebServices.Data.ContactSchema]::EmailAddress1,
                        [Microsoft.Exchange.WebServices.Data.ContactSchema]::EmailAddress2,
                        [Microsoft.Exchange.WebServices.Data.ContactSchema]::EmailAddress3,
                        [Microsoft.Exchange.WebServices.Data.ContactSchema]::CompanyName,
                        [Microsoft.Exchange.WebServices.Data.ContactSchema]::BusinessPhone)
 
    # Elemente mit hilfe des itemViews in dem Postfach suchen lassen
    $FindItems = $service.FindItems([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Contacts,$itemView)
 
     # jedes Item gefundene Item Durchlaufen
     ForEach ($Item in $FindItems.Items) {
     
         # Der kontakt Ordner kann auch Elemente enthalten die keine Kontakt sind (z.B. Verteiler-Listen)!
         # Wir nutzen hier nur Kontakt Elemente!
         If ($Item -is [Microsoft.Exchange.WebServices.Data.Contact]) {
                        
        # Geprüft wird auf Vorname, Nachname und Firmenname        
        if ((($ContactItem.FirstName -eq $Item.SurName) -AND ($ContactItem.LastName -eq $Item.GivenName) -AND ($ContactItem.Company -eq $item.CompanyName)) -OR (($ContactItem.FirstName -eq $Item.GivenName) -AND ($ContactItem.LastName -eq $Item.SurName) -AND ($ContactItem.Company -eq $item.CompanyName)))
        {
        $DelItem = $Item
        #$DelItem.Surname, $DelItem.GivenName <#$DelItem.PhoneNumbers[[Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::BusinessPhone]#>
        [void]$DelItem.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete)
        }
         }
     }
    # Berechnen der des Offsets für die nächste suchschleife
    $ItemOffset += $ItemPageSize
# wenn noch restliche Elemente im Kontaktordner vorhanden sind.
# wird die Schleife wieder bei DO angefangen
} While ($FindItems.MoreAvailable)

        # Save the contact
        $ExchangeContact.Save($ContactsFolder.Id);
        # Provide output that can be used on the pipeline
        #$ExchangeContact.Surname, $ExchangeContact.GivenName, $ExchangeContact.EmailAddresses[[Microsoft.Exchange.WebServices.Data.EmailAddressKey]::EmailAddress1]         
        
    }
}




Viewing all articles
Browse latest Browse all 2314


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>