Categories
Exchange Server Windows

Mail-enabled Public Folder doesn’t receive external Mails

Since SP1 for Exchange 2013 it could be possible, that just mail-enabling a Public Folder isn’t enough to make this Folder receiving external Mails. This is caused by a missing permission for external Senders (which appear as “Anonymous”) to “create” items in this specific folder.

If you track an external message, you may receive the following error:

RecipientStatus: {[{LRT=};{LED=550 5.7.1 RESOLVER.RST.AuthRequired; authentication required [Stage: CreateMessage]};{FQDN=};{IP=}]}

To resolve this issue, you have to drop the following command within the Exchange Management Shell:

Add-PublicFolderClientPermission –identity “\Folder\Subfolder” –User Anonymous –AccessRights CreateItems

This should resolve your problem.

Categories
Exchange Server Windows

Script: Grant “SendAs”-Permission for all Groupmembers in a Distribution Group

 

This Script will go through all Distribution Groups and grants SendAs-Permissions for all Groupmembers by using the Group itself instead of each User:

Grant-SendAs-To-Group

Categories
Hyper-V Server VMM Windows

Frequent VMM-Migrationerrors and possible solutions

Migrationen über den VMM (vorallem zwischen Clustern) können oft zu merkwürdigen Fehlern führen, die sich nicht immer logisch erklären lassen. Aus diesem Grund habe ich hier mal die mir widerfahrenen Probleme aufgelistet, gemeinsam mit Lösungsansätzen.

  • Es konnte keine verfügbare Verbindung mit dem ausgewählten VM-Netzwerk gefunden werden.
  • Es wurde keine Verbindung zu “[VM-Netzwerkname]” mit ausreichenden Ressourcen gefunden.

Das ist ein seltsamer Bug. Wenn wir jedoch im VMM aus dem Menüband die PowerShell-Konsole öffnen, und darüber die Migration durchführen, so funktioniert es ohne Probleme – Vorausgesetzt natürlich, dass das Netzwerk tatsächlich an dem Zielhost anliegt. Hierzu gehen wir folgendermaßen vor:

$VMHost = Get-VMHost -ComputerName "[Ziel-Host]"
$VM = Get-VM -Name "[Zu migrierdende VM]"
$VMPath = $VMhost.Vmpaths[[Index des korrekten Speicherorts]]
Move-VM -VM $VM -VMHost $VMHost -Path $VMPath

Move-VM : Die VM “XXXXX” kann aufgrund von Inkompatibilitätsproblemen nicht zu Host “XXXXXXX” migriert
werden. The virtual machine ‘XXXXX’ is using processor-specific features not supported on physical computer ‘XXXX’.
To allow for migration of this virtual machine to physical computers with different processors, modify the virtual
machine settings to limit the processor features used by the virtual machine. (Virtual machine ID
xxxxxxxx-xxxxxx-xxxxxxx-xxxxxxxx) (Fehler-ID: 23008, Detaillierter Fehler: )

Beheben Sie das Inkompatibilitätsproblem, und wiederholen Sie den Migrationsvorgang.

Hier ist die VM auf einem Host erstellt worden, dessen Prozessorgeneration neuer ist, als der Zielhost der Migration. Behoben werden kann das Ganze, in dem man die VM herunterfährt, den Haken unter “Hardware” -> “Prozessor” -> “Migration zu einem virtuellen Maschinenhost mit abweichender Prozessorversion zulassen” setzt und dann die Migration erneut durchführt. Nach der Migration sollte die Maschine erneut heruntergefahren werden, um diesen Haken wieder zu entfernen.


Move-VM : Der Hostvorgang auf dem Server “XXXXXXXXX” kann von VMM aufgrund des folgenden Fehlers nicht
abgeschlossen werden: Virtual machine migration operation for ‘XXXXXXXX’ failed at migration source ‘XXXXXXX’. (Virtual
machine ID xxxxxxxx-xxxxxx-xxxxxx-xxxxxxxxx)
Virtual machine migration for ‘XXXXXXX’ failed because configuration data root cannot be changed for a clustered
virtual machine. (Virtual machine ID xxxxx-xxxxxxxxx-xxxxxxxx-xxxxxx) (Fehler-ID: 12700, Detaillierter Fehler:
Unknown error (0x8005))

Beheben Sie das Problem auf dem Host, und wiederholen Sie dann den Vorgang.

Dieser Fehler kann behoben werden, indem man im Anschluss an den Fehler auf “Reparieren” -> “Ignorieren” klickt, und anschließend die Migration erneut triggert. Notfalls über PowerShell. 

Categories
Hyper-V Server Windows

VMM: Hinzufügen von HyperV-Hosts und -Cluster in vertrauenswürdigen Domänen

In unserer Infrastruktur haben wir uns dazu entschieden, jeden HyperV-Cluster in eine eigene Domain zu packen. Zusätzlich gibt es noch einen Management-Cluster, in dem unter anderem die Virtual Machine Manager-Server stehen. Die Domains sind untereinander über Forest-Trusts verbunden. Dieser Aufbau lässt zwar extrem hohe Sicherheitsstandards zu, bringt aber auch Probleme mit sich – Unter anderem beim Hinzufügen neuer HyperV-Cluster.

Vorgang:
Wie gewohnt öffnet man per Rechtsklick auf “All Hosts” oder einer Untergruppe den Assistent zum Hinzufügen von Ressourcen. Da wir wie erwähnt einen Cluster bzw. Host aus einer vertrauenswürdigen Domain hinzufügen wollen, wählen wir den obersten Punkt (“Windows-Server in einer vertrauenswürdigen Active Directory-Domäne”) aus. Anschließend wählen wir die zu verwendenden Anmeldeinformationen aus. Im darauffolgenden Fenster geben wir nun die Hostnamen der Server an, welche wir hinzufügen wollen. Da sich diese nicht in der selben Domain wie der VMM bewegen, geben wir die FQDNs an (hyperv-server01.cluster-domain01.dom). Klicken wir nun auf weiter, schlägt die Überprüfung nach einiger Wartezeit fehl, da er die Hostnamen (hyperv-server01) nicht auflösen kann.

Problem:
VMM ist hier ziemlich doof. Wir geben ihm die FQDNs, doch er will während dem Überprüfungsvorgang plötzlich die Hostnamen auch ohne Domain-Endung ansprechen. Nichts anderes sagt uns auch die Fehlermeldung.

Behebung:
Um das Problem zu umgehen, gibt es zwei Möglichkeiten. Bei einer von beiden von schön zu reden, wäre etwas vermessen:

  1. Hinzufügen der Hostnames aller Hosts in die DNS-Zone der Managementdomain: Die weniger unsaubere Lösung – Einfach in die DNS-Verwaltung der Management-Domain gehen um dort alle Hosts (und Cluster) als A-Records mit deren entsprechender IP einzutragen.
  2. Modifizieren der Hosts-Datei: Nicht schön aber selten – Wir öffnen das Notepad als Admin und öffnen die Hosts-Datei unter C:\Windows\System32\drivers\etc. Dort tragen wir gemäß dem auskommentierten Beispiel alle Host- (und Cluster-) Namen ein sowie deren IP (vorangestellt)

Anschließend kann im VMM auf “Retry” gedrückt werden. Sollte noch immer was fehlen, zeigt er dies zum Glück in der Fehlermeldung an.

Categories
Lync Server Windows

Lync/Skype4B: Nummern filtern in der Dialin-Page

Angenommen Sie haben in Ihrer Lync-/Skype for Business-Umgebung mehrere Dialin-Nummern, die aber zum Teil nicht von jedem gesehen werden sollen. Nun ist es aber so, dass auf der Dialin-Seite standardmäßig alle Einwahlnummern angezeigt werden. Um das zu unterbinden, kann man die Nummern in der PhoneList-Datei filtern. Diese finden wir wie folgt:

  • Melden Sie sich am Server an und öffnen Sie den IIS Manager
  • Navigieren Sie in der linken Baumstruktur auf folgenden Pfad:
    <Servername> → Sites → <Lync-/Skype-Version> External Web Site → dialin
  • Nun können Sie rechts in den Actions Explore auswählen, um im entsprechenden Dateiverzeichnis zu landen
  • Dort können Sie die Datei PhoneList.xslt finden. Diese können Sie erstmal nehmen und an den selben Ort nochmal kopieren mit dem Präfix “OLD_”. Somit haben Sie die originale Datei auf jeden Fall gesichert.
  • Nun öffnen Sie die PhoneList.xslt-Datei mit Hilfe des Notepads. (Zum anschließenden Speichern in den Pfad muss Notepad eventuell als Admin gestartet werden!)

Nun sollte sich in etwa ein solcher Eintrag öffnen:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
 <xsl:output method="xml" indent="yes"/>
 <xsl:template match="/PhoneList">
  <xsl:for-each select="Region/PhoneNumber">
   <tr>
    <td class="region">
     <xsl:value-of select="@Name"/>
    </td>
    <td class="number">
     <xsl:value-of select="@Value"/>
    </td>
    <td class="language">
     <span class="defaultLanguage">
      <xsl:value-of select="@Primary"/>
     </span>
     <xsl:value-of select="@Secondary"/>
    </td>
   </tr>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

Interessant für uns ist eigentlich nur eine Zeile, an welche wir den Filter anbringen werden:

<xsl:for-each select="Region/PhoneNumber">

Mit Filter sieht das Ganze dann folgendermaßen aus:

<xsl:for-each select="Region/PhoneNumber[<Variable>='<Wert>']">

Als Variable sind folgende Elemente verwendbar:

  • @Name – Das ist der Name der Dialin-Nummer, der in der Tabelle auf der Seite unter der Spaltenüberschrift “Region” zu finden ist.
  • @Value – Das ist die tatsächliche Telefonnummer, auch in der Tabelle unter “Nummer” zu finden.
  • @Primary – Die primäre Region, in der Tabelle dick abgebildet unter “Verfügbare Sprachen”
  • @Secondary – Die sekundären Regionen, in der Tabelle rechts von der primären Sprache unter “Verfügbare Sprachen” zu finden.

Der einzutragende Wert ist dann eben das, was man sehen möchte. Statt dem ‘=’ können auch noch die Operatoren ‘!=’ (ist nicht gleich), ‘&lt’ (kleiner als) und ‘&gt’ (größer als) verwendet werden.

Ein fertiger Filter kann dann zum Beispiel so aussehen:

<xsl:for-each select="Region/PhoneNumber[@Name!='Geheime Einwahl']">

Nach dem Speichern ist der Filter sofort aktiv und bereits beim nächsten Aktualisieren der Seite ist die Änderung zu sehen.

Categories
Lync Server SQL Windows

Lync 2013 Enterprise – Umzug der Datenbanken auf einen neuen SQL-Server

In diesem Beitrag werden wir den Umzug aller Datenbanken betrachten, die in einer Lync Enterprise-Umgebung auftreten. Diese nennen sich wie folgt:

— BackEnd —
CPSDYN – Dynamische Informationsdatenbank für das Call Parking-Feature
RGSCONFIG – In ihr liegt die Konfiguration aller Response Groups
RGSDYN – Dynamische Informationsdatenbank für Runtime-Daten der Response Groups
RTCAB – In ihr liegen die Daten aller Adressbücher
RTCSHARED – Beinhaltet Konferenzdaten
RTCXDS – Ist für das Backup der Benutzerdaten zuständig

— Persistent Chat —
MGC – Speichert alle Persistent Chats und deren Protokolle

— Monitoring —
LCSCDR – Speichert Details aller Calls
LCSLOG – Beinhaltet Daten aller Instant Messages und Konferenzen
QOEMETRICS – Beinhaltet QoE-Daten um die Qualität der Dienste für User sicherzustellen

Vorbereitung

Als erstes, und dies ist äußerst wichtig, muss dafür gesorgt werden, dass die Central Management Datenbank während des Umzugs nicht auf einem der FrontEnd-Server läuft. Da dessen Dienste während des Umzugs nur eingeschränkt bzw. gar nicht verfügbar sind, wir allerdings über die Topologie nachher auf den neuen SQL-Server verweisen, könnte dies fatale Folgen haben. Ist dies also der Fall, muss ein temporärer Lync-Server aufgesetzt werden, der keine Rolle besitzt, sondern nur den Central Managent Store besitzt. Erst wenn dies sichergestellt wurde und die CMS Replikation auf “healthy” steht, können wir fortfahren. Überprüfen können wir dies mit folgendem Befehl:

Get-CsManagementStoreReplicationStatus

Um sicherzustellen, dass keine Zugriffe mehr auf die Datenbank entstehen, müssen die Lyncdienste im gesamten FrontEnd- und auch im Persistent Chat-Pool beendet werden. Das heißt: Diese Arbeit ist auf jeden Fall außerhalb der Geschäftszeiten zu erledigen und kann sich ordentlich in die Länge ziehen.

Wie erwähnt gehen wir also als erstes auf sämtliche Server, die sich in den oben genannten Pools befinden und führen folgenden Befehl aus:

Stop-CsWindowsService

Dieser Befehlt stoppt sämtliche Lync-Dienste auf dem jeweiligen Server. Bitte notieren Sie sich die Reihenfolge der Abschaltung der Server in einer Handnotiz, um später zum Abschluss die Server wieder in entgegengesetzter Richtung zu starten.

Export

Als erstes müssen wir die Datenbanken für den Umzug vorbereiten. Dazu verwenden wir folgendes Script:

ALTER DATABASE cpsdyn SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE cpsdyn SET SINGLE_USER
ALTER DATABASE cpsdyn SET ONLINE
ALTER DATABASE rgsconfig SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE rgsconfig SET SINGLE_USER
ALTER DATABASE rgsconfig SET ONLINE
ALTER DATABASE rgsdyn SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE rgsdyn SET SINGLE_USER
ALTER DATABASE rgsdyn SET ONLINE
ALTER DATABASE rtcab SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE rtcab SET SINGLE_USER
ALTER DATABASE rtcab SET ONLINE
ALTER DATABASE rtcshared SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE rtcshared SET SINGLE_USER
ALTER DATABASE rtcshared SET ONLINE
ALTER DATABASE rtcxds SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE rtcxds SET SINGLE_USER
ALTER DATABASE rtcxds SET ONLINE
ALTER DATABASE mgc SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE mgc SET SINGLE_USER
ALTER DATABASE mgc SET ONLINE
ALTER DATABASE LcsCDR SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE LcsCDR SET SINGLE_USER
ALTER DATABASE LcsCDR SET ONLINE
ALTER DATABASE LcsLog SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE LcsLog SET SINGLE_USER
ALTER DATABASE LcsLog SET ONLINE
ALTER DATABASE QoEMetrics SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE QoEMetrics SET SINGLE_USER
ALTER DATABASE QoEMetrics SET ONLINE

Von diesem Zeitpunkt an kann man nur noch eine Verbindung pro Datenbank öffnen. Das heißt man kann auch nur eine Query im Management-Studio gleichzeitig geöffnet haben. Die alten Hasen werden nun vermutlich lachen, aber ich bin fast verzweifelt, bevor ich das kapiert habe…

Nun denn, nachdem das erledigt wurde, können wir die Datenbanken in einem Ordner unserer Wahl sichern. Dies erledigen wir über folgendes Script:

USE Master;
GO
BACKUP DATABASE cpsdyn
TO DISK = 'D:\BackUp\cpsdyn.bak'
GO
BACKUP DATABASE rgsconfig
TO DISK = 'D:\BackUp\rgsconfig.bak'
GO
BACKUP DATABASE rgsdyn
TO DISK = 'D:\BackUp\rgsdyn.bak'
GO
BACKUP DATABASE rtcab
TO DISK = 'D:\BackUp\rtcab.bak'
GO
BACKUP DATABASE rtcshared
TO DISK = 'D:\BackUp\rtcshared.bak'
GO
BACKUP DATABASE rtcxds
TO DISK = 'D:\BackUp\rtcxds.bak'
GO
BACKUP DATABASE mgc
TO DISK = 'D:\BackUp\mgc.bak'
GO
BACKUP DATABASE lcscdr
TO DISK = 'D:\BackUp\lcscdr.bak'
GO
BACKUP DATABASE lcslog
TO DISK = 'D:\BackUp\lcslog.bak'
GO
BACKUP DATABASE qoemetrics
TO DISK = 'D:\BackUp\qoemetrics.bak'

Kopieren der Daten und Umstellung der Topologie

Die gesicherten Daten können wir nun nehmen und schon mal zum Zielserver verschieben. Damit es zu keinen Irritationen kommt: Wir haben auch auf dem Zielserver wieder unter dem Laufwerk D: einen “BackUp”-Ordner erstellt. Dieser Pfad ist noch nicht der entgültige Pfad, dieser wird später beim Import der Datenbanken gesetzt.

Nun gehen wir auf unseren CMS-Host, laden uns die Topologie herunter und passen die Einstellungen an:

  1. Erstellung des SQL Server Stores:
    Unter Lync Server ->  <Site> -> Shared Components rechtsklicken wir auf “SQL Server stores” und klicken dann auf New SQL Server Store… . Die hier benötigten Daten sollten klar sein, FQDN des Servers und der Instanzname. Im Anschluss mit OK bestätigen.
  2. Nun können wir auf den FrontEnd-Pool rechtsklicken und gehen dann auf Edit Properties… . Unter dem Punkt “Associations” können wir nun den neuen SQL Server store auswählen. Direkt darunter können wir auch noch für die Archivierung den Server auswählen.
  3. Nun werden wir die Topologie publishen. Dabei wird uns auch gesagt, dass er nun eine Datenbank auf dem Server anlegen wird. Das ist schön, denn das wollen wir. Wenn der Wizard mit einer Warning bei “Creating Database” erfolgreich abschließt, ist der erste Schritt getan.
  4. Nun widmen wir uns erneut der Topologie, rechtsklicken diesmal auf den Persistent Chat-Pool, öffnen wieder die Properties und wählen auch hier den neuen SQL Server store.
  5. Nun wiederholen wir Schritt 3 nochmal, publishen erneut die Topologie und lassen uns wieder eine Datenbank erstellen. Auch hier kann wieder eine Warnung beim letzten Schritt stehen.

Damit sind die Änderungen in der Topologie abgeschlossen.

Import der Bestandsdaten in die neue Datenbank

Bevor wir beginnen, müssen wir auf dem neuen Server die eben erstellten Datenbanken ebenfalls in diesen SingleUser-Modus bekommen. Dazu führen wir unser bereits von oben bekanntes Script erneut aus:

ALTER DATABASE cpsdyn SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE cpsdyn SET SINGLE_USER
ALTER DATABASE cpsdyn SET ONLINE
ALTER DATABASE rgsconfig SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE rgsconfig SET SINGLE_USER
ALTER DATABASE rgsconfig SET ONLINE
ALTER DATABASE rgsdyn SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE rgsdyn SET SINGLE_USER
ALTER DATABASE rgsdyn SET ONLINE
ALTER DATABASE rtcab SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE rtcab SET SINGLE_USER
ALTER DATABASE rtcab SET ONLINE
ALTER DATABASE rtcshared SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE rtcshared SET SINGLE_USER
ALTER DATABASE rtcshared SET ONLINE
ALTER DATABASE rtcxds SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE rtcxds SET SINGLE_USER
ALTER DATABASE rtcxds SET ONLINE
ALTER DATABASE mgc SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE mgc SET SINGLE_USER
ALTER DATABASE mgc SET ONLINE
ALTER DATABASE LcsCDR SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE LcsCDR SET SINGLE_USER
ALTER DATABASE LcsCDR SET ONLINE
ALTER DATABASE LcsLog SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE LcsLog SET SINGLE_USER
ALTER DATABASE LcsLog SET ONLINE
ALTER DATABASE QoEMetrics SET OFFLINE WITH ROLLBACK AFTER 10 Seconds
ALTER DATABASE QoEMetrics SET SINGLE_USER
ALTER DATABASE QoEMetrics SET ONLINE

Nun können wir unseren Bestand in die neuen Datenbanken integrieren. Hierzu ist folgendes Script nötig, wobei wieder der Quellpfad und Zielpfad auf die individuellen Einstellungen anzupassen sind:

USE Master;
RESTORE DATABASE [cpsdyn] FROM DISK = N'D:\BackUp\cpsdyn.bak' WITH FILE = 1,
MOVE N'cpsdyn_data' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\cpsdyn.mdf',
MOVE N'cpsdyn_log' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\CPSDYN.LDF',
NOUNLOAD, REPLACE, STATS = 10
GO
RESTORE DATABASE [rgsconfig] FROM DISK = N'D:\BackUp\rgsconfig.bak' WITH FILE = 1,
MOVE N'rgsconfig_data' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\rgsconfig.mdf',
MOVE N'rgsconfig_log' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\rgsconfig.LDF',
NOUNLOAD, REPLACE, STATS = 10
GO
RESTORE DATABASE [rgsdyn] FROM DISK = N'D:\BackUp\rgsdyn.bak' WITH FILE = 1,
MOVE N'rgsdyn_data' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\rgsdyn.mdf',
MOVE N'rgsdyn_log' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\rgsdyn.LDF',
NOUNLOAD, REPLACE, STATS = 10
GO
RESTORE DATABASE [rtcab] FROM DISK = N'D:\BackUp\rtcab.bak' WITH FILE = 1,
MOVE N'rtcab_data' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\rtcab.mdf',
MOVE N'rtcab_log' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\rtcab.LDF',
NOUNLOAD, REPLACE, STATS = 10
GO
RESTORE DATABASE [rtcshared] FROM DISK = N'D:\BackUp\rtcshared.bak' WITH FILE = 1,
MOVE N'rtcshared_data' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\rtcshared.mdf',
MOVE N'rtcshared_log' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\rtcshared.LDF',
NOUNLOAD, REPLACE, STATS = 10
GO
RESTORE DATABASE [rtcxds] FROM DISK = N'D:\BackUp\rtcxds.bak' WITH FILE = 1,
MOVE N'rtcxds_data' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\rtcxds.mdf',
MOVE N'rtcxds_log' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\rtcxds.LDF',
NOUNLOAD, REPLACE, STATS = 10
GO
RESTORE DATABASE [mgc] FROM DISK = N'D:\BackUp\mgc.bak' WITH FILE = 1,
MOVE N'mgc_data' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\mgc.mdf',
MOVE N'mgc_log' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\mgc.LDF',
NOUNLOAD, REPLACE, STATS = 10
GO
RESTORE DATABASE [LcsCDR] FROM DISK = N'D:\BackUp\LcsCDR.bak' WITH FILE = 1,
MOVE N'LcsCDR_data' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\LcsCDR.mdf',
MOVE N'LcsCDR_log' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\LcsCDR.LDF',
NOUNLOAD, REPLACE, STATS = 10
GO
RESTORE DATABASE [LcsLog] FROM DISK = N'D:\BackUp\LcsLog.bak' WITH FILE = 1,
MOVE N'LcsLog_data' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\LcsLog.mdf',
MOVE N'LcsLog_log' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\LcsLog.LDF',
NOUNLOAD, REPLACE, STATS = 10
GO
RESTORE DATABASE [QoEMetrics] FROM DISK = N'D:\BackUp\QoEMetrics.bak' WITH FILE = 1,
MOVE N'QoEMetrics_data' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\QoEMetrics.mdf',
MOVE N'QoEMetrics_log' TO N'D:\MSSQL12.SKYPE4BUSINESS\MSSQL\DATA\QoEMetrics.LDF',
NOUNLOAD, REPLACE, STATS = 10
GO

Damit ist der Import an sich erledigt.

Abschließende Einstellungen

Zum Abschluss nehmen wir die Datenbanken wieder in den MultiUser-Mode. Erledigt wird das mit folgendem Script:

ALTER DATABASE cpsdyn SET multi_USER
ALTER DATABASE rgsconfig SET multi_USER
ALTER DATABASE rgsdyn SET multi_USER
ALTER DATABASE rtcab SET multi_USER
ALTER DATABASE rtcshared SET multi_USER
ALTER DATABASE rtcxds SET multi_USER
ALTER DATABASE mgc SET multi_USER
ALTER DATABASE LcsCDR SET multi_USER
ALTER DATABASE LcsLog SET multi_USER
ALTER DATABASE QoEMetrics SET multi_USER

Dann muss man noch ein sogenanntes “Cross-Database Ownership Chaining” auf der RTCshared-Datenbank aktivieren. Hierzu rechtsklicken wir auf die Datenbank und führen eine neue Query aus mit folgendem Inhalt:

ALTER DATABASE rtcshared SET DB_CHAINING ON;

Reaktivierung der Lync-Dienste + Funktionsüberprüfung

Dank der Notizen, die wir bzgl. der Reihenfolge der Abschaltungen der Frontend-Serverdienste gemacht hatten, können wir nun in entgegengesetzter Richtung die Server wieder anfahren. Dies geschieht mit folgendem Befehl:

Start-CsWindowsService

Währenddessen können wir zur Funktionsprüfung den Eventlog aufmachen (RUN -> eventvwr). Dort sehen wir dann schön die Statusmeldungen beim Starten der einzelnen Dienste und auch die sich öffnenden Verbindungen auf den neuen Datenbankserver.

Damit sind wir durch. Lediglich den CMS können wir noch zurückverlagern auf einen FrontEnd-Server.

Categories
Certificates Exchange Server Windows

Exchange 2007-2013: Umstellen der internen URLs auf die externen Namen

Um den vollen Funktionsumfang aller Exchange-Dienste ausnutzen zu können, müssen alle Namen, sowohl intern als auch extern, mit einem oder mehreren Zertifikaten abgedeckt werden. Nun hat man zwei Möglichkeiten, das ganze zu bewerkstelligen:

  1. Verwendung von zwei unterschiedlichen Zertifikaten: Eins ausgestellt von der internen CA zur Abdeckung aller internen URLs und eins ausgestellt von einem Zertifikatsanbieter Ihrer Wahl zur Abdeckung der externen URLs.
  2. Umstellung der internen URLs auf die externen, um anschließend im internen DNS die öffentlichen URLs zusätzlich zu pflegen, allerdings unter Verwendung von internen IPs. Hier wird dann nur ein Zertifikat benötigt.

Die bisherige dritte Möglichkeit, nämlich sowohl lokale als auch öffentliche URLs in ein Zertifikat zu packen, wird ab dem 1. November 2015 nicht mehr unterstützt. Für mehr Informationen hierzu klicken Sie bitte auf folgenden Link: https://www.icann.org/en/system/files/files/sac-057-en.pdf

Die zweite Möglichkeit werden wir nun durchführen. Hierfür müssen wir allerdings einige Befehle in der Exchange Management Shell absetzen. Diese lauten wie folgt:

Set-ClientAccessServer -Identity <HostName> -AutodiscoverServiceInternalUri https://mail.example.de/autodiscover/autodiscover.xml

Set-WebServicesVirtualDirectory -Identity "<HostName>\EWS (Default Web Site)" -InternalUrl https://mail.example.de/ews/exchange.asmx

Set-OABVirtualDirectory -Identity "<HostName>\oab (Default Web Site)" -InternalUrl https://mail.example.de/oab

Set-ActiveSyncVirtualDirectory -Identity "<HostName>\Microsoft-Server-ActiveSync (Default Web Site)" -InternalUrl https://mail.example.de/Microsoft-Server-ActiveSync

Set-OWAVirtualDirectory -Identity "<HostName>\owa (Default Web Site)" -InternalUrl https://mail.example.de/owa

Set-ECPVirtualDirectory -Identity "<HostName>\ecp (Default Web Site)" -InternalUrl https://mail.example.de/ecp

Optional (kann zuvor über Get-OutlookAnywhere getestet werden):

Set-OutlookAnywhere -Identity "<HostName>\Rpc (Default Web Site)" -InternalHostname  -InternalClientsRequireSsl $true

Im Anschluss daran muss man den IIS Application Pool recyclen, damit die Änderungen wirksam werden. Hierfür muss der IIS Manager geöffnet werden. Darin angekommen, klicken wir unter Application Pools auf den MSExchangeAutodiscoverAppPool und anschließend auf Recycle. Sobald dies erledigt ist, sind die Einstellungen übernommen und die Clients ziehen sich bei der nächsten Autodiscover-Abfrage die neuen URLs.

Categories
Hyper-V Server Windows

Hyper-V: Shared Nothing Live Migration zwischen Clustern

Shared Nothing Live Migration ist nun bereits seit der Servergeneration 2012 fest integriert und wurde nun auch bei uns im Rahmen von diversen Clusteraktualisierungen zu einem echten Thema. Wie das Ganze funktioniert, werden wir hier im Detail nicht mehr erläutern. Nur soviel sei dazu gesagt: Während die ursprüngliche Live-Migration einen gemeinsam genutzten Storagepool voraussetzt, wird bei der Shared Nothing Live Migration (kurz: VSM) der tatsächliche Speicherort der VM so lange für den Zielhost freigegeben, bis dieser alle benötigten Dateien in den für ihn vorgesehenen Storagepool verschoben hat. Anschließend wird die Freigabe geschlossen, die VM läuft mit max. 2 verlorenen Pings weiter und die Migration ist erfolgreich beendet.

Wie Sie sich vielleicht vorstellen können, bedeutet dieser veränderte Zugriff der Hosts aufeinander logischerweise mehr Konfigurationsaufwand. Vorallem dann, wenn man nicht wie von Microsoft vorgesehen jeden Cluster in die selbe Domain schiebt, sondern für jeden Cluster eine eigene Domain hat. Wir werden Ihnen hier schrittweise aufzeigen, wie wir vorgegangen sind, um dennoch die VSM-Migration zu ermöglichen. Dabei wird auch Bezug auf die Migration über den System Center Virtual Machine Manager genommen, da wir diesen zur Verwaltung unserer Cluster verwenden.

 

Schritt 1 – Trusts soweit das Auge reicht
Als erstes sorgten wir dafür, dass sich sämtliche Clusterdomains in einer Vertrauensstellung zueinander befanden. Hierzu wurde immer ein Two-Way-Forest-Trust verwendet. Mehr gibt es an dieser Stelle eigentlich nicht zu sagen.

 

Schritt 2 – Pro Domain eine Gruppenrichtlinie
Nun machen wir pro Clusterdomäne eine Gruppenrichtlinie, die dafür sorgt, dass die Administratoren und Hosts aus den anderen Clusterdomänen Vollzugriff auf die Hosts der Clusterdomain haben:

Beispiel-GPO
Beispiel-GPO

 

Schritt 3 – Portfreigabe
Damit die Migration durchgeführt werden kann, müssen diverse Portfreigaben gesetzt werden. Zusätzlich zu den gewöhnlichen LDAP-Ports usw. gesellt sich hier der Port TCP 6600. Ohne den geht gar nichts. Hier wäre es am Besten, einfach das Firewall-Monitoring zu öffnen um zu schauen, was noch zwischen den Clustern geblockt wird.

 

Schritt 4 – Kerberos
Nun wird es spannend, denn hier müssen wir von jeder Empfehlung abweichen auf Grund unserer Multi-Domain-Struktur. Wir klicken also im ersten Cluster im Domain Controller auf “Active Directory User and Computers” und suchen die Maschinen-Accounts unserer Hosts. Wir picken uns den ersten Host heraus, öffnen dessen Properties und klicken auf den Tab “Delegation”. Hier müssten wir eigentlich alle Hosts einzeln für die benötigten Services auf dem Host berechtigen. Unser einziges Problem: Wir können hier keine Hosts aus Vertrauensstellungen auswählen. Stattdessen setzen wir also unseren Haken bei “Trust this Computer for Delegation to any service (Kerberos only)”. Da dies ein Stück weit auch die Tore öffnet, ist es umso wichtiger, die Firewall in Schritt 3 sorgfältig zu konfigurieren. Diese Aktion ist für jeden Host in jedem Cluster zu wiederholen.

 

Schritt 5 – Hyper-V Einstellungen setzen
Nun muss man noch auf jedem einzelnen Hyper-V-Host die generellen Einstellungen anpassen. Dazu öffnen wir den Hyper-V Manager, klicken auf Hyper-V Settings und wählen dann links die Option “Live Migrations”. Folgende Einstellungen müssen gesetzt werden:

[x] Enable incoming and outgoing live migrations
[x] Use any available network for live migration (kann auch geändert werden)

-> Links die Option Live Migrations über das + erweitern und auch noch folgende Einstellungen setzen:

[x] Use Kerberos
[x] TCP/IP oder Compression (das eine belastet das Netzwerk länger, das andere dafür die CPU mehr)

 

Schritt 6 – Netzwerke publizieren (Nur beim VMM)
Idealerweise haben Sie die Netze schon immer über den VMM gepflegt, ansonsten wird es hier nochmal sehr trocken. Sobald Sie alle Cluster im VMM integriert haben, sollten Sie die Netzwerke anlegen. Ich kann hier nur jedem ans Herz legen, es vernünftig zu machen, sprich ein Netz pro VLAN. Dies hängt ganz einfach mit den Erweiterungsmöglichkeiten des VMM zusammen, wie z.B. dem App Controller, bei welchem Sie den Usern Clouds zuordnen können (Ja, geht auch ohne, aber hier machts auch Sinn). Den Clouds können Sie verfügbare Netze zuweisen, nicht jedoch nur einzelne VLANs aus einem Netz. Nachdem Sie jedes Netz angelegt und die Haken gesetzt haben, für welche Hosts diese Netze verfügbar sein sollen, müssen Sie nun nochmal bei jedem Host im VMM in die Eigenschaften reingehen. Unter dem Punkt Hardware weisen Sie nun den entsprechenden Netzwerkkarten die verfügbaren VLANs zu. Dies ist leider unumgänglich um VMs mit Netzwerkkarten von A nach B umziehen zu können. Man kann es sich leichter machen mit sogenannten Port-Profiles, danach am Besten einfach mal googlen.

 

Nach diesen Schritten sollte der Live-Migration nichts mehr im Wege stehen. Viel Spaß!

Categories
CRM

rsProcessingAborted – CRM 2011-X Custom Fetch Reports

Betroffene Systeme:
Microsoft Dynamics CRM Server 2011, 2013, 2015

Genaue Beschreibung:
Bei der Ausführung eines selbsterstellten FetchXML-Reports wird einem anstatt des Reports nur folgender Fehler angezeigt:

The report cannot be displayed. (rsProcessing Aborted)

Geht man nun auf den Reporting-Server und schaut in die Logs (Standardpfad: C:\Program Files\Microsoft SQL Server\<Datenbank>\Reporting Services\LogFiles), so wird man unter anderem folgende Meldungen finden:

System.ServiceModel.Security.SecurityNegotiationException: A call to SSPI failed, see inner exception.
System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception.
System.ComponentModel.Win32Exception: The target principal name is incorrect

Ursache:
Die FetchXML-Abfrage muss einen hierfür zuständigen HTTP SPN abfragen können, um korrekt mit dem Reporting-Server kommunizieren zu können. Läuft der CRM Application Pool unter einem Domain-Account, so wird diese Abfrage fehlschlagen, da der SPN nicht von Haus aus gesetzt wird.

Behebung:
Um diesen Fehler zu beheben, sind folgende Schritte notwendig:

  • Im IIS gehen wir auf die CRM-Seite, klicken auf Authentication, highlighten “Windows Authentication” und aktivieren dann unter Advanced Settings den Haken für “Enable Kernel-mode authentication”.
  • Anschließend setzen wir folgende Befehle in der Kommandozeile ab:
    PS> setspn -a “HTTP/<CRM-Srv – Hostname>” “<Application Service User>”
    PS> setspn -a “HTTP/<CRM-Srv – FQDN>” “<Application Service User>”

Damit sollten die FetchXML-Reports wieder laufen.

Categories
Exchange

SMTP Tarpitting – Sinn und Unsinn

Was ist das?

SMTP Tarpitting ist ein pro Empfangskonnektor setzbarer Parameter. Dieser sorgt dafür, dass beim Versand über den jeweiligen Konnektor an eine dem Exchange nicht unmittelbar bekannte Adresse (sprich extern oder nicht vergebene Aliase) eine definierte Verzögerung eintritt.

Macht das Sinn?

Ja und nein. Es macht Sinn für meistens genau einen Konnektor, nämlich den, der Mails von extern empfängt. Wenn man nun versucht, den Exchange-Server mit Spam zu überschütten, wird die ein oder andere falsche Adresse dabei sein, was immer zu einer Verzögerung führt. Vielen Spammern wird das dann letztendlich zu blöd, da sie diese Zeit sinnvoller nützen können.
Keinen Sinn macht es jedoch für interne Relays, die meist zügig die Mails nach außen schieben sollen. Hier wird so manche externe Adresse dabei sein, die diese Verzögerung bewirkt. Viele einfach programmierte SMTP-Konnektoren werden bis die Response kommt sogar komplett freezen. Daher macht dies intern wirklich keinerlei Sinn.

Konfigurieren der Konnektoren

Standardmäßig sind 5sek. pro Konnektor gesetzt. Um beim erstgenannten Empfangskonnektor für Mails aus dem www die Zeit sogar noch zu erhöhen, kann folgender Befehl ausgeführt werden: 

Set-ReceiveConnector “FromInternet” -tarpitinterval 00:00:10

Um z.B. für interne Relays die Tarpitting komlett abzuschalten, ist stattdessen dieser Befehl hier nötig: 
Set-ReceiveConnector “Internal” -tarpitinterval 00:00:00