weltbesteritler
Goto Top

Öffentliche Kontakte auf jedes Smartphone kopieren

Hallo Superadministratoren,

ich bin ein langjähriger SAP Mitarbeiter, wurde leider versetzt und soll mich jetzt in einem Windows Umfeld einarbeiten.
Hier benutzen die doch tatsächlich veraltete Versionen in jeder Hinsicht. Der Email Server ist ein 2010er.
Ständig kommen irgendwelche Personen auf mich zu. Sie wollen den öffentlichen Ordner mit den Kontakten gern auf ihr Smartphone kopieren.
So ein Jungspund aus der IT Abteilung meinte zu mir, dass sich die User die öffentlichen Kontakte selbst in ihr persönliches Kontaktelaufwerk ziehen müssen, um die Kontakte auf den Smartphones zu sehen. Habe ihm gesagt, dass das nicht sein kann, und es eine Funktion gibt, mit der man das automatisch erledigen kann.

Wo finde ich diese Funktion oder gibt es ein Batchprogramm, das das automatisch abgleicht?

Grüße vom SAP Experten

Content-ID: 385651

Url: https://administrator.de/contentid/385651

Ausgedruckt am: 22.11.2024 um 07:11 Uhr

137084
137084 06.09.2018 um 13:25:22 Uhr
Goto Top
WeltbesterITler
WeltbesterITler 06.09.2018 aktualisiert um 13:41:42 Uhr
Goto Top
Liest sich verlockend, aber ich weiß nicht ob ich als alter Admin aus dem SAP Umfeld das hinbekomme.
Was ist PS denn für eine Programmiersprache ist das was neues?
137084
137084 06.09.2018 aktualisiert um 13:44:30 Uhr
Goto Top
Zitat von @WeltbesterITler:
Was ist PS denn für eine Programmiersprache ist das was neues?
face-big-smile Willst du uns verarschen? Das ist schon mind. ein jahrzehnt Windows-Standard.
https://de.wikipedia.org/wiki/PowerShell
WeltbesterITler
WeltbesterITler 06.09.2018 um 13:55:07 Uhr
Goto Top
Ich lerne sehr schnell-.
Hast du das Script selbst auch im Einsatz`?
Pjordorf
Pjordorf 06.09.2018 aktualisiert um 14:03:55 Uhr
Goto Top
Hallo,

Zitat von @WeltbesterITler:
ich bin ein langjähriger SAP Mitarbeiter, wurde leider versetzt und soll mich jetzt in einem Windows Umfeld einarbeiten.
Und SAP läuft nicht auf Windows oder hat SAP ein eigenes OS?

Hier benutzen die doch tatsächlich veraltete Versionen in jeder Hinsicht. Der Email Server ist ein 2010er.
Ist zwar etwas älter aber immer noch gültig. https://blogs.msdn.microsoft.com/deva/2015/01/14/microsoft-support-lifec ...

Ständig kommen irgendwelche Personen auf mich zu. Sie wollen den öffentlichen Ordner mit den Kontakten gern auf ihr Smartphone kopieren.
Ja, das ist so, denn Öffentliche Kontakte werden nicht Synchronisiert, und ein Outlook ist ein OIM - Personal Information Manager

So ein Jungspund aus der IT Abteilung meinte zu mir, dass sich die User die öffentlichen Kontakte selbst in ihr persönliches Kontaktelaufwerk ziehen müssen, um die Kontakte auf den Smartphones zu sehen.
Hat der Jungspund recht.

Habe ihm gesagt, dass das nicht sein kann, und es eine Funktion gibt, mit der man das automatisch erledigen kann.
MS hat keine Funktion dazu eingebaut, es geht nur über lokales kopieren oder halt drittanbieter Software kaufen und einsetzten.

Wo finde ich diese Funktion oder gibt es ein Batchprogramm, das das automatisch abgleicht?
Es gibt keine eingebaute Funktion. Und sicherlich gibt es Batch programme die dies kann (Öffentliche Kontakte in Persönliche Kontakte kopieren und umgekehrt, aber ob dir jemand diese Batchdateien zur Verfügung stellt ist eher fraglich. SAP hat auch nichts verschenkt oder der Öffentlichkeit einfach so zur Verfügung gestellt. Hat dort alles geld gekostet.

z.B.https://www.gangl.de/product/folderreplication-agent.html

Was ist PS denn für eine Programmiersprache ist das was neues
Das gibt es schon zu Server 2003 zeiten und nennt sich Powershell. Ist die ablösung / nachfolger / alternative zu Batch *.bat *.cmd https://en.wikipedia.org/wiki/PowerShell
https://commandwindows.com/powershell.htm

Gruß von einen nicht SAP Experten,
Peter
WeltbesterITler
WeltbesterITler 06.09.2018 um 14:04:08 Uhr
Goto Top
Hallo Peter,

ein gewisser Herr namens Uwe Collinardo hat dieses Script der breiten Öffentlichkeit zur Verfügung gestellt:

<#
    Sync AD-Users to Contact-Folder in all Mailboxes  EX2010  / (c) @colinardo

   Vor dem Start des Skript ist dem User welcher das Skript später ausführt die Impersonation-Berechtigungzu erteilen:
   In diesem Beispiel der User 'Administrator' (Bitte einmalig in einer EMS ausführen)  

    New-ManagementRoleAssignment -Name:impersonationAssignmentName -Role:ApplicationImpersonation -User:Administrator
#>

if ($PSVersionTable.PSVersion.Major -lt 3){write-host "ERROR: Minimum Powershell Version 3.0 is required!" -F Yellow; return}    

# Active Directory Modul laden
Import-Module ActiveDirectory

# EWS DLL laden
Add-Type -Path "$(Split-Path $MyInvocation.MyCommand.Definition -Parent)\Microsoft.Exchange.WebServices.dll"  

# Mit Exchange verbinden
try{
    $exchange_server = Get-ADObject -LDAPFilter 'objectClass=msExchExchangeServer' -SearchBase (([ADSI]"LDAP://RootDse").configurationNamingContext.ToString()) -Properties networkaddress | select -Expand networkaddress | ?{$_ -match 'ncacn_ip_tcp'} | %{$_.split(":")[1]} | select -First 1  
    if (!$exchange_server){Write-Host "Could not determine Exchange-Server FQDN from AD" -ForegroundColor Red; return}  
    write-host "Creating connection to Exchange-Server '$exchange_server' ..." -ForegroundColor Green  
    $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "http://$exchange_server/powershell" -Authentication Kerberos  
    Import-PSSession $session -DisableNameChecking -AllowClobber | out-null
}catch{
    throw $_
    return
}

# Start Variablen -------------------------------------------------------------------------
# Name des Ordners in dem die Kontake angelegt werden
$foldername = "Firmenkontakte"  
# Überordner festlegen
$parentFolder = [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Contacts
# Ende Variablen -------------------------------------------------------------------------

# Custom Propertyset erstellen um einen Kontakt eindeutig zu identifizieren
$propid = [GUID]'{05591a58-e392-4aa9-8cbd-06627d605c95}'  
$propset = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition($propid,'ObjectSID',[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String)  

# EWS Objekt erstellen
$ews = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2)
$ews.Url = [string](Get-WebServicesVirtualDirectory).InternalURL
# Benutze die Credentials mit dem das Skript ausgeführt wird
$ews.UseDefaultCredentials = $true

# Eigenschaft der User welche abgerufen werden
$user_properties =  @('DisplayName','EmailAddress','Company','facsimileTelephoneNumber','givenName','initials','l','mailNickname','name','pager','postalCode','sn','streetAddress','telephoneNumber','HomePhone','MobilePhone','title','co','State','Department','Office','wwwHomePage','Manager')  

# Aktivierte Benutzer abrufen welche als Kontake in den Mailboxen angelegt werden
$users = Get-ADUser -Filter{ObjectCategory -eq "Person" -and objectClass -eq "user" -and Enabled -eq $true} -Properties $user_properties  

# Funktion zum Prüfen von Eigenschaften
function Get-PropValue($prop){return @{$true=$prop;$false=$null}[$prop -ne ""]}  

# Für alle aktivierten Usermailboxen ausführen
Get-Mailbox -RecipientTypeDetails UserMailbox -Filter "IsMailBoxEnabled -eq 'True'" | %{  
    write-host "Updating Mailbox '$($_.Name)'." -ForegroundColor Blue -BackgroundColor White  
    $ews.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, [string]$_.PrimarySmtpAddress)
    # Nach dem Ordner "Firmenkontakte" im Default Kontakte-Ordner suchen  
    $view = New-Object Microsoft.Exchange.WebServices.Data.FolderView(1)
    $view.PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly,[Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName)
    $view.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Shallow
    $filter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,$foldername)
    $result = $ews.FindFolders($parentFolder,$filter,$view)
    
    if ($result.TotalCount){
        # Ordner wurde gefunden
        $targetFolder = $result.Folders
    }else{
        # Ordner existiert noch nicht, lege ihn an
        write-host "Creating the contact folder '$foldername' in Mailbox." -ForegroundColor Green  
        $targetFolder = New-Object Microsoft.Exchange.WebServices.Data.ContactsFolder($ews)
        $targetFolder.DisplayName = $foldername
        $targetFolder.Save($parentFolder)
    }
    
    # Items im Ordner auflisten
    $view = New-Object Microsoft.Exchange.WebServices.Data.ItemView(10000)
    $view.PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly,[Microsoft.Exchange.WebServices.Data.ContactSchema]::DisplayName,$propset)
    $result = $ews.FindItems($targetFolder.Id,$view)

    $targetSIDs =  $result | %{$_.ExtendedProperties | ?{$_.PropertyDefinition.PropertySetId -eq $propid} | select -Expand Value}

    # überschüssige Kontakte die vom User dort angelegt wurden im Ordner löschen
    $result | ?{$_.ExtendedProperties.Value -notin $users.SID -or $_.ExtendedProperties.Count -eq 0 } | %{
        write-host "Removing abandoned contact '$($_.DisplayName)' in '$foldername.'" -ForegroundColor Yellow  
        $_.Delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete)
    }
    
    # Vorhandene Kontakte aktualisieren und neue erstellen
    foreach ($user in $users){
        if ($user.SID -in $targetSIDs){
            $isupdate = $true
            $contact = $result | ?{($_.ExtendedProperties | ?{$_.PropertyDefinition.PropertySetId -eq $propid}).Value -eq $user.SID}
            write-host "Updating contact '$($user.Name)'." -ForegroundColor Green  
        }else{
            $isupdate = $false
            $contact = new-object Microsoft.Exchange.WebServices.Data.Contact($ews)
            write-host "Creating new contact '$($user.Name)'." -ForegroundColor Green  
        }

        $contact.GivenName = Get-PropValue $user.GivenName
        $contact.Surname = Get-PropValue $user.sn
        $contact.Initials = Get-PropValue $user.Initials
        $contact.DisplayName = Get-PropValue $user.DisplayName
        $contact.CompanyName = Get-PropValue $user.Company
        $contact.OfficeLocation = Get-PropValue $user.Office
        $contact.Department = Get-PropValue $user.Department
        $contact.JobTitle = Get-PropValue $user.Title
        $contact.BusinessHomePage = Get-PropValue $user.wwwHomePage
        $contact.Manager = Get-PropValue $user.Manager

        $contact.PhoneNumbers[[Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::HomePhone] = Get-PropValue $user.HomePhone
        $contact.PhoneNumbers[[Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::BusinessPhone] = Get-PropValue $user.telephoneNumber
        $contact.PhoneNumbers[[Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::MobilePhone] = Get-PropValue $user.MobilePhone
        $contact.PhoneNumbers[[Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::Pager] = Get-PropValue $user.Pager
        $contact.PhoneNumbers[[Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::BusinessFax] = Get-PropValue $user.facsimileTelephoneNumber
        
        $privateAddress = New-Object Microsoft.Exchange.WebServices.Data.PhysicalAddressEntry
        $privateAddress.Street = Get-PropValue $user.streetAddress
        $privateAddress.City = Get-PropValue $user.l
        $privateAddress.PostalCode = Get-PropValue $user.postalCode
        $privateAddress.State = Get-PropValue $user.State
        $privateAddress.CountryOrRegion = Get-PropValue $user.co
        $contact.PhysicalAddresses[[Microsoft.Exchange.WebServices.Data.PhysicalAddressKey]::Home] = $privateAddress
        $contact.PostalAddressIndex = [Microsoft.Exchange.WebServices.Data.PhysicalAddressIndex]::Home

        $contact.EmailAddresses['EMailAddress1'] = Get-PropValue $user.EMailAddress  
        $contact.FileAsMapping = [Microsoft.Exchange.WebServices.Data.FileAsMapping]::SurnameCommaGivenName

        if ($isupdate){
            $contact.Update([Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverwrite)
        }else{
            # Schreibe die SID des Users in die custom extended property des Kontakts (Dient zur eindeutigen Identifikation des Kontakts)
            $contact.SetExtendedProperty($propset,[string]$user.SID)
            $contact.Save($targetFolder.id)
        }
    }
}

# Exchange Session beenden
Remove-PSSession $session

Um z.B. dem User 'Administrator' dieses Recht zu erteilen führt man folgenden Befehl in einer EMS aus

New-ManagementRoleAssignment -Name:impersonationAssignmentName -Role:ApplicationImpersonation -User:Administrator
--> das hab ich gerade gemacht
Kriegt jetzt der lokale Admin oder der Domänenadministrator dieses Recht?

Benötigt wird für das Script ebenfalls die Microsoft.Exchange.WebServices.dll die Ihr euch ja bei MS herunterladen könnt. Für das folgende Script ist diese DLL in das Verzeichnis des Scripts zu kopieren, außer man passt den Pfad im Skript an.

--> das habe ich auch bereits abgearbeitet

Müssen in dem Script weitere Anpassungen vorgenommen werden oder kann man es einfach starten?`

PS: Support für den Exchange 2010 bis 14.1.2020, das geht dann noch face-smile
beschlagfuchs
beschlagfuchs 06.09.2018 um 14:13:47 Uhr
Goto Top
Irgendwie amüsant das dich jemand an so einem Zeug herumschrauben lässt, obwohl du noch "eingelernt" wirst und wahrscheinlich so wie man es heraushören kann, überhaupt kein Bock hast.
WeltbesterITler
WeltbesterITler 06.09.2018 um 14:24:24 Uhr
Goto Top
Habe mich geweigert SAP ohne monatelange Tests auf SAP Fiori umzustellen und schon wurde ich versetzt.
Pjordorf
Pjordorf 06.09.2018 um 14:29:30 Uhr
Goto Top
Hallo,

Zitat von @WeltbesterITler:
Habe mich geweigert SAP ohne monatelange Tests auf SAP Fiori umzustellen und schon wurde ich versetzt.
Ist doch nur ne neue GUI...
How SAP Fiori was born?

When a research was conducted, it was found that most of the SAP users use SAP User Interface to access the applications. These included common applications related to Manager-employee interactions such as leave request, travel request, etc. These GUI had more than 300,000 screens with various functions in it. SAP checked the most frequently used application and then decided to renew these applications. This is how SAP Fiori was born.
Gruß,
Peter
WeltbesterITler
WeltbesterITler 06.09.2018 um 16:24:23 Uhr
Goto Top
Andere GUI ok. Aber in jedem Browser ein anderer Fehler, Darstellung ...

Wer kann denn jetzt eig helfen, was ich an dem Script noch anpassen muss?
Pjordorf
Pjordorf 06.09.2018 um 17:06:08 Uhr
Goto Top
Hallo,

Zitat von @WeltbesterITler:
Aber in jedem Browser ein anderer Fehler
Ja du sagtest schon das es SAP seiface-smile

Wer kann denn jetzt eig helfen, was ich an dem Script noch anpassen muss?
Hmmm, warum niht den fragen der dieses Skript erstellt hat. PM an @colinardo oder warten bis er selbst hier aufschlägt. Und es wäre für alle beteiligten einfacher wenn du den ganzen Link zum Fred hier reingestellt hättest, dann könnten wir selbst sehen was als drumherum noch alles existiert. ES ist nicht verboten hier einen Link auf bestehende Eintragungen oder User zu machen.

Gruß,
Peter
colinardo
colinardo 07.09.2018, aktualisiert am 10.09.2018 um 18:11:06 Uhr
Goto Top
Wer kann denn jetzt eig helfen, was ich an dem Script noch anpassen muss?
Das ist Einiges für dein geschildertes Vorhaben, denn das obige Script synct ja keinen "öffentlichen Ordner" sondern die in der Domain vorhandenen "AD-User" wie im Thread vermerkt.

Persönliche Anpassungen gerne, dann aber bitte PN

Grüße Uwe