Viele Personen kennen diese Adressen gar nicht mehr, dabei basieren Termine und auch die gute alte Autovervollständigen-Funktion bei Eingabe einer Adresse in An:/Cc:/Bcc: noch immer auf diesen Adressen. In Folge dessen kommt es nach einer Migration oft zu Problemen bspw. beim reorganisieren von Terminen, so dass Teilnehmer nicht mehr benachrichtigt werden. Um dem entgegenzuwirken, kann man diese Adressen migrieren. Wie das geht, zeigen wir hier.
Export vom alten Domain Controller
Zunächst erstellen wir in der alten Umgebung mit Hilfe von PowerShell einen CSV-Export, der die Legacy-Adressen enthält.
Die CSV-Datei muss nun möglicherweise zu einem Server/PC kopiert werden, der auf die Exchange-Shell Zugriff hat. Dort angekommen importieren wir die Datei wieder und führen dann folgendes aus:
$Asdf = Import-CSV "C:\x500adresses.csv"
foreach ($User in $Asdf){ if ($User.legacyExchangeDN){ Get-Mailbox -Identity $User.UserPrincipalName | Set-Mailbox -EmailAddresses @{add="X500:$($User.legacyExchangeDN)"} } }
Ob die Migration erfolgreich war, kann über folgenden Befehl geprüft werden:
PowerShell-Script erfasst auf Host-Seite die nötigen Daten
Ansteuerung über Zabbix-Server mit Parametern (also kein Zabbix Trapper)
Verwendung aktueller Best-Practices – sprich am Besten ein “Raw Item” aus dessen Inhalt die anderen Items berechnet werden, um den Datentransfer und die Kommunikation zw. Host und Zabbix-Server so klein wie nur irgendwie möglich zu halten.
Unser Szenario
Im konkreten Beispiel wird ein Script den Inhalt eines Ordners überwachen und uns alarmieren, wenn Inhalte im Ordner älter sind, als eine definierte Zeitspanne. Zusätzlich sollen gewisse Dateien innerhalb des Ordners ignoriert werden.
Schlussfolgerungen
Pfad, Zeitspanne und zu ignorierende Dateien werden als Macros ins Template übernommen und können somit auf Hostebene angepasst werden. Diese Macros werden dann in einem einzigen Item an den Host übergeben, der auf seiner Seite ein Script ausführt und die ganzen benötigten Informationen “raw” zurückgibt. Wir erstellen dann weitere “berechnete Items”, die den Inhalt des “Raw Items” auswerten und damit arbeiten.
Schritt 1: Das Script
Im Installationsverzeichnis von Zabbix (bei uns C:\ZABBIX) legen wir einen Ordner “userparameter” an. Hier wird das Script “Get-OldFilesInFolder.ps1” angelegt:
Entscheidend ist hier unsere letzte Zeile. Wir geben ein (zugegebenermaßen recht einfaches) Json-Objekt zurück. Unser “Raw Item” wird somit nachher mit Json befüllt sein – der wohl sinnvollsten Möglichkeit in Zabbix mit multiplen Daten zu arbeiten.
Der zweite wichtige Punkt ist ganz oben im Script. Im “param()”-Block geben wir die Argumente an, die wir auf dem Zabbix-Host später übergeben müssen.
Schritt 2: Anpassung der zabbix_agentd.conf
Die wichtigste Zeile, die wir hinzufügen müssen, ist folgende:
Mit [*] geben wir an, dass das Item Parameter unterstützt.
Mit dem grün geschriebenen geben wir den Pfad zum Script an
Und die gelben Elemente sind die übergebenen Parameter, die auf keinen Fall weniger sein sollten, wie wir beim Item nachher übergeben.
Die zweite Zeile die angepasst werden muss, ist leider folgende:
UnsafeUserParameters=1
Da wir hier später einen Ordnerpfad übergeben, muss diese Option angepasst werden, da sonst die “Backslashes” nicht akzeptiert werden.
Schritt 3: Erstellung des Templates
Um mit der etwas eigenwilligen Benennung von Templates seitens Zabbix compliant zu sein, habe ich das Template “Template Module Windows folder content by Zabbix agent” genannt und in die Gruppe “Templates/Modules” abgelegt. Mehr gehe ich auf das Design des Templates aber gar nicht ein – viel wichtiger sind andere Dinge:
Macros:
Hier erstellen wir nun die drei besagten Macros:
Macro
Inhalt
Beschreibung
{$FOLDERMONITORING.IGNORE}
Example,Template
Comma-separated list of ignored Files/Folders
{$FOLDERMONITORING.PATH}
C:\TEMP
Path to folder getting monitored
{$FOLDERMONITORING.THRESHOLD}
30
Threshold in seconds
Ist denke ich recht verständlich. Durch die einheitliche Benennung werden Sie später beim Host leichter zu finden sein.
Das Zabbix Raw Item
Nun kommen wir zur Erstellung des “Raw Items” und somit zum Script-Trigger:
Name: Whatever floats your Boat
Type: Zabbix agent
Key: foldermonitoring.getstatus[“{$FOLDERMONITORING.PATH}”,”{$FOLDERMONITORING.IGNORE}”] Hier referenzieren wir die Macros. Auch andere Parameter können aber selbstverständlich angegeben werden.
Type of information: Text
Update interval: 1m (Zabbix Template Guideline)
History: 7d (Zabbix Template Guideline)
Applications: Zabbix raw items (Zabbix Template Guideline)
Description: Hier kann man beschreiben, was Hostseitig in der Config angepasst werden muss, damit das Item funktioniert
Enabled: klar.
Damit ist das “Raw Item” schon fertig. Sollten Sie das Template nun an einen Host anbinden, auf dem das Script liegt und die Config entsprechend angepasst wurde, sollten Sie unter “Latest Data” bereits Ihr Json-Objekt sehen.
Die berechneten Items (Dependent item)
Hier werden nun zwei Items erstellt – Bietet sich bei diesem Json-Objekt an:
Dependent Item #1 (Numeric)
Name: Whatever floats your boat
Type: Dependent item
Key: foldermonitoring.age
Master item: Auswahl des Raw-Items
Type of information: Numeric (unsigned)
Units: s (spezielle Unit für Zeitspannen)
History: 7d (Zabbix Template Guideline)
Trends: Do not keep trends
Show value: As is
Applications: File monitoring
Description: ¯\_(ツ)_/¯
Enabled: ja.
Das war jedoch noch nicht alles, wir wechseln stattdessen auf den “Preprocessing”-Reiter, um dem Raw-Item auch den richtigen Wert zu entziehen:
Add -> JSONPath -> $[“MaxAge”] Das ist die Json-Property, wie wir Sie im Script erstellten.
Add -> Custom multiplier -> 60 Hierdurch machen wir aus den Minuten Sekunden.
Dependent ITEM #2 (Text only)
Name: Whatever floats your boat
Type: Dependent item
Key: foldermonitoring.name
Master item: Auswahl des Raw-Items
Type of information: Text
History: 7d (Zabbix Template Guideline)
Applications: File monitoring
Description: ¯\_(ツ)_/¯
Enabled: ja.
Auch hier dann wieder auf den “Preprocessing”-Reiter wechseln und folgendes konfigurieren:
Add -> JSONPath -> $[“FileName”] Das ist die Json-Property, wie wir Sie im Script erstellten.
Schritt 4: Funktion prüfen
Falls nicht schon nach Erstellung des “Raw Items” passiert, können Sie nun das Script auf einem Host ablegen, die Config des Agents entsprechend anpassen und in Zabbix dem Host das Template zuordnen. Wenig später (falls die Default-Werte eingehalten wurden, eine Minute später) sollten dann die Werte abgerufen werden und unter “Latest Data” einsehbar sein. Die Macros müssen natürlich angepasst werden.
Schritt 5: Trigger erstellen
Nun können wir wieder auf das Template wechseln, um noch einen Trigger zu erstellen. Schließlich wollen wir ja melden, falls eine Datei tatsächlich älter ist als der im Macro hinterlegte Wert.
Auch hier werden wir wieder Best Practices anwenden – Somit kommen keine {ITEM.LASTVALUEX}-Attribute mehr in den Triggernamen, da diese seit Zabbix 4 (nicht komplett sicher) nicht mehr aktualisiert werden. Stattdessen kommen solche Infos in das Feld “Operational Data”. Gesagt, getan:
Name: File in ‘{$FOLDERMONITORING.PATH}’ older than threshold ({$FOLDERMONITORING.THRESHOLD}m)
Operational Data: Age: {ITEM.LASTVALUE1} Immer klein halten, da es in Dashboards zusätzlich zum Triggernamen in der Zeile angezeigt wird
Serverity: Frei wählbar
Expression: {Template Module Windows folder content by Zabbix agent:foldermonitoring.age.last()}>{$FOLDERMONITORING.THRESHOLD} and {Template Module Windows folder content by Zabbix agent:foldermonitoring.name.strlen()}>0 Wir prüfen den Namen hier nur, um darauf zugreifen zu können
OK event generation: Expression
PROBLEM event generation mode: Single
OK event closes: All problems
Allow manual close: Nein.
URL: –
Description: Path of File: {ITEM.LASTVALUE2} Hier greifen wir nun den Namen ab um ihn anzuzeigen.
Enabled: Ja.
Abschluss
Das war es nun – wir haben unser Template erstellt. Was die Komplexität betrifft, war das natürlich gar nichts. Jedoch haben wir hierdurch einen guten Einblick in alle nennenswerten Mechaniken bekommen. Funktionstechnisch kratzen wir hier sicher nur an der Oberfläche.
Auf einem beliebigen Unix-OS folgenden Befehl ausführen:
openssl rand -hex 48
… um einen hexadezimalen PSK-Schlüssel mit einer Länge von 48 Zeichen zu erstellen. Hexadezimal muss er sein, das setzt ZABBIX voraus. Ob es bei der Zeichenlänge Limitierungen gibt, ist mir aktuell nicht bekannt. Diesen Key nun in die Zwischenablage kopieren.
Einspielen im ZABBIX-Server
In der Hostkonfiguration kann nun unter dem Reiter “Encryption” folgende Einstellung gesetzt werden:
Connections to host:
PSK
Connections from host:
PSK
PSK-Identity
[z.B. der Hostname des Hosts]
PSK
[Key aus Zwischenablage]
Mit dem Speichern der Einstellungen wird die Verbindung zum Host unterbrochen, da der ZABBIX-Server nun eine verschlüsselte Verbindung voraussetzt.
Einspielen im Host
Auf dem jeweiligen Host muss nun die Config-Datei angepasst werden. Zuvor legen wir (am besten im Agent-Verzeichnis) ein Textfile ab, das den PSK-Key enthält. Diese nennen wir beispielsweise “psk.key”. Anschließend bearbeiten wir in der Agentconfig folgende Parameter:
# Pfad zur Key-Datei
TLSPSKFile=[Pfad zur Key-Datei]
# Wert für PSK-Identity
TLSPSKIdentity=[z. B. der Hostname]
# Akzeptierte Arten von eingehenden Verbindungen
TLSAccept=psk
# Art der ausgehenden Verbindung
TLSConnect=psk
Nachdem die Parameter entsprechend angepasst wurden, kann der Agent neugestartet werden. Sofern PSK-Identity und PSK-Key auf Server und Host übereinstimmen, sollte nun die Verbindung wieder erfolgen – verschlüsselt.
Bei der Ausführung und Weitergabe der Anleitung fanden wir jedoch heraus, dass man ein wenig Hintergrundwissen benötigt, um die Schritte umsetzen zu können.
Von einem an sich funktionierenden Zabbix-Agent wird hier ausgegangen.
Prüfen Sie über die Agent-Konfiguration, in welchem Ordner zusätzliche Configs eingelesen werden (Suchen nach “Include”-Parameter):
Include=/etc/zabbix/zabbix_agentd.d/*.conf
Erstellen Sie dort ein neues Config-File für mysql:
cd /etc/zabbix/zabbix_agentd.d/
nano userparameter_mysql.conf
… und fügen Sie folgenden Text ein …
#template_db_mysql.conf created by Zabbix for "Template DB MySQL" and Zabbix 4.2
#For OS Linux: You need create .my.cnf in zabbix-agent home directory (/var/lib/zabbix by default)
#For OS Windows: You need add PATH to mysql and mysqladmin and create my.cnf in %WINDIR%\my.cnf,C:\my.cnf,BASEDIR\my.cnf https://dev.mysql.com/doc/refman/5.7/en/option-files.html
#The file must have three strings:
#[client]
#user=zbx_monitor
#password=<password>
#
UserParameter=mysql.ping[*], mysqladmin -h"$1" -P"$2" ping
UserParameter=mysql.get_status_variables[*], mysql -h"$1" -P"$2" -sNX -e "show global status"
UserParameter=mysql.version[*], mysqladmin -s -h"$1" -P"$2" version
UserParameter=mysql.db.discovery[*], mysql -h"$1" -P"$2" -sN -e "show databases"
UserParameter=mysql.dbsize[*], mysql -h"$1" -P"$2" -sN -e "SELECT SUM(DATA_LENGTH + INDEX_LENGTH) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='$3'"
UserParameter=mysql.replication.discovery[*], mysql -h"$1" -P"$2" -sNX -e "show slave status"
UserParameter=mysql.slave_status[*], mysql -h"$1" -P"$2" -sNX -e "show slave status"
Erstellen Sie in MySql einen Benutzer für Zabbix:
mysql -u <Root-User> -p
<Eingabe Passwort>
> CREATE USER 'zbx_monitor'@'%' IDENTIFIED BY '[Neues Passwort für den User]';
> GRANT USAGE,REPLICATION CLIENT,PROCESS,SHOW DATABASES,SHOW VIEW ON *.* TO 'zbx_monitor'@'%';
… jetzt haben Sie einen Benutzer ‘zbx_monitor’ erstellt mit einem von Ihnen definierten Passwort (anstelle von [Neues Passwort für den User])
Nun kommt der Punkt, der von ZABBIX nicht erklärt wird: Die Verbindungsdaten müssen nun im Home-Laufwerk des Zabbix-Benutzers abgelegt werden. Das hat er jedoch standardmäßig nicht. Wir legen nun also dem Benutzer ein Home-Laufwerk an:
# Ordner anlegen
mkdir -p /var/lib/zabbix
# Berechtigung setzen
chown zabbix:zabbix /var/lib/zabbix
# Zabbix Agent stoppen (sonst gehts nicht)
service zabbix-agent stop
# Dem Zabbix-Benutzer das Homelaufwerk zuordnen
usermod -d /var/lib/zabbix zabbix
# Jetzt kann der Agent wieder gestartet werden
service zabbix-agent start
Jetzt kann die Verbindungsdatei hinterlegt werden:
nano /var/lib/zabbix/.my.cnf
[client]
user=zbx_monitor
password=[Neues Passwort für den User]
… das sollte es gewesen sein. Am Besten abschließend den Zabbix-Agent nochmal neustarten:
In dieser Anleitung wird davon ausgegangen, dass Ubuntu 18.04 bereits auf der Maschine installiert wurde. Weiter setzt die Anleitung eine funktionierende Internetverbindung auf dem Proxy voraus.
Um keine Probleme mit Berechtigungen zu bekommen, stellen Sie bitte sicher, dass Sie nun als Admin unterwegs sind:
sudo su
Zunächst laden wir uns dann das aktuelle Repository-Konfigurationspaket herunter:
Nun erstellen wir den PostgreSQL-Benutzer, der vom Proxy verwendet wird, um auf die lokale Datenbank zuzugreifen. Sie werden nach Eingabe der Zeile wiederholt um die Eingabe des Kennworts für den User gebeten. “zabbix” beschreibt den Benutzernamen, der natürlich variieren kann.
sudo -u postgres createuser --pwprompt zabbix
Im nächsten Schritt erstellen wir die Datenbank für den Proxy. Wir nennen diese im Beispiel ebenfalls “zabbix”:
Im letzten Schritt passen wir die Zabbix Proxy-Konfiguration an:
nano /etc/zabbix/zabbix_proxy.conf
Folgende Parameter müssen angepasst werden:
# IP oder FQDN des Hauptservers
Server=192.168.1.20
# Hostname des Proxies
Hostname=ZBX-PROXY
# DBHost muss wirklich leer bleiben, also wie abgebildet
DBHost=
# Name der Datenbank
DBName=zabbix
# Zuvor definierter Benutzer, den der Proxy zur DB-Verbindung verwendet
DBUser=zabbix
# Zuvor definiertes Passwort, das der Proxy zur DB-Verbindung verwendet
DBPassword=*******
Im Anschluss können wir den Zabbix Proxy einmal neustarten:
service zabbix-proxy restart
Bei Bedarf können mit folgender Zeile die Logfile-Einträge des Proxys in Echtzeit ausgegeben werden:
tail -f /var/log/zabbix/zabbix_proxy.log
Damit sollte die Installation abgeschlossen sein und Sie können den Proxy in Ihrer Zabbix-Oberfläche einrichten.
Man kann mit der Computerverwaltung nicht nur den lokalen Computer verwalten, sondern sich auch remote auf andere Rechner schalten. In unserem Fall war es nun aber so, dass wir von einem Rechner in einer ActiveDirectory-Domain (A) auf einen Rechner drauf wollten, der sich nicht in der Domain befand (B). Der User, mit dem wir uns also auf Rechner B schalten wollten, war selbigem komplett unbekannt. Somit stellte sich die Frage, wie wir uns hier mit einem anderen Benutzer authentifizieren können.
Aber der Reihe nach. Als erstes greifen wir auf die lokale Computerverwaltung zu:
Dort angekommen, können wir uns nun mit dem anderen Computer per IP-Adresse verbinden:
Dies mag sogar manchmal noch gehen, jedoch bekommt man spätestens beim Zugriff auf die Dienste o.ä. einen “Zugriff verweigert”-Fehler zurück.
Um diesen Fehler zu verhindern, gibt es einen ziemlich tollen Trick. Mittels des “net use”-Befehls kann man sich nämlich an einem fremden Rechner authentifizieren, um beispielsweise ein Netzlaufwerk zu mappen. Diese Authentifizierung gilt global, also über das Laufwerkmapping hinaus und somit auch tatsächlich für unsere Computerverwaltung.
Wir öffnen also die Kommandozeile ([Win] + [R] –> cmd) oder PowerShell und geben folgende Zeile ein:
net use \c$ /user:
Damit verbinden wir uns auf die versteckte C$-Freigabe, die auf wirklich jedem PC verfügbar sein sollte. Dabei ersetzen wir die eingefärbten Zeichenfolgen natürlich sinnvoll. Ist der Zielcomputer nicht in einer Domäne, so können Sie “” weglassen. Statt dem Computernamen können Sie natürlich auch eine IP eintragen.
Sie bekommen dann noch eine Passwortabfrage, die Sie für den User entsprechend ausfüllen sollten. Sofern alles passt, bekommen Sie den Erfolg mit der Meldung “Der Befehl wurde erfolgreich ausgeführt.” quittiert:
Nun können Sie sich nochmal auf den Remotecomputer schalten und diesen ohne Probleme verwalten können.
Falls Sie Perfomance-Probleme mit Ihrer Dynamics CRM / 365-Instanz haben, können Sie mit den folgenden Schritten etwas mehr ins Detail gehen, um zu sehen, an welcher Stelle es tatsächlich hängt.
Rufen Sie als erstes bitte ein Formular auf, von dem Sie denken, dass es wirklich langsam lädt. In unserem Beispiel verwenden wir das Firmenformular:
Der nächste Schritt ist Browserabhängig: Internet Explorer: Drücken Sie [Strg] + [Shift] + [Q] zum Aufruf des Performance Centers Chrome: Drücken Sie [Strg] + [D] und drücken Sie dann auf [Mehr …]. Als URL geben Sie folgende Zeichenfolge ein (ohne Anführungszeichen): “javascript:Mscrm.Performance.PerformanceCenter.get_instance().TogglePerformanceResultsVisibility()” und als Namen beispielsweise “Performance Center”. Dadurch haben Sie oben nun einen Knopf in der Lesezeichenleiste, den Sie nun drücken um das Performance Center aufzurufen. Firefox: Drücken Sie [Strg] + [B] um die Lesezeichenleiste aufzurufen. Fügen Sie hier ein neues Lesezeichen mit der URL “javascript:Mscrm.Performance.PerformanceCenter.get_instance().TogglePerformanceResultsVisibility()” (ohne Anführungszeichen) ein und benennen Sie es treffend. Klicken Sie dieses danach an, während Sie das betroffene Formular im aktiven Tab geöffnet haben.
In allen Fällen sollten Sie nun ein Performance Center sehen. Hier drücken Sie nun nacheinander [Enable](1) und dann [Close](2):
Lösen Sie nun einen Reload der Seite aus. Dies kann durch drücken von [F5] oder des “Aktualisieren”-Knopfes erfolgen.
Rufen Sie anschließend wieder das Performance Center auf. Sie sehen nun den Ablauf des Seitenaufbaus (3). Mit dem Knopf [Copy All](4) können Sie nun die Wartezeiten auch nochmal als Text herauskopieren.
Sollten Sie für unser Hosted Dynamics 365 einen Performance-Auszug machen, so würden wir Sie zum einen um den Text bitten, den Sie über den [Copy All]-Knopf heraus bekommen und zum anderen könnten Sie uns noch einen Screenshot von der Balkendiagramm-Darstellung schicken.
-Befehl, so klappt die automatische Annahme solange, bis ein Terminkonflikt entsteht. In einer Terminserie ist das dann besonders ärgerlich, da alle Serienelemente abgelehnt werden, sobald sich ein Element mit einem vorhanden Termin überschneidet. Dies kann man umgehen, in dem man weitere Parameter anpasst. Grundsätzlich zu klären wäre dabei folgende Frage: Sind Überschneidungen erlaubt?
Wenn Überschneidungen erlaubt sind, kann man die Einstellungen wie folgt überschreiben:
Damit werden die Termine einfach parallel zu eventuell bereits bestehenden Terminen eingetragen. Das macht dann Sinn, wenn ein Raum beispielsweise doppelt belegbar ist.
Wenn man Überschneidungen vermeiden will und stattdessen wünscht, dass sich überschneidende Termine einfach abgelehnt werden ohne die ganze Serie abzulehnen, so ist folgender Befehl zu verwenden:
Der Parameter –ConflictPercentageAllowed gibt hierbei an, welcher Anteil an Serienelementen auf Grund von Überschneidungen abgelehnt werden darf (in Prozent, aber anzugeben ohne ‘%’-Zeichen), während -MaximumConflictInstances angibt, wie viele Serienelemente wegen Überschneidungen abgelehnt werden dürfen. Beide Werte kann man dabei natürlich utopisch hochsetzen um zu garantieren, dass jede Serie angenommen wird. Dennoch sind sicher an der ein oder anderen Stelle sinnvoll gewählte Grenzwerte nützlich.
Achtung: Solange -AllowConflicts auf $true steht, haben die für –ConflictPercentageAllowed und -MaximumConflictInstances gesetzten Werte keinen Einfluss, sie werden ignoriert.
Szenario:
IMAP- oder POP3-Verbindungen mittels Email-Clients funktionieren einfach nicht mehr, die Verbindungen werden vom Server sofort wieder geschlossen. Bei der weiteren Recherche stellt sich raus, das man mittels Telnet auf dem Exchange-Server selbst unter Verwendung von 127.0.0.1 die Dienste noch abfragen kann. Führt man jedoch Telnet von einer anderen Maschine remote aus, so wird die Verbindung sofort wieder getrennt. Die jeweiligen Dienste sind jedoch auf dem Server aktiv.
Problem: Wenn oben beschriebenes teilweise oder gar komplett auf Sie zutrifft, liegt es vermutlich daran, dass die Proxy-Komponente des jeweiligen Dienstes inaktiv ist. Prüfen können Sie das, indem Sie eine PowerShell-Eingabeaufforderung starten, und folgende Zeile eingeben:
Get-ServerComponentState -Identity [Servername]
Folgendes könnten Sie als Ausgabe zurückbekommen:
Server Component State
-------
[...]
[Servername] ImapProxy Inactive
[...]
[Servername] PopProxy Active
[...]
Die Ausgabe ist selbstverständlich nicht eingefärbt, dies dient nur der Veranschaulichung.
Behebung:
Sollte nun eine oder gar mehrere Komponenten als Inactive angezeigt werden, müssen wir selbige wieder aktivieren. Dies erfolgt durch folgenden PowerShell-Befehl:
Set-ServerComponentState -Identity [Servername] -Component [Komponente] -Requester HealthAPI -State Active
In unserem Beispiel würde der Befehl wie folgt aussehen:
Set-ServerComponentState -Identity SRV-EXCHANGE -Component ImapProxy -Requester HealthAPI -State Active
Damit sollten die Verbindungen wieder möglich sein. Eventuell müssen die jeweiligen Dienste noch neugestartet werden.
Ursache:
Auch nach weiterer Recherche konnte nicht herausgefunden werden, was den Server dazu trieb, die Komponente auf inaktiv zu setzen. Zwar sieht man im Eventlog, dass er es tat, aber keinen tieferen Grund. Sollte sich hier noch etwas ergeben, werde ich den Blogeintrag entsprechend erweitern.
Nachtrag:
Scheinbar führt irgendein Softwarefehler beim Exchange Server 2013 regelmäßig zum Absturz solcher Komponenten. Aus diesem Grund wurde ein Script angefertigt, das dieses Problem automatisiert behebt, falls es existent sein sollte. Dieses ist auch TaskScheduler-kompatibel, kann hier also ganz einfach eingesetzt und alle 5 Minuten gestartet werden:
Zur besseren Veranschaulichung der Ausgabe besitzt dieses Script einige Zeilen, die im Taskscheduler natürlich unnötig sind. Diese habe ich violett markiert.
Möchte man eine Instanz in eine andere Infrastruktur migrieren (möglicherweise aufgrund einer Aktualisierung), sollten folgende Schritte beachtet werden.
Bevor die Instanz in der “alten Umgebung” abgeschaltet wird, sollte der aktuelle Schlüssel für die Datenverschlüsselung kopiert werden. Diesen finden Sie ab Dynamics CRM 2011 unter Einstellungen > Datenverwaltung > Datenverschlüsselung > [X] Schlüssel anzeigen. Sie benötigen diesen nach der Migration, um die Datenverschlüsselung wieder zu aktivieren.
Stellen Sie zudem sicher, dass es einen CRM-User gibt, der alle der folgenden Eigenschaften besitzt.
Zugriffsmodus: Lesen-Schreiben (NICHT Administrator und erst recht nicht Lesezugriff)
Rolle: Mindestens Systemadministrator
Anschließend können Sie auf dem Anwendungsserver die Instanz deaktivieren und löschen. Hierbei wird die Datenbank nicht gelöscht.
Besagte Datenbank können Sie anschließend auf dem SQL-Server entweder im Rahmen eines Backups sichern, oder aber die Datenbank einfach aushängen.
In beiden Fällen können Sie die Datenbank entweder durch simples Wiedereinhängen oder durch das Wiederherstellen der Sicherung im neuen SQL-Server einhängen.
Auf dem neuen CRM- / Dynamics 365-Server können Sie dann die Organisation importieren. Nach der erneuten Eingabe der Namen sowie der Auswahl des Report-Servers kommen wir hier zum Benutzermapping. Dies können Sie automatisiert durchlaufen lassen, sofern die Domäne gleich bleibt. Anderenfalls müssen Sie die CRM-Benutzer manuell den AD-Benutzern zuweisen.
Im Falle des Fehlers “You must map your Active Directory user account to at least one enabled Microsoft Dynamics CRM user who has the System Administrator role before the organization can be imported” sind folgende Ursachen möglich:
Sie führen den Import mit einem Benutzer durch, den Sie nicht gemappt haben > Sie müssen sich entweder den Import mit dem Benutzer durchführen, auf den die Anforderungen aus Schritt 2 passen, oder Ihren aktuellen Benutzer auf den besagten CRM-User mappen.
Sie führen den Import mit einem Benutzer durch, dessen CRM-User nur administrativen Zugriff auf das CRM hat > Führen Sie folgende Query in der Datenbank Ihrer Instanz aus:
UPDATE SystemUserBase
SET AccessMode = 0
WHERE DomainName = 'DOMAIN\User'
Sie führen den Import mit einem Benutzer durch, dessen CRM-User deaktiviert ist > Führen Sie folgende Query in der Datenbank Ihrer Instanz aus:
UPDATE SystemUserBase
SET IsDisabled = 0
WHERE DomainName = 'DOMAIN\User'
Es kann sein, dass Sie davor einen anderen Benutzer deaktivieren müssen, um die maximale Anzahl von Benutzern nicht zu überschreiten:
UPDATE SystemUserBase
SET IsDisabled = 1
WHERE DomainName = 'DOMAIN\OtherUser'
Danach wird der Import durchgeführt. Dies lief bei uns fehlerfrei durch. Sollten uns bei kommenden Migrationen noch gängige Fehler auffallen, werden wir diese an der Stelle ebenfalls festhalten.
Nach dem erfolgreichen Umzug müssen Sie bei der Verwendung von ADFS spätestens jetzt die alte Instanz löschen. Aktualisieren Sie anschließend beide Relying Party Trusts (mangels deutscher Server fehlt mir hier die Übersetzung) – die der alten Instanz und die der neuen.
Der A-Record muss ebenfalls auf die neue Infrastruktur zeigen.
Tragen Sie nach dem erfolgten Zugriff auf das neue CRM den in Schritt 1 gespeicherten Verschlüsselungskey wieder unter Einstellungen > Datenverwaltung > Datenverschlüsselung ein. Danach ist das CRM / Dynamics 365 wieder voll benutzbar.