SQL Alias – Wenig Arbeit mehr Komfort für Sharepoint Admins


Andreas Rauch

Warum das Leben nicht einfacher gestalten..? Nehmen wir doch mal folgende Fälle an: Man möchte die Datenbanken des Sharepoint Servern auf einen anderen Server umziehen ohne den aktuellen Server herunterzufahren. Oder man entscheidet sich Gründen der “Hochverfügbarkeit”  Datenbanken auf einen Server redundant (per Logshipping bspw) mitlaufen zu lassen. Fällt nun SQL Server 1 aus, soll SQL Server 2 rangehen. Aber wie bekommt man in Sharepoint den Switch hin? Im Falle von Sharepoint würde man nun versuchen, vermutlich in der ZA, die Datenbankserver zu ändern. Oder man ändert im DNS Server die IP Adresse des SQL Servers, so dass nun der gleiche Name, aber eine andere IP Adresse, die des neuen SQL Servers, rangeht. Allerdings bringt diese zweite Lösung nichts, wenn man mit benannten Instanzen arbeitet und sich mehr oder weniger per Zufall der Port des SQL Servers geändert hat. DNS macht keine Port Aliase Aber warum auch so umständlich, wenn es auch leichter geht: mit SQL Alias. SQL Allias Ein SQL Alias ist die sehr sehr einfache Methode auf dem jeweiligen Betriebssystem speziell für SQL Server andere (virtuelle) Namen und Ports für SQL Instanzen bekannt zu geben. Die SQL Aliase gelten sofort .. ab Eintrag! Beispiel: Man hat einen SQL Server SQL1 und zieht die Datenbanken auf SQL2 um. Als SQL Alias legt man einen SQL1 (Port 1433) ein und definiert aber , dass die tatsächliche Instanz der SQL2 auf 1433 ist. Sharepoint oder auch jede andere Software wird diese Settings auf der Stelle verwenden. Wie gehts? SQL Alias mit SQL Konfigurationsmanager Mit dem SQL Server wird auch der SQL Konfigurationsmanager mitgeliefert. In diesem kann man so wichtige Dinge wie Protokolle, Ports, Servicekonten usw einstellen… und eben auch SQL Alias: Es gilt nur ein wenig aufzupassen. Je nach Clientsoftware (32 oder 64-bit) kann man die Aliase vergeben. Im besten Falle vergibt man halt Alias Bezeichnungen für beiden Bereichen. Dazu legt man per rechter Maus einen neuen Alias an, vergibt den Aliasname: Name wie der SQL Server aufgerufen werden soll Portnummer: Port der SQL Server Instanz (Std = 1433) Server: Name des tatsächlichen Servers, auf dem die Instanz zu finden ist. Ergebnis:     Problem   Sofern SQL Server oder die Tools dazu nicht auf dem Server installiert sind, haben wir kein SQL Server Konfigurationsmanager.! Aber wir haben cliconfg.exe   CLIFONFG.EXE Cliconfg macht exakt dasselbe. Nur wo ist das..? Guggste für 32-bit unter c:\Windows\system32 und für 64-bit Clients unter c:\Windows\SysWoW64. Effektiv geben wir exakt die gleichen Informationen ein. Wir schalten zuerst das TCP/IP Protokoll frei, dann vergeben wir einen Alias und die entsprechenden Ports und tatsächlichen SQL Server Maschinen Namen (nicht die Instanznamen).   REGISTRY   Letztendlich sind die Settings in Registry zu finden. und ließen sich automatisiert verteilen, wenn man den entsprechenden Schlüssel exportiert und anschließend editiert:   Sharepoint Wenn Sie sich also einen Gefallen tun wollen, dann verwenden Sie bereits bei der Konfiguration zu Beginn einen SQL Alias. Dann müssen Sie lediglich im Fall des Falles nur den tatsächlichen Server im Alias ändern. Sharepoint und jede andere Software wird das sofort mitmachen.   Falls Sie dies nicht getan haben, können Sie das dennoch auch nachträglich tun. Einfach als Alias den aktuell gültigen SQL Server als Alias eintragen und den neuen SQL Server als tatsächlichen Datenbankserver eintragen. Fertig…   Einfach und große Wirkung!   Verwandte Artikel: SQL Server Multiserver Verwaltung leicht gemacht (17.2) SQL Server: Index Leitfaden – Verwaltung der Indizes durch Rebuild oder Reorganize (15.6) Systemanforderung: Sharepoint 2010 – Datenbank Server (13.7) Komfortable Sicherungen der Sharepointfarm per Powershell (12)

RunWithElevatedPrivilege für SharePoint Apps

Seit längeren ist es im SharePoint Server API möglich, Code mit mehr Rechten auszuführen als der Benutzer der den Code ausführt eigentlich hat. Dadurch können z.B. in Webparts dem Benutzer Aktionen angeboten werden zu denen er keine Berechtigungen hat. Unter SharePoint 2013 gibt es nun das Appmodel in dem kein Server-Seitiger Code vorkommt. Alles wird nur mit ClientObject Model programmiert. In der App-Entwicklung kann es vorkommen, dass eine App mehr Rechte  benötigt als der Benutzer hat. Bei der Installation einer App kann ein Benutzer der App aber immer nur soviel Rechte zubilligen als er selbst hat. Wenn nun eine App eine WebSite erstellen soll, so muss der Benutzer der diese App verwendet auch das Recht zur Anlage einer WebSite haben. Zum Glück hat Microsoft hier Vorkehrung getroffen. App können mehr Rechte bekommen, als der Benutzer der sie ausführt. App-only Security policy Eine App kann entweder User+app policy verwenden oder app-only. Bei User+app muss sowohl der User als auch die App die notwendigen Berechtigungen haben. Bei App-Only hat nur die App die Berechtigungen zu haben. Der Benutzer benötigt diese Rechte nicht. Im SharePoint Umfeld können nur Auto Hosted oder Provider Hosted Apps die App-Only Policy nutzen. Die SharePoint-Hosted Apps können immer nur das User+App Model verwenden. Möchte man nun eine App schreiben, die WebSites anlegen darf, obwohl der Benutzer nur Lese-Rechte hat, muss eine Provider Hosted App erstellt werden. unter “App Dev Umgebung” habe ich beschrieben wie eine Entwicklungsmaschine konfiguriert werden muss um Provider Hosted Apps zu entwickeln. Im App Manifest muss eingestellt werden, dass die App sogenannte “App-only calls” absetzen darf. Dies wird auf der Permissions Seite eingestellt. In der XML Ansicht des Manifests ist dann er Eintrag AllowAppOnlyPolicy=”true” zu finden. Apps die mit AppOnlyPolicy arbeiten können nur von Site-Collections Administratoren installiert werden.   Der richtige ClientContext Im nächsten Schritt ist der Code zu bearbeiten. Die Visual Studio Vorlage einer App startet im Page Load mit Code, der einen ClientContext mit User+App Policy erstellt. var clientContext = TokenHelper.GetS2SClientContextWithWindowsIdentity(hostWeb, Request.LogonUserIdentity) .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Um jedoch einen ClientContext mit App-Only Policy zu erstellen sind folgende zwei Zeilen notwendig: 1: string accessToken = TokenHelper.GetS2SAccessTokenWithWindowsIdentity(hostWeb, null); 2: ClientContext ctx = TokenHelper.GetClientContextWithAccessToken(hostWeb.ToString(), accessToken); .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Hiermit wird zuerst aus einer Server2Server Verbindung das AccessToken abgefragt und dieses zur Erstellung des ClientContext herangezogen. Spannend ist hier, dass die Angabe der Windows Identiy unterbleibt und nur Null übergeben wird. Dies bedeutet dass das Token für die App abgefragt wird. WebSite anlegen ohne Rechte als Beispiel Die oben genannten Punkte, habe ich zu einer Mini App zusammengestellt, die eine WebSite anlegt obwohl der Benutzer dazu keine Berechtigung hat. 1: private ClientContext GetClientContext() 2: { 3: Uri hostWeb = new Uri(Request.QueryString["SPHostUrl"]); 4: string accessToken = TokenHelper.GetS2SAccessTokenWithWindowsIdentity(hostWeb, null); 5: ClientContext ctx = TokenHelper.GetClientContextWithAccessToken(hostWeb.ToString(), accessToken); 6: return ctx; 7: } 8: 9: protected void btAnlegen_Click(object sender, EventArgs e) 10: { 11: string projektName = ProjektNameTextBox.Text; 12: using (ClientContext ctx = GetClientContext()) 13: { 14: WebCreationInformation wci = new WebCreationInformation(); 15: wci.Url = projektName; 16: wci.Title = projektName; 17: wci.WebTemplate = "STS#0"; 18: wci.UseSamePermissionsAsParentSite = true; 19:   20: Web nWeb = ctx.Web.Webs.Add(wci); 21: ctx.Load(nWeb, webSite => webSite.Url); 22: ctx.ExecuteQuery(); 23:   24: linkNewWeb.Text = "Web für " + projektName + " wurde angelegt"; 25: linkNewWeb.NavigateUrl = nWeb.Url; 26: linkNewWeb.Visible = true; 27: } 28: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

Error bei PivotTable Refresh in PowerPivot SharePoint 2013

PowerPivot für SharePoint ist immer für Fehler gut. Leider ist das Problem meist nicht aus der Fehlermeldung erkennbar. Diesmal hatte ich wiedermal einen “An error occured while working on the Data Model in the workbook” Das Datenmodell wurde korrekt in die PowerPivot SSAS-Instanz geladen. Dort war das Problem also nicht zu suchen. Die einzige neue Komponente war die Office Web App Installation innerhalb der Farm. Sobald der Office Web App Server installiert ist, wird für die Anzeige der Excel Dateien dieser verwendet und nicht mehr der in SharePoint eingebaute xlsx-Viewer. Das ist leicht an der URL zu erkennen da die Seite WopiFrame.aspx aufgerufen wird. http://sp1/PowerPivot/_layouts/15/WopiFrame.aspx?sourcedoc=/…. Die Office Web Apps unterstützen leider die BI Feature wie PivotTable und Slicer nicht. Sobald diese in Excel verwendet werden kommt es zu oben genannter Fehlermeldung. Anhilfe schafft man indem für den Dateityp xlsx eine Ausnahme hinterlegt wird. Damit wird der normale ExcelViewer verwendet und die BI Feature stehen wie gewohnt zur Verüfung. in der SharePoint Management Shell ist folgender Befehl auszurufen: New-SPWOPISuppressionSetting –Extension “XLSX” –Action “View” .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }Nach dieser Änderung wird für die Anzeige einer Excel-Datei wieder der eingebaute ExcelViewer verwendet, was anhand der URL geprüft werden kann: http://sp1/PowerPivot/_layouts/15/xlviewer.aspx?id=/P… Das Editieren des Workbooks ist weiterhin mit den Office Web Apps möglich. Um die Änderung rückgängig zu machen, ist folgender Befehl notwendig: Remove-SPWOPISuppressionSetting -Extension "XLSX" -Action View .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

ChromeControl in Provider-Hosted App einbinden.

SharePoint Apps können auf unterschiedliche Arten gehostet werden. Direkt im SharePoint selbst (“SharePoint-hosted Apps”) in Form eines eigenen SubWebs oder in der Cloud. Letztere Variante unterteilt sich widerrum in direkt bei Microsft Azure (“Autohosted”) oder bei einem beliebigen Anbieter bzw. Webserver (“Provider-hosted”) gehostete Apps. Die SharePoint hosted Apps besitzen automatisch das typische SharePoint 2013 Look&Feel (Styles, Navigationsleiste, WebsiteAktionen-Link etc.). Bei Provider- bzw. Autohosted Apps sucht man dies vergeblich. Damit jedoch auch solche Apps optisch reibungslos innerhalb der bisherigen SharePoint 2013 Umgebung bereitgestellt werden können, muss das sog. “Chrome Control” eingebunden werden. Zunächst ist in Visual Studio eine App für SharePoint 2013 anzulegen. Anschließend wird “Provider-hosted” oder ggf. auch “Autohosted” als Typ gewählt. Nun muss ggf. ein Zertifikat ausgewählt werden. Wie dies einzurichten ist, wurde bereits in diesem Blogeintrag ausführlich erläutert. In einem ersten Testlauf soll das “Problem” zunächst dargestellt werden. Dazu kann in der “Default.aspx” innerhalb der <div>-Tags im zur Zeit noch leeren <body>-Bereich einmal eine Überschrift eingefügt werden: <h1>Hallo Welt!</h1> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Nun kann das Projekt auch schon debuggt werden (F5). Im Anschluss öffnet sich der Browser und die App muss als vertrauenswürdig erklärt werden.   Danach wird direkt die App geöffnet. Wie unschwer zu erkennen ist, ohne SharePoint Look&Feel.   Um dies zu ändern, muss zunächst eine Referenz auf die JavaScript Bibliothek “SP.UI.Controls.js” eingbeunden werden via Object-Explorer –> Kontextmenü Scripts –> Add –> Existing Item –> [SP root folder]\TEMPLATE\LAYOUTS\SP.UI.Controls.js   Nachem die “SP.UI.Controls.js” hinzugefügt wurde, ist sie – ggf. neben der jquery-Bibliothek - nun noch im <head>-Bereich der aspx-Page zu referenzieren. <script type="text/javascript" src="../Scripts/sp.ui.controls.js"></script> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Die App soll neben der aspx-Page aber auch noch das AppIcon anzeigen, welches dazu einfach aus dem Manifest-Bereich in den Pages-Ordner innerhalb des Provider-Bereichs (welcher sich standardmäßig als automatisch angelegte Webanwendung unterhalb der Standard-Webanwendung im IIS befindet) kopieren lässt.   Schließlich folgt das Einbinden der eigentlichen Chrome-Controls im Code der aspx—Page: 1: <body> 2: <div id="chrome_ctrl_container" data-ms-control="SP.UI.Controls.Navigation" data-ms-options= 3: '{ 4: "appTitle" : "Provider Hosted App with Chrome Control", 5: "appIconUrl" : "AppIcon.png", 6: "settingsLinks" : [ 7: { 8: "linkUrl" : "http://www.ppedv.de", 9: "displayName" : "visit ppedv" 10: } 11: ] 12: }'> 13: </div> 14: <form id="form1" runat="server"> 15: <div> 16: <h1 class="ms-accentText">Hallo Welt!</h1> 17: <h2 class="ms-accentText">Überschrift 2</h2> 18: <div id="MainContent">Dies ist Standard Text...</div> 19: </div> 20: </form> 21: </body> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Die Properties “appTitle” und “appIconUrl” sind selbsterklärend. Die “settingsLinks” können u.a. dazu verwendet werden, im WebsiteAktions-Menü (Zahnrad rechts oben) einige Hyperlinks zu hinterlegen. Falls beim erneuten Debuggen folgender Warnhinweis erscheint, kann dieser u.U. durch das Deaktivieren der SSL-Verbindung, welche standardmäßig für alle SharePoint Apps immer aktiviert ist, zukünftig vermieden werden. Dazu ist im Solution-Explorer die Property “SSL Enabled” der ProviderHostedApp auf “False” zu setzen.  Letztendlich erhält die App durch Einbinden des Chrome-Controls das SharePoint-typische Look&Feel, wie die folgende Grafik zeigt.

Eigenes Website-Template mit Masterpage und CSS als Farmsolution bereitstellen

Heute möchte ich zeigen, wie ein benutzerdefiniertes Website-Template inkl. eigener Masterpage und CSS-Datei als Farmsolution bereitgestellt werden kann. Im Beispiel habe ich das OrangeWebsite-Template von FreeSMP als benutzerdefinierte Masterpage verwendet. Zunächst ist in Visual Studio ein neues SharePoint Projekt vom Typ “Site Definition” als Farmsolution zu erstellen. Zum Einbinden der eigenen Masterpage ist dem Projekt im Solution Explorer mittels Kontextmenü –> Add –> New Item ein Modul hinzuzufügen. Diesem sollte gleich beim Erstellen ein aussagekräftiger Name verfgeben werden (im Bsp. “NewMasterPageModule”). Im neu erschienenen Modulordner ist anschließend ein Unterordner namens “_catalogs” und in diesem widerum einer names “masterpage” zu erstellen. Im Ordner Masterpage wird nun via Kontextmenü –> Add –> Existing Item die Masterpage importiert (vgl. Abbildung in Schritt 9). In der Elements.xml des Moduls sind weiterhin die Deployment-Pfade wie folgt anzupassen, damit die Masterdatei in den Catalogs-Bereich der Zielwebsite kopiert wird, wo auch die anderen Masterpages liegen. 1: <?xml version="1.0" encoding="utf-8"?> 2: <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> 3: <Module Name="NewMasterpageModule" Url="_catalogs/masterpage"> 4: <File Path="NewMasterpageModule\_catalogs\masterpage\OrangeWebsite.master" Url="OrangeWebsite.master" /> 5: </Module> 6: </Elements> Die Css-Datei wird nun über ein mapped-SharePoint Folder hinzugefügt. Dies geschieht im Kontextmenü des Projekts –> Add –> SharePoint Mapped Folder –> mit folgender Location: {SharePointRoot}\Template\LAYOUTS\1033\STYLES\. In diesen Mapped Folder wird nun die CSS importiert (Kontextmenü –> Add –> Existing Item). Gleiches Verfahren kann noch für ein Vorlagen-Image wiederholt werden. In dem Fall allerdings mittels Add –> SharePoint “Images” Mapped Folder und anschließend das Bild hier importieren. Das Vorlagen-Image dient später beim Erstellen einer neuen Website auf Basis des eigenen Website-Templates als Icon bzw. Symbol. Nun muss noch die CSS korrekt innerhalb der Masterpage referenziert werden. Dies geschieht mittels folgender Zeile: <SharePoint:CssRegistration name="OrangeWebsite.css" After="corev4.css" runat="server"/> Die Markierung zeigt die Stelle innerhalb der Masterpage, an der die Anpassung vorgenommen wird: Damit die Masterpage innerhalb der Website-Vorlage überhaupt verwendet werden kann, muss sie innerhalb eines Features bereitgestellt werden. Wenn dem Projekt das erste Artefakt (in unserem Bsp. das Modul für die Masterpage) hinzugefügt wird, erzeugt Visual Studio automatisch ein Feature, welches als Paketierungseinheit für das hinzugefügte Modul dient. Aus Gründen der Übersichtlichkeit und besseren Lesbarkeit empfiehlt es sich, Features mit Hilfe eines aussagekräftigen Namens umzubenennen (z.B. “MasterPage Feature”). Dies geschieht – genau wie das Einstellen des Feature-Scopes auf “Web” – im Feature Designer (Doppelklick auf das Feature oder über Kontextmenü). Anschließend muss der SiteDefinition (in der Datei Onet.xml) noch die Referenz auf die benutzerdefinierte Masterdatei eingebunden werden. Dies erfolgt zum einen durch das Einfügen des MasterUrl- und CustomMasterUrl-Properties im Configuration-Tag <Configuration ID="0" Name="OurTemplate" MasterUrl="_catalogs/masterpage/OrangeWebsite.master" CustomMasterUrl="_catalogs/masterpage/OrangeWebsite.master"> und zum anderen durch das Einbinden des MasterPage Features im Abschnitt “WebFeatures”. Die FeatureID kann im Feature-Designer unter “Manifest” ermittelt werden. <WebFeatures> <Feature ID="e627ebdf-38eb-4d87-94b1-bdd8e41a3771"></Feature> </WebFeatures>   Optional: Wie in Punkt 8 anhand der Attribute zu erkennen ist, wird unterschieden zwischen Standard- (MasterUrl) und benutzerdefinierter (CustomMasterUrl) Masterpage. In diesem Beispiel soll die OrangeMaster sowohl Default als auch Custom Masterpage darstellen. Folgender Schritt ist daher optional und nur dann wichtig, wenn mit Veröffentlichungsseiten (Publishing Pages) gearbeitet werden soll und diese eine andere Masterpage verwenden, als “normale” aspx Pages. Soll bspw. die mitgelieferte “Default.aspx” die Custom-Masterpage verwenden, ist in Zeile 1  der Default.aspx das MasterPageFile Attribut auf "~masterurl/custom.master" zu setzen. Nachdem der Lösung alle Artefakte hinzugefügt und ggf. umbenannt wurden, sollten im Solution-Explorer zusätzlich folgende Einträge vorhanden sein:  Zum Testen kann nun mit dem Debuggingvorgang begonnen werden (F5) und auf der Seite im Browser eine neue Website basierend auf dem eigenen Website-Template erzeugt werden. Der Eintrag dazu befindet sich standardmäßig in der Kategorie “SharePoint Customizations”. Anschließend wird die Default.aspx als Startseite der neu erstellten Website aufgerufen basierend auf der eigenen Masterpage bzw. CSS-Datei.  Wenn das Projekt den Anforderungen entspricht kann der Solution Status auf Release gesetzt und im Solution Explorer im Kontextmenü der Lösung mittels “Package” die wsp-Datei erzeugt werden. Diese befindet sich dann im Projktordner unter \bin\Release\ und kann wie üblich mittels Powershell deployt werden.

KeywordQuery Class–deprecated

Unlängst habe ich wieder einmal die KeywordQuery Klasse für ein SharePoint Webpart verwendet. Allerdings kam beim Kompilieren das Warning: “  [deprecated ]” was mich, ehrlich gestanden, etwas verwundert hat. Interessanterweise wird jedoch im MSDN die Klasse im Detail beschrieben. (msdn) Jedoch ist die Lösung einfach. Früher gab es die Klasse im Namespace “Microsoft.SharePoint.Search.Query”. Diese Klasse ist nun veraltet und wird in der nächsten Version nicht mehr enthalten sein. Sucht man im MSND nach dem Begriff “KeywordQuery” wird leider als erstes Suchergebnis die veraltete Klasse angezeigt. Der richtige Namespace ist “Microsoft.Office.Server.Search.Query”. Bei der Auswahl der dll, die bei bei Referenzen anzugeben ist, muss darauf geachtet werden die richtige auszuwählen! Leider liegen beide Dateien im ISAPI Verzeichnis des SharePoint Servers.

Entity Framework 5.0 in SharePoint 2013 nutzen

Um den Datenzugriff innerhalb von Webparts einfach zu gestalten, kann das Entity Framework innerhalb eines SharePoint Projektes genutzt werden. Allerdings gilt es einige “Kleinigkeiten” zu beachten. Zunächst wird ein “Entity Data Model” zum Projekt hinzugefügt, jedoch kann der Connections-String nicht in der App.Config gespeichert werden. Hürde 1 das EF Assembly wird vom SharePoint Server nicht geladen, da diese nicht als SafeControl eingetragen ist. Um einen SafeControl Eintrag zu setzen, muss das Package-Manifest bearbeitet werden. In der Karteikarte “Advanced” kann mit “add” ein Assembly eingetragen werden. Hürde 2 Bis zum EF 4 konnte bei der Initialisierung des Context ein Connection String angegeben werden. EF 5 bietet diesen Konstruktor nicht mehr. Die Context Klasse ist jedoch als partial Class definiert, daher kann ein eigener Konstruktor, der einen Connections String übergeben bekommt definiert werden. In das Projekt ist eine weitere Klasse aufzunehmen, die folgenden Code enthält: 1: public partial class Entities : DbContext 2: { 3: public Entities(string ConnectionString) 4: : base(ConnectionString) 5: { 6: } 7: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } Nachdem die Klasse geschrieben ist, kann der Connection String formuliert werden. Wichtig ist, dass der vollständige, für das EF formulierte Connection String verwendet wird. Sollte nur ein “simpler” SQL Server Connection String verwendet werden, kann es zu einer UnintentionalCodeFirstException kommen. Der Connection String kann aus dem “Update Model from Database”-Dialog kopiert werden. Die im Connection String verwendeten doppelten Hochkomma können durch einfache Hochkomma ersetzt werden. Im Connection String muss noch die User Information angepasst werden. Im Code BSP wird diese Information hardcoded im Source Code abgelegt. Eine Erklärung wie die Credentials im Secure Store Service abgelegt und wieder abgefragt werden können ist hier zu finden. Der Code für die Datenabfrage sieht nun so aus: 1: string co = @" 2: metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl; 3: provider=System.Data.SqlClient; 4: provider connection string='data source=server1; 5: initial catalog=Northwind; 6: user Id=sa; 7: password=ppedvAG 8: MultipleActiveResultSets=True; 9: App=EntityFramework' 10: "; 11:   12: Entities ctx = new Entities(co); 13:   14: var erg = from c in ctx.Customers 15: select c; .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

SharePoint 2013 Workflowmanager–configuration not present

Nach einer Installation des Workflowmanagers konnten zwar mit dem SharePoint Designer Workflows mit der neuen Worflowengine erstellt werden. Jedoch die mit Visual Studio erstellte Workflows konnten nicht gestartet werden. Beim Debuggen erscheint im Command Prompt eine Fehlermeldung. Leider zu kurz um sie zu lesen. Aber die Zeit reicht um mit Print Screen den Bildschirm zu speichern und dann in Ruhe die Fehlermeldung zu studieren: System.IO.InvalidDataException: A required Workflow Manager configuration ‘WorkflowService.ScopeSnapshotProcessBatchSize’ is not present. Nun kann dieser Wert mit der Powershell eingetragen werden, allerdings fehlt dann ein anderer Konfigurationswert. Das Warum für diesen Fehler konnte ich nicht klären. Aber nach der Installation des CU 1 für der Service Bus und danach der Installation des CU 1 des Workflowmanagers funktionieren die Workflows wieder wie gewohnt. Wichtig ist dass die Updates mit jenem Useraccount eingespielt werden, welcher damals zur Erstinstallation des Workflowmanagers verwendet wurde und die Reihenfolge muss beachtet werden. Zuerst Service Bus und dann Workflowmanager. Cumulative Update for Service Bus 1.0 (KB2799752)  Download Cumulative Update for Workflow Manager 1.0 (KB2799754) Download

Website-Template farmweit als SiteCollection bereitstellen

Es ist relativ einfach, eine SharePoint-Websites als Template (Lösungspaket in Form einer wsp-Datei) zu exportieren, und diese dann für künftige, neu zu erzeugende Websites als Vorlage zu verwenden. Etwas kniffeliger wird es, wenn die exportierte Website als Vorlage für weitere SiteCollections auf Farmebene in der Zentraladministration bereitgestellt werden soll. Für diesen Fall ist es notwendig, die exportierte wsp-Datei – insbesondere deren Anwendungsbereich (Scope) - in Visual Studio zu modifizieren.  In den folgenden Schritten wird diese Anpassung beschrieben. Zunächst ist die Quell-Website in den Websiteeinstellungen zu exportieren und die erzeugte wsp-Datei lokal zu speichern. Diese wsp-Datei muss nun in Visual Studio als neues Projekt importiert werden. Dabei ist die Option Farmlösung auszuwählen und anschließend im nächsten Fenster die lokal gespeicherte wsp-Datei auszuwählen. Im Anschluss kann noch festgelegt werden, welche Inhalte (Spalten, Inhaltstypen, Listeninstanzen etc.) mit enthalten sein sollen. Standardmäßig sollte alles ausgewählt sein.   Anschließend erscheint die Meldung, dass der Importvorgang erfolgreich abgeschlossen wurde. Optional: es bietet sich an, den Feature-Ordnern aussagekräftigere Namen als Feature1 bis n (bei einer leeren Teamwebsite standardmäßig 4 Features, je nach bereits implementierten Inhalten der Quellwebsite ggf. mehr) zu geben. Hierzu ist es nützlich zu wissen, welche Features welche Elemente beinhalten. Dies lässt sich in Erfahrung bringen, indem doppelt auf das Feature geklickt wird, wodurch sich der Feature Designer öffnet. Das Textfeld “Title” verrät, was in diesem Feature enthalten ist. Im rechten Bereich “Items in this Feature” können außerdem sämtliche Inhalte des Features betrachtet werden. Das “Feature1” in folgfender Grafik beinhaltet bspw. Listeninstanzen und Inhaltstypen des Website. Nun kann der Featureordner (rechts im Solution Explorer) umbenannt werden. Dieser Schritt ist ggf. für alle Features zu wiederholen. Optional: im Anschluss empfiehlt es sich, alle Features, außer das Feature mit dem WebTemplate, auszublenden. Dadurch tauchen diese später nicht gesondert in den Websiteeinstellungen –> WebsiteFeatures auf, was Verwirrung stiften kann. Dazu im unteren rechten Bereich “Properties” das Attribut “IsHidden” auf True setzen. Nun muss die wichtigste Änderung vorgenommen werden: Den Scope des WebTemplate-Features auf “Farm” ändern. Jetzt kann zum Testen ein Debuggingvorgang gestartet (F5) und auf der Zielwebsite eine neue Website auf Basis der Vorlage erzeugt werden. Schließlich muss die Lösung deployt werden. Dazu den Entwicklungsstatus auf “Release” setzen und im Kontextmenü des Projekts die Option “Package” wählen. Dadurch wird eine wsp-Datei im Release-Ordner innerhalb des Projektordners erzeugt.  Für den produktiven Deploymentvorgang (auf Entwicklungsumgebungen kann dies auch direkt das Visual Studio übernehmen mit dem Befehl “Deploy”) wird empfohlen, diese Solution nun via SharePoint Management Shell bereitzustellen. Dies erfolgt in 2 Schritten. - Befehl zum upload der Solution an die Zentraladministration: Add-SPSolution [Laufwerksbuchstabe]:\[Pfad und Name der Solution].wsp - Befehl zum deployment der Solution: Install-SPSolution –identity [Name der Solution].wsp -gacdeployment Nun kann die Farmlösung getestet und eine neue SiteCollection erzeugt werden. In der Zentraladministration –> “Application Managemnent” –> “Create Site Collections” sollte im Bereich “Custom” die neue Vorlage auftauchen. Im Anschluss sollte eine Meldung die erfolgreiche Erstellung einer neuen SiteCollection – und somit einer neuen Website oberster Ebene (root Website) auf Basis des benutzerdefinierten Templates bestätigen:

SharePoint Liste mit Outlook verbinden

Dank der fortgeschrittenen Integration zwischen SharePoint und Microsoft Office ist es mit nur wenigen Mausklicks möglich, eine SharePoint-Liste mit der lokalen Outlook Anwendung zu verbinden. Somit ist eine bilaterale Datensynchronisation möglich, d.h. das Pflegen der Informationen kann sowohl über die SharePoint Weboberfläche als auch direkt in Outlook erfolgen. Im folgenden Beispiel wird anhand einer Kontaktliste gezeigt, wie eine SharePoint Liste in Outlook eingebunden werden kann. Auf der Weboberfläche zur Zielliste navigieren -> Im Menüband Register „Liste“ -> Gruppe „verbinden und exportieren“ -> Schaltfläche „Verbindung mit Outlook herstellen“ anklicken. Es wird eine Sicherheitswarnung angezeigt, die mit „Zulassen“ bestätigt werden muss. In Outlook wird auch eine Warnung angezeigt, diese mit „Ja“ bestätigen. Die Kontaktliste aus SharePoint wird mit im Bereich Kontakte in Outlook mit angezeigt.   Diese Vorgehensweise funktioniert neben Kontaktlisten analog auch mit allen anderen für Outlook relevanten Listentypen wie Aufgaben und Kalendern.