Alle Beiträge von Uwe Grohne

DCs und RODCs per LDAP Query abfragen

Heute beschäftigte mich mal wieder das Thema, wie man effektiv alle schreibbaren Domain Controller und RODCs in einer Active Directory Domain abfragen kann. Hintergrund war in diesem Fall ein Tool, das für einen Benutzer die Werte von badPwdCount, badPasswordTime, lastLogon und lastLogoff abfragen kann, die in einem AD nicht repliziert werden. D.h. sie müssen von jedem DC abgefragt und der maximale Wert verwendet werden.

Und siehe da, ich fand eine sehr einfache Lösung:

Domain Controller sind automatisch Mitglied der AD-Gruppe “Domain Controllers” und RODCs sind Mitglied der Gruppe “Read-only Domain Controllers” und haben diese auch als primäre Gruppe gesetzt.

Da diese beiden Gruppen builtin sind, haben sie auch immer dieselben RIDs von 516 resp. 512. Damit können die DCs und RODCs sehr einfach über folgende LDAP Queries abgefragt werden:

primaryGroupId=516

für Domain Controller und

primaryGroupId=521

für ReadOnly Domain Controller. Viel einfacher geht es wohl nicht ;).

ADFS 2016: Invoke-AdfsFarmBehaviourLevelRaise schlägt fehl

Nachdem in einer größeren Farm alle ADFS-Server durch Windows Server 2016 ausgetauscht wurden, war das Anheben des Farm Behaviour Levels dran. In der Regel muss hierzu lediglich das Cmdlet Invoke-AdfsFarmBehavourLevelRaise ausgeführt werden, fertig.

Hier aber kam beim Aufruf des Cmdlets jedes Mal die Fehlermeldung:

Invoke-AdfsFarmBehaviorLevelRaise : Database upgrade could not be performed on localhost. Error: Unable to connect to the database. You may not have permission to create the AD FS configuration database in the specified SQL server. You can do one of the following: (1) have the SQL administrator grant permissions to you to create the AD FS configuration database in the specified SQL server or (2) have the SQL administrator create the AD FS configuration database by running  SQL scripts. Use the Export-ADFSDeploymentSQLScript to create the SQL scripts.

After the SQL administrator runs the scripts, try the command again specifying that the database is to be overwritten.

Die Accounts hatten alle die benötigten Rechte, daher war die Fehlersuche sehr schwer. Im Log des SQL Servers standen mehrere Fehlermeldungen:

Login failed for user 'DOMAIN\ADMINUSER'. Reason: Failed to open the explicitly specified database 'AdfsConfigurationV3'. [CLIENT: xx.xx.xx.xx]
Login failed for user 'DOMAIN\ADMINUSER'. Reason: Failed to open the explicitly specified database 'AdfsConfigurationV3'. [CLIENT: xx.xx.xx.xx] 
Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'. Reason: Failed to open the explicitly specified database 'AdfsConfigurationV3'. [CLIENT: xx.xx.xx.xx] 
Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'. Reason: Failed to open the explicitly specified database 'AdfsConfigurationV3'. [CLIENT: xx.xx.xx.xx] 

Das machte die Fehlersuche auch nicht einfacher, denn die Datenbank wurde gar nicht erstellt.

Die Lösung

Nach einem Blick in die Dokumentation des Cmdlets löste sich das Problem per Try-And-Error, denn in dieser Umgebung war die Konstellation etwas komplexer: Die ADFS-Datenbank lag auf einem eigenen Always-On Cluster, das scheint bei dem Cmdlet für Authentifizierungsprobleme zu sorgen.

Die Nutzung der Parameter Credentials und ServiceAccountCredentials, ersterer mit einem Admin-Account, zweiterer mit dem Service Account lief das Cmdlet fehlerfrei durchlaufen:

$admincred = Get-Credential #Admin-Account angeben
$cred = Get-Credential #Service Account angeben
Invoke-AdfsFarmBehaviorLevelRaise -ServiceAccountCredential $cred -Credential $admincred

SharePoint WebTemplate Bug: Listenansichten mit mehreren WebParts

Szenario

Es wird eine Site in SharePoint 2013 erzeugt, die später als Template abgespeichert und mehrfach instanziiert werden soll (z.B. für Projekt-Sites). In dieser Site existieren mehrere Listen. In den Listenansichtsseiten werden jedoch weitere Listenwebparts eingebaut, um z.B. auf einer Page Dokumente und Aufgaben anzeigen zu lassen. WICHTIG: Es werden keine neuen Pages in der Pages-Library erzeugt, sondern direkt in einer Bibliotheksansicht zusätzliche Listen-WebParts eingebaut.

Diese Site wird dann als Template abgespeichert und aus diesem Template eine neue Site erzeugt.

Das Problem

Auf der neu erzeugten Site sind die zusätzlichen Listen-WebParts in den Bibliotheksansichten verschwunden, nur noch das WebPart der Bibliothek/Liste ist vorhanden, zu dem die Ansichtsseite gehört.

Die Lösung

In der ursprünglich für das Erzeugen des Templates genutzten Site muss bei allen WebParts die WebPart-Einstellung “Chrome Type” z.B. auf “Nur Titel” gesetzt werden. Dann werden alle WebParts in das Template aufgenommen und daraus erzeugte Sites beinhalten auch wieder die zusätzlichen WebParts.

AADConnect Upgrade fails: “the provided user is not a member of the enterprise admins group”

In irgendeiner Version seit 1.1.5xx hat Microsoft im Upgrade-Wizard von AADConnect offensichtlich den Code zur Prüfung des Enterprise Admin Accounts geändert, den man im Upgrade Wizard angeben muss.

Unter bestimmten Umständen kann es passieren, dass Accounts nicht funktionieren, obwohl sie Mitglieder der Enterprise Admins-Gruppe des Forests sind, so geschehen jetzt aktuell in einer meiner Umgebungen.

Das Szenario:

  • Der Forest besteht aus einer Root-Domain (z.B. contoso.com) und mindestens einer Subdomain (z.B. corp.contoso.com)
  • Der verwendete administrative Account ist Mitglieder der Gruppe “Enterprise Admins” in der Root-Domain
  • Der verwendete administrative Account befindet sich selbst in einer Subdomain

Und genau der letzte Punkt ist das Problem: Im Code versucht der Wizard die Gruppenmitgliedschaften des angegeben Users aufzulösen, sucht sich hierzu jedoch ein neues DirectoryEntry-Objekt mit Hilfe des samAccountNames und unter Verwendung einer Verbindung zur Root Domain. Und damit erhält man meist keinen User und damit keine Gruppenmitgliedschaften und daher erscheint die Fehlermeldung.

Die einfache Lösung: Der verwendete Account muss sich auch in der Root-Domain befinden, also im Zweifelsfall einen separaten Account anlegen oder den Builtin-Administrator der Root-Domain verwenden.

Kalenderliste mit Serienterminen darstellen

Heute mal wieder eine Anforderung eines Kunden: Auf der Startseite von SharePoint sollten die nächsten anstehenden Termine im Unternehmen angezeigt werden und zwar als Liste, da die Kalenderansicht zu viel Platz weg nimmt.

Problem war dabei, dass in dieser Liste die Serientermine nicht korrekt angezeigt wurden, lediglich der erste Termin erschien, aber alle weiteren Instanzen wurden nicht mehr dargestellt.

Das Phänomen lässt sich leicht nachstellen: Es gibt zwar die Ansicht “Aktuelle Ereignisse”, die auch Serientermine korrekt darstellt, sobald man diese kopiert, ist das Verhalten dasselbe, alle kommenden Serientermine tauchen nicht mehr in der Liste auf. Hintergrund ist, dass ein Serientermin ein einziges Element ist, dass mehrfach abgefragt werden muss. Und die dazu notwendigen Einstellungen können über die Oberfläche nicht gesetzt werden.

Wird die Ansicht also kopiert und modifiziert, muss z.B. per PowerShell das WebPart und die dahinterliegende View verändert werden:

$web = Get-SPWeb "[Url zur Site]"
 $wpm = $web.GetLimitedWebPartManager("[relative Url zur ASPX-Datei]","Shared")
 $wp = $wpm.WebParts | ?{$_.Title -eq "[Titel des WebParts]"}
 $wp.ViewFlags = $wp.ViewFlags -bor [Microsoft.SharePoint.SPViewFlags]::RecurrenceRowset
 $wp.View.Query = "<Where><DateRangesOverlap><FieldRef Name="EventDate" /><FieldRef Name="EndDate" /><FieldRef Name="RecurrenceID" /><Value Type="DateTime"><Now /></Value></DateRangesOverlap></Where><OrderBy><FieldRef Name="EventDate" /></OrderBy>"
 $wpm.SaveChanges($wp)

Dies setzt die notwendigen Einstellungen und danach sollten die Serientermine korrekt dargestellt werden.

Installation von Visual Studio 2015 und SharePoint Server 2013

Heute wollte ich eine neue Entwicklungsumgebung mit den aktuellen Produkten aufbauen:

  • Windows Server 2012 R2
  • SharePoint Server 2013 SP1
  • Visual Studio 2015

Da das Herunterladen des SharePoint Images noch einige Zeit dauerte, habe ich in der Zwischenzeit Visual Studio 2015 installiert. Im Nachhinein hat sich dies als sehr schlechte Idee herausgestellt.

Denn nach dem Ausführen des Prerequisite Installer hat das Setup weiterhin hartnäckig bemängelt, dass .NET 4.5 nicht installiert sei, obwohl dies ja bei Windows Server 2012 R2 standardmäßig installiert ist. Auch diverse Tipps in Foren, wie das Neuinstallieren von .NET oder das Umbenennen der ServerManager.exe in ServerManagerCMD.exe hatten nicht geholfen.

Zu guter Letzt habe ich den Grund doch noch gefunden: VS 2015 installiert .NET 4.6 und hebt damit auch gleich die Versionsangabe von .NET 4 darauf an, die das Setup ausliest. Und damit kommt selbiges noch nicht klar, da es eine Versionsnummer mit 4.5 erwartet.

Doch dies lässt sich glücklicherweise für das Setup über die Registry beheben. Hierzu muss der Wert von “Version” im Key “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client” in die Versionsnummer “4.5.50501” geändert werden.

Aufgrund der Berechtigungen gestaltet sich dies leider etwas schwieriger. Zunächst muss der Besitz des Schlüssels übernommen werden:

Danach muss die Berechtigung für die Administratoren-Gruppe erweitert werden:

Zu guter Letzt wird der Wert geändert:

Danach kann das Setup gestartet werden und sollte ohne Probleme die Key-Abfrage zeigen. Nicht vergessen nach der Installation die Versionsnummer wieder auf den ursprünglichen Wert zu ändern!

Keine Daten in „Berichte zu Beliebtheit und Recherche“

Bis gestern hatte ein Kunde von mir das Problem, dass bei Aufruf eines beliebigen Berichts unter “Berichte zu Beliebtheit und Recherche” in den Site Settings keine Excel-Datei erzeugt wurde und nur die Meldung erschien, dass keine Daten vorhanden sein.

Da es sich um eine bereits seit einem Jahr laufende Plattform mit mehreren Benutzern handelt, konnte das nicht sein, zumal die Berichte schon mal funktionierten.

Nach einer Internetrecherche habe ich festgestellt, dass dieses Problem viele betrifft und habe angefangen, tief in dem System zu graben.

Die Symptome

Lange Rede, kurzer Sinn: Alle Timer Jobs liefen, nur der für die Befüllung der Analytics Reporting DB verantwortliche Job “Usage Log file Import” hat keine Daten erzeugt und im Trace Log die Meldungen

“AnalyticsDataFilter: SPRequestUsageEntry filtered out because tenant settings could not be loaded”

und

“AnalyticsUsageDataImporter: Entries received: 146 Entries filter out: 146”

erzeugt.

Zusätzlich war die AnalyticsDB bis auf Einträge in der Versions-Tabelle komplett leer. Wichtig ist hier vor allem die Tabelle “TenantSettings”, denn genau deswegen wurden diese Meldungen erzeugt.

Die Lösung

Lange habe ich gesucht nach einer Code-Variante, diesen Eintrag wieder zu erzeugen, leider vergeblich. Ich hätte wahrscheinlich die ganze Search Service Application neu erzeugen müssen. Daher habe ich mich entschlossen, den Eintrag aus einem funktionierenden System zu kopieren. Nach etwas Recherche habe ich herausgefunden, dass der Eintrag in allen OnPremise-Umgebungen ohne partitionierte Service Applications gleich sein müssen, somit können alle, die dieses Problem und die Symptome haben, folgendes SQL-Statement einfach auf ihre Analytics-DB los lassen. Natürlich ohne Gewährleistung von meiner Seite ;):

INSERT INTO [dbo].[TenantSettings]

([PartitionId]

,[EventTypeDefinitions]

,[Options]

,[Filters]

,[LastUpdateTime]

,[Version])

VALUES

(0x2B85370CD0348E4191C62AC25AF4BE5B00000000000000000000000000000000

,0x0001000000FFFFFFFF01000000000000000C020000006F4D6963726F736F66742E4F66666963652E5365727665722E5365617263682E4170706C69636174696F6E732C2056657273696F6E3D31352E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D3731653962636531313165393432396305010000004F4D6963726F736F66742E4F66666963652E5365727665722E5365617263682E416E616C79746963732E416E616C79746963734576656E7454797065446566696E6974696F6E436F6C6C656374696F6E02000000095F74656E616E744964185F6576656E7454797065446566696E6974696F6E4C69737403030B53797374656D2E47756964BD0253797374656D2E436F6C6C656374696F6E732E47656E657269632E44696374696F6E61727960325B5B53797374656D2E496E7433322C206D73636F726C69622C2056657273696F6E3D342E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D623737613563353631393334653038395D2C5B4D6963726F736F66742E4F66666963652E5365727665722E5365617263682E416E616C79746963732E416E616C79746963734576656E7454797065446566696E6974696F6E2C204D6963726F736F66742E4F66666963652E5365727665722E5365617263682E4170706C69636174696F6E732C2056657273696F6E3D31352E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D373165396263653131316539343239635D5D0200000004FDFFFFFF0B53797374656D2E477569640B000000025F61025F62025F63025F64025F65025F66025F67025F68025F69025F6A025F6B000000000000000000000008070702020202020202020000000000000000000000000000000009040000000404000000BD0253797374656D2E436F6C6C656374696F6E732E47656E657269632E44696374696F6E61727960325B5B53797374656D2E496E7433322C206D73636F726C69622C2056657273696F6E3D342E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D623737613563353631393334653038395D2C5B4D6963726F736F66742E4F66666963652E5365727665722E5365617263682E416E616C79746963732E416E616C79746963734576656E7454797065446566696E6974696F6E2C204D6963726F736F66742E4F66666963652E5365727665722E5365617263682E4170706C69636174696F6E732C2056657273696F6E3D31352E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D373165396263653131316539343239635D5D040000000756657273696F6E08436F6D7061726572084861736853697A650D4B657956616C756550616972730003000308910153797374656D2E436F6C6C656374696F6E732E47656E657269632E47656E65726963457175616C697479436F6D706172657260315B5B53797374656D2E496E7433322C206D73636F726C69622C2056657273696F6E3D342E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D623737613563353631393334653038395D5D08C10253797374656D2E436F6C6C656374696F6E732E47656E657269632E4B657956616C75655061697260325B5B53797374656D2E496E7433322C206D73636F726C69622C2056657273696F6E3D342E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D623737613563353631393334653038395D2C5B4D6963726F736F66742E4F66666963652E5365727665722E5365617263682E416E616C79746963732E416E616C79746963734576656E7454797065446566696E6974696F6E2C204D6963726F736F66742E4F66666963652E5365727665722E5365617263682E4170706C69636174696F6E732C2056657273696F6E3D31352E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D373165396263653131316539343239635D5D5B5D0B00000009050000001100000009060000000405000000910153797374656D2E436F6C6C656374696F6E732E47656E657269632E47656E65726963457175616C697479436F6D706172657260315B5B53797374656D2E496E7433322C206D73636F726C69622C2056657273696F6E3D342E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D623737613563353631393334653038395D5D00000000070600000000010000000B00000003BF0253797374656D2E436F6C6C656374696F6E732E47656E657269632E4B657956616C75655061697260325B5B53797374656D2E496E7433322C206D73636F726C69622C2056657273696F6E3D342E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D623737613563353631393334653038395D2C5B4D6963726F736F66742E4F66666963652E5365727665722E5365617263682E416E616C79746963732E416E616C79746963734576656E7454797065446566696E6974696F6E2C204D6963726F736F66742E4F66666963652E5365727665722E5365617263682E4170706C69636174696F6E732C2056657273696F6E3D31352E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D373165396263653131316539343239635D5D04F9FFFFFFBF0253797374656D2E436F6C6C656374696F6E732E47656E657269632E4B657956616C75655061697260325B5B53797374656D2E496E7433322C206D73636F726C69622C2056657273696F6E3D342E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D623737613563353631393334653038395D2C5B4D6963726F736F66742E4F66666963652E5365727665722E5365617263682E416E616C79746963732E416E616C79746963734576656E7454797065446566696E6974696F6E2C204D6963726F736F66742E4F66666963652E5365727665722E5365617263682E4170706C69636174696F6E732C2056657273696F6E3D31352E302E302E302C2043756C747572653D6E65757472616C2C205075626C69634B6579546F6B656E3D373165396263653131316539343239635D5D02000000036B65790576616C7565000408454D6963726F736F66742E4F66666963652E5365727665722E5365617263682E416E616C79746963732E416E616C79746963734576656E7454797065446566696E6974696F6E0200000001000000090800000001F7FFFFFFF9FFFFFF02000000090A00000001F5FFFFFFF9FFFFFF03000000090C00000001F3FFFFFFF9FFFFFF04000000090E00000001F1FFFFFFF9FFFFFF00020000091000000001EFFFFFFFF9FFFFFF01020000091200000001EDFFFFFFF9FFFFFF02020000091400000001EBFFFFFFF9FFFFFF03020000091600000001E9FFFFFFF9FFFFFF04020000091800000001E7FFFFFFF9FFFFFF05020000091A00000001E5FFFFFFF9FFFFFF06020000091C0000000508000000454D6963726F736F66742E4F66666963652E5365727665722E5365617263682E416E616C79746963732E416E616C79746963734576656E7454797065446566696E6974696F6E0C000000095F74656E616E7449640C5F6576656E745479706549640A5F636F756E7454797065085F726F6C6C7570730D5F7461696C5472696D6D696E67085F6F7074696F6E730A5F726563576569676874105F72656C6576616E6365576569676874195F726563656E74506F70756C6172697479496E74657276616C0A5F6576656E744E616D65085F6170704E616D65125F637573746F6D4576656E745479706549640300040400040000000101030B53797374656D2E4775696408374D6963726F736F66742E4F66666963652E5365727665722E5365617263682E416E616C79746963732E4576656E74436F756E745479706502000000354D6963726F736F66742E4F66666963652E5365727665722E5365617263682E416E616C79746963732E4576656E74526F6C6C7570730200000008354D6963726F736F66742E4F66666963652E5365727665722E5365617263682E416E616C79746963732E4576656E744F7074696F6E73020000000808080B53797374656D2E477569640200000001E3FFFFFFFDFFFFFF000000000000000000000000000000000100000005E2FFFFFF374D6963726F736F66742E4F66666963652E5365727665722E5365617263682E416E616C79746963732E4576656E74436F756E7454797065010000000776616C75655F5F0008020000000300000005E1FFFFFF354D6963726F736F66742E4F66666963652E5365727665722E5365617263682E416E616C79746963732E4576656E74526F6C6C757073010000000776616C75655F5F000802000000070000000200000005E0FFFFFF354D6963726F736F66742E4F66666963652E5365727665722E5365617263682E416E616C79746963732E4576656E744F7074696F6E73010000000776616C75655F5F0008020000000200000001000000010000000E0000000A0A01DFFFFFFFFDFFFFFF00000000000000000000000000000000010A0000000800000001DEFFFFFFFDFFFFFF000000000000000000000000000000000200000001DDFFFFFFE2FFFFFF0100000001DCFFFFFFE1FFFFFF070000000200000001DBFFFFFFE0FFFFFF0000000000000000010000000E0000000A0A01DAFFFFFFFDFFFFFF00000000000000000000000000000000010C0000000800000001D9FFFFFFFDFFFFFF000000000000000000000000000000000300000001D8FFFFFFE2FFFFFF0100000001D7FFFFFFE1FFFFFF070000000200000001D6FFFFFFE0FFFFFF0000000000000000010000000E0000000A0A01D5FFFFFFFDFFFFFF00000000000000000000000000000000010E0000000800000001D4FFFFFFFDFFFFFF000000000000000000000000000000000400000001D3FFFFFFE2FFFFFF0100000001D2FFFFFFE1FFFFFF070000000200000001D1FFFFFFE0FFFFFF0000000000000000010000000E0000000A0A01D0FFFFFFFDFFFFFF0000000000000000000000000000000001100000000800000001CFFFFFFFFDFFFFFF000000000000000000000000000000000002000001CEFFFFFFE2FFFFFF0100000001CDFFFFFFE1FFFFFF070000000000000001CCFFFFFFE0FFFFFF0200000000000000010000000E0000000A0A01CBFFFFFFFDFFFFFF0000000000000000000000000000000001120000000800000001CAFFFFFFFDFFFFFF000000000000000000000000000000000102000001C9FFFFFFE2FFFFFF0100000001C8FFFFFFE1FFFFFF070000000000000001C7FFFFFFE0FFFFFF0200000000000000010000000E0000000A0A01C6FFFFFFFDFFFFFF0000000000000000000000000000000001140000000800000001C5FFFFFFFDFFFFFF000000000000000000000000000000000202000001C4FFFFFFE2FFFFFF0300000001C3FFFFFFE1FFFFFF070000000000000001C2FFFFFFE0FFFFFF0200000000000000010000000E0000000A0A01C1FFFFFFFDFFFFFF0000000000000000000000000000000001160000000800000001C0FFFFFFFDFFFFFF000000000000000000000000000000000302000001BFFFFFFFE2FFFFFF0100000001BEFFFFFFE1FFFFFF070000000000000001BDFFFFFFE0FFFFFF0200000000000000010000000E0000000A0A01BCFFFFFFFDFFFFFF0000000000000000000000000000000001180000000800000001BBFFFFFFFDFFFFFF000000000000000000000000000000000402000001BAFFFFFFE2FFFFFF0100000001B9FFFFFFE1FFFFFF070000000000000001B8FFFFFFE0FFFFFF0200000000000000010000000E0000000A0A01B7FFFFFFFDFFFFFF00000000000000000000000000000000011A0000000800000001B6FFFFFFFDFFFFFF000000000000000000000000000000000502000001B5FFFFFFE2FFFFFF0100000001B4FFFFFFE1FFFFFF070000000000000001B3FFFFFFE0FFFFFF0200000000000000010000000E0000000A0A01B2FFFFFFFDFFFFFF00000000000000000000000000000000011C0000000800000001B1FFFFFFFDFFFFFF000000000000000000000000000000000602000001B0FFFFFFE2FFFFFF0100000001AFFFFFFFE1FFFFFF070000000200000001AEFFFFFFE0FFFFFF0200000000000000010000000E0000000A0A01ADFFFFFFFDFFFFFF000000000000000000000000000000000B

            ,0

,NULL

,GETDATE()

,1)

 

Damit waren am nächsten Tag dann die ersten Daten wieder da.

CallOutActions-Menu in Listen und Bibliotheken anpassen

Einige Kunden möchten in SharePoint die bestehenden Menüs anpassen und bestimmte Buttons oder hinzufügen. Im Fall des Ribbons, Websiteeinstellungen und anderer Menüs ist das relativ einfach über CustomAction-Definitionen. Das in SharePoint 2013 neu eingeführte CallOut-Menü verhält sich allerdings etwas anders, da es komplett durch JavaScript erzeugt wird:

 

Um dieses anzupassen, muss also ein wenig mit JavaScript entwickelt werden. Problematisch ist hier vor allem, dass es kein entwicklerfreundliches Framework hierfür gibt, sondern das Erzeugen des kompletten Menüs überschrieben werden müsste. Microsoft macht sich das selbst zunutze, wenn des “Following Content”-Feature aktiviert wird: Die Render-Methode wird überschrieben, alle Buttons neu erzeugt und der Follow-Button hinzugefügt. Dies macht die Angelegenheit etwas komplex.

Nach einigen Stunden Arbeit habe ich jedoch eine recht einfache Möglichkeit gefunden, die an die Variante des “Following Content”-Features angelehnt ist: Das darin enthaltene JavaScript ruft eine vom System bereitgestellte Methode auf, die den Edit- und Share-Button erzeugt und nur der Follow-Button ist hardcoded in dem JavaScript. Und genau diese zentrale Methode wird in meiner Variante überschrieben und angepasst. Damit funktioniert die Anpassung sowohl mit Following-Content, als auch ohne.

Für diese Lösung wird nichts weiter benötigt als ein Visual Studio-Projekt mit einem Feature und einer CustomAction-Definition:

<CustomAction
 Id="CustomCalloutOnPostRenderTemplate"
 Location="ScriptLink" ScriptBlock="(function(){
CalloutOnPostRenderTemplate = function CalloutOnPostRenderTemplate(renderCtx, calloutActionMenu) {
var listItem = renderCtx.CurrentItem;
var openText = GetCallOutOpenText(listItem, renderCtx);
calloutActionMenu.addAction(new CalloutAction({
text: openText,
onClickCallback: function(calloutActionClickEvent, calloutAction) {
CalloutAction_Open_OnClick(calloutActionClickEvent, calloutAction, renderCtx);
}
}));
//calloutActionMenu.addAction(new CalloutAction({
// text: Strings.STS.L_CalloutShareAction,
// onClickCallback: function(calloutActionClickEvent, calloutAction) {
// CalloutAction_Share_OnClick(calloutActionClickEvent, calloutAction, renderCtx);
// },
// isVisibleCallback: function(calloutAction) {
// return CalloutAction_Share_IsVisible(calloutAction, renderCtx);
// }
//}));
};
})();"/>
 

Das JavaScript-Snippet definiert hierbei die Methode CalloutOnPostRenderTemplate neu und hierin kommentiere ich einfach die auszublendenden Buttons aus oder kann anhand des Beispiels auch neue erzeugen. Dieses JavaScript wird in das Script-Link-Delegate-Control eingebunden und das Ergebnis sieht dann so aus:

 

Wichtig: Das JavaScript darf nicht in eine externe JS-Datei ausgelagert werden (oder wenn, dann muss deutlich mehr Aufwand betrieben werden), da es ansonsten mit aktivierter “Minimal Download Strategy” nicht mehr funktioniert.

Nützlicher Schalter beim Anlegen eines Identity Providers: SignOutUrl

Vor Kurzem habe ich festgestellt, dass eine derzeit noch undokumentierte Eigenschaft in SharePoint gibt, die es einem erlaubt, beim Anlegen (und auch danach) eines Identity Providers in SharePoint eine SignOut-URL anzugeben.
Dies ist sehr nützlich, da hiermit das Ausloggen aus einer SAML-basierte Infrastruktur, wie z.B. ADFS möglich ist.

Die neue Option lässt sich bei der Verwendung von “New-SPTrustedIdentityTokenIssuer” mit dem Parameter SignOutUrl nutzen oder später mit Hilfe der Eigenschaft ProviderSignOutUrl festlegen.

Für die Nutzung in Verbindung mit ADFS könnte das Setzen der Eigenschaft per PowerShell beispielsweise so aussehen (vorausgesetzt, es gibt nur einen Identity Provider):

$ti = Get-SPTrustedIdentityTokenIssuer
$ti.ProviderSignOutUri = "https://login.firma.de/adfs/ls/?wa=wsignout1.0&wreply={UrlZurWeiterleitungNachSignOut}
$ti.Update()

Damit erspart man sich das leidige Anpassen der Login-Infrastruktur per Code. Die Eigenschaft kam mit einem der letzten Post-SP1-Updates, also zwischen April und Juli.

Probleme bei TMG und Web Application Proxy

Heute hatte ich mal wieder eine interessant Konstellation: Für eine ADFS-Authentifizierung für Office 365 sollte ein ADFS Proxy über das Internet verfügbar gemacht werden. In Windows Server 2012 R2 gibt es hierfür den Web Application Proxy, der gleichzeitig ADFS Proxy ist. Eine separate Rolle gibt es in ADFS 3.0 nicht mehr.

Sollte eigentlich einfach sein: TMG ist bereits im Einsatz, Listener ohne Authentifizierung und mit passendem Zertifikat existiert bereits. Also einfach neue Web Publishing Rule anlegen, mit der entsprechenden URL und auf den WAP zeigen lassen.

Resultat:

Obwohl die Pfade und Adressen alle stimmen, sagt er, er könne den Host nicht finden.

Lösung: Derzeit gibt es keine für dieses Szenario, der Web Application Proxy kann nicht über eine Web Publishing Rule veröffentlicht werden. Wenn man allerdings den ADFS Server direkt published, funktioniert es, aus Sicherheitsgründen empfiehlt es sich aber nicht.

Es gibt zwei Möglichkeiten, dieses Szenario umzusetzen:

  1. Authentifizierung auf TMG und Kerberos-Authentifizierung am ADFS. Nachteil: Der eingegeben Benutzername im Office 365 wird nicht in das TMG-Formular übernommen, das müsste dann noch per JavaScript implementiert werden. Und damit geht natürlich auch nur die interne Authentifizierung, kaskadierte ADFS-Konstrukte sind damit nicht möglich.
  2. Port-Weiterleitung auf den WAP. Sollten allerdings noch andere Publishing Rules auf dem Listener liegen und keine weitere IP-Adresse zur Verfügung stehen, müssen die bestehenden Veröffentlichungen dann auch auf den WAP umgezogen werden und damit der TMG komplett umgangen werden.