Kontakte automatisch via Powershell generieren anstatt von Hand verschieben

Ein Mitarbeiter musste immer wieder Kontakte von Hand aus dem Active Directory auslesen und in einem speziellen Postfach einfügen. Dies hat Stundenweise Arbeit beansprucht. Da wir kurzfristig keine Möglichkeit hatten, dies via Exchange zu erledigen, schrieb ich kurzerhand folgendes Skript, welches AD Kontakte ausliest, filtert und danach via EWS (http) in einem speziellen Postfach einfügt. Dieses Postfach kann in den Variablen des Skripts ganz einfach geändert werden.

Seither läuft das Skript täglich, und aktualisiert das Kontaktepostfach der Smartphones automatisch mit den neusten Mitarbeiterdaten. Sollte es fehlschlagen, schickt es eine E-Mail ab.

Das Skript


#----------------------------------------------------------------------------------------------------------------------------------------#
#
# Script by Kim,Internet & MSDN
# V1.0 - 18.06.2014 - by [email protected]
#
# Schritt 1:  - Variablen unten anpassen
# Schritt 2:  - Powershell öffnen und folgendes ausführen: set-executionpolicy remotesigned
#             - Die Änderung bestätigen
# Schritt 3:  - Dieses Script in der Powershell ("als Administratorausführen") ausführen
#
# Weiteres:   - Benötigt: EWS Management API Bibliothek benötigt http://www.microsoft.com/en-us/download/details.aspx?id=35371
#              - Benötigt: Active Directory Modul
#             - Benötigt: Powershell 3 um fehlerfrei zu laufen
#
# Neuerungen: -
#
#----------------------------------------------------------------------------------------------------------------------------------------#
$mailbox = "*****@company.com"
$username = "***@domain.local"
$password = "*******"
$ids = @()

# Laden der EWS Managed API-DLL in den Prozessraum http://www.microsoft.com/en-us/download/details.aspx?id=35371
try
{
    [void][Reflection.Assembly]::LoadFile("C:\ProgramFiles\Microsoft\Exchange\WebServices\2.0\Microsoft.Exchange.WebServices.dll")
}
catch
{
    Write-Host "=> EWS Management API DLL fehlt. Bitte installiere http://www.microsoft.com/en-us/download/details.aspx?id=35371" -ForegroundColor 'Red'
    break
}

#Importieren des Active Directory Moduls für Powershell
Import-Module ActiveDirectory

$mailBox = "[email protected]"
#$CSVContacts = @("First Name","Last Name","Company","Job Title","BusinessStreet","Business City","Business Postal Code","BusinessCountry/Region","Business Phone")
#$CSVExportPath = "test.csv"
#$CSVDelimiter = "    "
#$CSVFormat = "unicode"
$OUFilter = $("domain.local/company/x_*","domain.local/company/Ressource*")
$DisplayNameFilter = $("_*","service pc")
$NameFilter = "_a_*"
$PhoneFilter = $null
$ADUsers = @()
$OldOutlookContacts = @()
$count = 0

Write-Host "*WARNUNG*. Dieses Skript benötigt das Powershell ActiveDirectory Modul und ein installiertes Outlook." -ForegroundColor 'Red'
Write-Output "+ Auslesen der Kontakte aus AD gestartet"

try
{
$ADUsers = Get-ADUser -Filter{ObjectCategory -eq "Person" -and objectClass -eq "user" -and Enabled -eq $true} -Properties DisplayName,EmailAddress,Company,extensionAttribute1,facsimileTelephoneNumber,givenName,initials,ipPhone,l,mailNickname,name,pager,postalCode,sn,streetAddress,telephoneNumber,title,userPrincipalName,Canonicalname |
Select-object DisplayName,EmailAddress,Company,extensionAttribute1,facsimileTelephoneNumber,givenName,initials,ipPhone,l,mailNickname,name,pager,postalCode,sn,streetAddress,telephoneNumber,title,userPrincipalName,Canonicalname|
    Where {
        $_.Canonicalname -notlike $OUFilter[0] -and
        $_.Canonicalname -notlike $OUFilter[1] -and
        $_.DisplayName -notlike $DisplayNameFilter[0] -and
        $_.DisplayName -notlike $DisplayNameFilter[1] -and
        $_.Name -notlike $NameFilter -and
        $_.extensionAttribute1 -ne $PhoneFilter
    }

    #$ADUsers | export-csv $CSVExportPath -Encoding $CSVFormat -notypeinformation -Delimiter $CSVDelimiter
}
catch
{
    Write-Host "=> Konnte Kontacte nicht vom Active Directory laden. Bitteüberprüfe die Verbindung. Wurde das Active-Directory Modul korrektgeladen?"  -ForegroundColor 'Red'
    break
}
Write-Output "+ Auslesen fertiggestellt. Es wurden $($ADUsers.Count) User ausgelesen"


Write-Output "+ Verbinde mit EWS"
# ews-Klasse instanzieren
# Wenn Sie auf Exchange 2007 zugreifen, müssen Sie dies mit angeben

#$ews = new-object Microsoft.Exchange.WebServices.Data.ExchangeService
try
{
    $ews = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2)
}
catch
{
    Write-Host "=> Konnte Objekt nicht erstellenMicrosoft.Exchange.WebServices.Data.ExchangeService. API funktioniertnicht"  -ForegroundColor 'Red'
    break
}

# Dann müssen Sie die EWS-Url angeben oder per Autodicsover anhand der Mailadresse ermitteln lassen.

try
{
    # Ermitteln mit Mailadresse
    $ews.AutodiscoverUrl($mailbox)
}
catch
{
    Write-Host "=> Kein Zugang zur Autodiscover URL mit User $mailbox" -ForegroundColor 'Red'
    break
}


# alternativ: Aktuellen User verwenden
#$windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
#$sidbind = "LDAP://"
#[adsi]$aceuser = [ADSI]$sidbind
#$ews.AutodiscoverUrl($aceuser.mail.ToString())

# Alternativ URL fest vorgeben
$ews.Url = [system.URI]"https://mail.companydomain.ch/ews/exchange.asmx"

Write-Output "+ Melde mich als $username am Exchange an"
# Mit anderen Benutzerdaten anmelden
try
{
    $creds = New-Object System.Net.NetworkCredential($username,$password)
    $ews.Credentials = $creds
}
catch
{
    Write-Host "=> Konnte nicht am EWS anmelden"  -ForegroundColor 'Red'
    break
}
#$ews.ImpersonatedUserId = New-Object
Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $mailbox);

Write-Output "+ Erstelle Bindung an Exchange Kontakte"
$ContactsFolderid  = new-object
Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Contacts,$_)
$view = New-Object Microsoft.Exchange.WebServices.Data.ItemView(1000)
$findResults = $ews.FindItems($ContactsFolderid,$view)


Write-Output "+ Lösche vorhandene Kontakte"
try
{
    if($findResults)
    {
        foreach($contact in  $findResults)
        {
            #$ids = $contact.Id
            $contact.Delete("MoveToDeletedItems")
            " $($contact.DisplayName) wurde gelöscht"
        }
    }
}
catch
{
    Write-Host "=> Fehler beim Löschen der Kontakte aus dem Exchange Postfach $username"  -ForegroundColor 'Red'
    break
}

Write-Output "+ Erstelle Kontakte und lese Sie in Exchange ein"
try
{
    foreach($user in $ADUsers)
    {
        Write-Output "Erstelle Kontakt: $($user.userPrincipalName)"
        $newContact = new-object Microsoft.Exchange.WebServices.Data.Contact($ews)
        $newContact.GivenName = $user.givenName
        $newContact.Surname = $user.sn;
        $newContact.DisplayName = $user.DisplayName
        $newContact.EmailAddresses["EmailAddress1"] = $user.EmailAddress
        $newContact.JobTitle = $user.title
        $newContact.CompanyName = $user.company

        #[Addressen]
        $objNewPhysicalAddress1 = new-object Microsoft.Exchange.WebServices.Data.PhysicalAddressEntry
        $objNewPhysicalAddress1.Street          = $user.streetAddress
        $objNewPhysicalAddress1.City            = $user.l
        $objNewPhysicalAddress1.State           = ""
        $objNewPhysicalAddress1.PostalCode      = $user.postalCode
        $objNewPhysicalAddress1.CountryOrRegion = "Schweiz"

        #[enum]::getvalues([Microsoft.Exchange.WebServices.Data.PhysicalAddressKey])
        $enumBusinessValue = [Microsoft.Exchange.WebServices.Data.PhysicalAddressKey]::Business
        #$enumHomevalue     = [Microsoft.Exchange.WebServices.Data.PhysicalAddressKey]::Home
        #$enumOtherValue    = [Microsoft.Exchange.WebServices.Data.PhysicalAddressKey]::Other

        $newContact.PhysicalAddresses[$enumBusinessValue] = $objNewPhysicalAddress1

        #[TELEFON]
        #[enum]::getvalues([Microsoft.Exchange.WebServices.Data.PhoneNumberKey])
        $enumPhoneHomeValue        = [Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::HomePhone
        $enumPhoneMobileValue      = [Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::MobilePhone
        $enumPhoneBusinessValue    = [Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::BusinessPhone
        $enumPhoneBusiness2Value   = [Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::BusinessPhone2
        $enumPhoneCompanyMainValue = [Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::CompanyMainPhone
        $enumPhoneBusinessFaxValue = [Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::BusinessFax

        $newContact.PhoneNumbers[$enumPhoneBusinessFaxValue] = $user.pager
        $newContact.PhoneNumbers[$enumPhoneBusinessValue] = $user.ipPhone
        $newContact.PhoneNumbers[$enumPhoneBusiness2Value] = $user.extensionAttribute1

        #$newContact.Notes = $user.userPrincipalName

        $newContact.Save($ContactsFolderid)
    }
}
catch
{
    Write-Host "=> Problem beim einlesen der Kontakte ins Exchange Postfach:
$username"  -ForegroundColor 'Red'
    break
}
Write-Output "+ Task fertig gestellt"
Hilfe benötigt? Günstigen Support gibts bei www.fixthis.ch