<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Build on SharePoint</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/sambetts/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/sambetts/feed.xml</link>
    <description>The blog of Sam Betts on SharePoint application development - full of lot&amp;#039;s of useful info, guides, and various cats.</description>
    <lastBuildDate>Tue, 12 Sep 2017 19:52:50 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Umbrella Corporation Theme for ADFS</title>
      <link>https://docs.microsoft.com/archive/blogs/sambetts/umbrella-corporation-theme-for-adfs</link>
      <pubDate>Fri, 23 Jun 2017 10:59:16 GMT</pubDate>
      <dc:creator><![CDATA[Sam Betts MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sambetts/?p=2745</guid>
      <description><![CDATA[So I got bored the other day, and decided it was high time my ADFS server had something more...]]></description>
      <content:encoded><![CDATA[So I got bored the other day, and decided it was high time my ADFS server had something more inventive than the out-the-box look.

<strong>Fair use disclaimer</strong>: in case it’s not obvious, Umbrella Corp is a made-up company from the <a href="https://en.wikipedia.org/wiki/Umbrella_Corps">Resident Evil universe </a>and isn't public IP. I’m using it because I love a good Sci-Fi flick and it’s as good a fake corporate entity as any to borrow for a test-lab. Fair use and all that – the point of this is to show how to theme ADFS, and to share my hacky theme (download files below too).

After some hacking around I ended up with this theme below:

<img width="742" height="570" alt="" src="https://pbs.twimg.com/media/DC64OwwXoAEezix.jpg:large" />

This is what happens when you’re bored in a hotel somewhere.
<h1>How Does Theming Work in ADFS?</h1>
Given ADFS isn’t exactly an normal app in IIS, theming ADFS is a bit trickier than normal. What you can include in a theme is tightly controlled so as to not compromise security of what’s actually quite a serious role for ADFS server – being a security gateway into all the things.

So if you want to customise how ADFS looks, first of all you have to create an ADFS “theme” to package up your customisations. A theme consists of the following elements:
<ol>
 	<li>Logo (image).</li>
 	<li>Illustration (image).</li>
 	<li>Stylesheet (CSS).</li>
 	<li>Runtime stylesheet (CSS).</li>
 	<li>JavaScript to run “on load”.</li>
 	<li>Additional file resources.</li>
</ol>
Each element can have a specific locale too if you want; i.e. a stylesheet for Spanish, another for English. You put together a theme with those elements (you can export an existing theme to base new themes on), then make the theme active and that’s it. All in PowerShell.

So as my theme is a bit craptastic, I did it by just adding a couple of hand-hacked images I borrowed + a custom stylesheet with the references in this script:
<blockquote>New-AdfsWebTheme -Name "umbrella-theme" -SourceName default

Set-AdfsWebTheme -TargetName "umbrella-theme" -AdditionalFileResource  @{Uri="/adfs/portal/images/caution.PNG";Path="S:\Umbrella-ADFS-theme\images\caution.PNG"}

Set-AdfsWebTheme -TargetName "umbrella-theme" -AdditionalFileResource  @{Uri="/adfs/portal/images/UmbrellaBack.jpg";Path="S:\Umbrella-ADFS-theme\images\UmbrellaBack.jpg"}

Set-AdfsWebTheme -TargetName "umbrella-theme" -StyleSheet @{Locale="";path="S:\Umbrella-ADFS-theme\css\style.css"}

Set-AdfsWebConfig -ActiveThemeName "umbrella-theme"</blockquote>
That’s it. Files available <a href="https://msdnshared.blob.core.windows.net/media/2017/06/Umbrella-ADFS-theme.zip">here</a>.]]></content:encoded>
    </item>
    <item>
      <title>Introduction to MySQL &amp; PHP on Azure App Services (WIMP)</title>
      <link>https://docs.microsoft.com/archive/blogs/sambetts/introduction-to-mysql-php-on-azure-app-services-wimp</link>
      <pubDate>Sun, 21 May 2017 12:59:09 GMT</pubDate>
      <dc:creator><![CDATA[Sam Betts MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sambetts/?p=2735</guid>
      <description><![CDATA[As there doesn’t seem to be masses of info on how PHP works on Azure App Services, I figured I’d do...]]></description>
      <content:encoded><![CDATA[<p>As there doesn’t seem to be masses of info on how PHP works on Azure App Services, I figured I’d do something around on the subject now having played around with it a bit. <p>PHP has been an option for an Azure web-app runtime for a while now as you may have noticed already: <p><a href="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image00234.jpg"><img title="Azure App Services" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="Azure App Services" src="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image002_thumb25.jpg" width="566" height="346"></a> <p>That’ll give you IIS with PHP configured through FastCGI. Read more about how it’s setup @ <a href="https://docs.microsoft.com/en-us/azure/app-service-web/web-sites-php-configure">https://docs.microsoft.com/en-us/azure/app-service-web/web-sites-php-configure</a> if you want. <p>There is a Linux option too for full LAMP as a service, but I’ve not looked in it yet.  <h3>What is Azure App Services?</h3> <p>If you’re wondering what app services even are, here’s my own, brief explanation with the official explanation <a href="https://azure.microsoft.com/en-us/services/app-service/">here</a>.  <p>App Services is “platform as a service”, for anything web-server related. What that means in reality is you don’t have to worry about managing the underlying machines that run your code; we (the Azure guys) are responsible for that, and you just focus on your code. It’ll “just work”! <p>More specifically, we’ll handle patching, uptime, load-balancing, core OS configuration, etc, etc; you just have to make sure you’ve configured your “app service” the way you want – what code is on it, what logging &amp; monitoring you want to see.  <p>For performance vs cost, you say how much it needs to scale vs how much money you want to spend. There’s all sorts of options for scaling automatically, manually, on a schedule, etc, etc. Free is an option, but obviously that’ll go rather slow if anyone actually hits the website in any real amount. <h3>MySQL in App</h3> <p>Something available in App Services is something called “MySQL in App” which is a cost-effective way of getting MySQL running. Here it is:  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image00418.jpg"><img title="Azure App Services" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="Azure App Services" src="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image004_thumb11.jpg" width="330" height="397"></a> <p>I say cost-effective because of how MySQL runs, which is basically within the same virtual-machine that also runs the PHP code, so you don’t have to pay any more for a database tier.  <p>Obviously, this limits scalability quite significantly; you’re sharing the same CPU &amp; memory with IIS/PHP, but it is cheap. Free even, if you run the free service-tier.  <p>Want to scale-up? You can offload the MySQL part to <a href="https://azure.microsoft.com/en-us/services/mysql/">Azure Database for MySQL</a> and scale as much as you want. Azure Database is “database as a platform”, and now there’s a MySQL flavour too. <h4>Running MySQL under IIS</h4> <p>So, the first thing to realise about MySQL in App is it runs within the context of IIS itself, hence the “in app” part. <p>Here we see a MySQL log-file from a MySQL process that’s just been spun-up: <p><a href="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image00618.jpg"><img title="Azure App Services" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="Azure App Services" src="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image006_thumb12.jpg" width="575" height="406"></a> <p>Note the process ID of MySQL… <p>Now if we check out the environment process-explorer in Kudu (available under the “advanced tools” blade in the portal): <p><a href="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image00813.jpg"><img title="Azure App Services" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="Azure App Services" src="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image008_thumb8.jpg" width="591" height="243"></a> <p>Also notice “mysqld.exe” is running under w3wp.exe (IIS worker process). <p>This is fairly significant; it means that is we have no IIS worker-process, we have no database in the “MySQL in App” setup. That in turns means, if nobody’s hitting the site, we have no database running! See below for why &amp; how. <p>Also worth noting, and this is a potentially big deal for production sites especially, the “free” tier in app-services doesn’t give you the App-Services “always on” setting. This means IIS will eventually unload itself after a certain amount of activity…unloading your database engine with it.  <p>That is until someone hits the site anyway, which will trigger a new worker-process and start-up another MySQL instance too. <h4>phpMyAdmin on App Services</h4> <p>phpMyAdmin is a very popular admin tool for MySQL and if you’re running “MySQL in App” then you actually already have it installed, despite phpMyAdmin being an extension you can install. <p>Click on the “MySQL In App” blade and you’ll see the config + a link to the pre-installed phpMyAdmin via the “manage” button. <p><a href="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image01011.jpg"><img title="Azure App Services" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="Azure App Services" src="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image010_thumb6.jpg" width="244" height="104"></a> <p>Clicking that will open phpMyAdmin. It’ll open on the admin “SCM” URL for the website (i.e. be secured the same way Azure portal is). <p>Interestingly, if you’ve not hit the website yet &amp; spawned an IIS worker-process then MySQL won’t be running, and you’ll hit a connection error: <p><a href="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image01210.jpg"><img title="Azure App Services" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="Azure App Services" src="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image012_thumb5.jpg" width="534" height="287"></a> <p>Hit the website; that’ll spawn a worker-process + MySQL, and then phpMyAdmin should now work. <p><a href="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image0149.jpg"><img title="Azure App Services" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="Azure App Services" src="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image014_thumb4.jpg" width="563" height="221"></a> <p>Pro-tip: don’t install the phpMyAdmin extension if you have the “MySQL in App” option already. Seriously don’t; you’ll kill the nicely pre-configured instance.  <h3>Connection String to MySQL</h3> <p>Where’s the connection-string for PHP then? Having played around with the WordPress App Services template, this is where it seems to be: <p><a href="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image01610.jpg"><img title="Azure App Services" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="Azure App Services" src="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image016_thumb5.jpg" width="547" height="380"></a> <p>Opening the file &amp; here’s the string: <p><a href="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image0188.jpg"><img title="Azure App Services" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="Azure App Services" src="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image018_thumb3.jpg" width="504" height="102"></a> <p>Sharper-eyed readers may have noticed above; this connection-string is normally available via environment variable “MYSQLCONNSTR_localdb”, which is what WordPress at least uses for its connections to the database. <h3>Transferring Files into App Services</h3> <p>Finally, as this is a bit of a n00b article, how do we get files on &amp; off the website? <p>GitHub integration is probably the best way, but if you want a more traditional way too FTP is an option. <p>Configure deployment credentials first: <p><a href="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image0206.jpg"><img title="Azure App Services" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="Azure App Services" src="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image020_thumb1.jpg" width="456" height="219"></a> <p>Then, download the publishing profile: <p><a href="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image0222.jpg"><img title="Azure App Services" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="Azure App Services" src="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image022_thumb.jpg" width="530" height="160"></a> <p>That’s basically an XML file with various ways of publishing files to the app-service, one of which is the FTP method: <p><a href="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image0242.jpg"><img title="Azure App Services" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="Azure App Services" src="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image024_thumb.jpg" width="442" height="134"></a> <p>(and yeah, this was a throwaway app-service, so don’t try and connect :P). <p>Lo &amp; behold, the server files: <p><a href="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image0262.jpg"><img title="Azure App Services" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="Azure App Services" src="https://msdnshared.blob.core.windows.net/media/2017/05/clip_image026_thumb.jpg" width="536" height="317"></a> <p>Upload &amp; download to your hearts’ content! <p>That’s it for now - cheers! <p>// Sam Betts]]></content:encoded>
    </item>
    <item>
      <title>Excel Data Connection Refreshes in SharePoint 2016 &amp; Office Online 2016</title>
      <link>https://docs.microsoft.com/archive/blogs/sambetts/excel-data-connection-refreshes-in-sharepoint-2016-office-online-2016</link>
      <pubDate>Tue, 25 Apr 2017 16:59:20 GMT</pubDate>
      <dc:creator><![CDATA[Sam Betts MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sambetts/?p=2495</guid>
      <description><![CDATA[Here’s a quick run-through on how to refresh data connections in Excel files stored in SharePoint,...]]></description>
      <content:encoded><![CDATA[<p>Here’s a quick run-through on how to refresh data connections in Excel files stored in SharePoint, via Office Online, 2016 edition.  <p>Things have moved around in SharePoint 2016; no longer does Excel services exist in SharePoint-land, so refreshing Excel data-sources on the web has changed a bit. This is a quick guide on how to get the same setup in the year of our Lord, 2016 AD.  <h4>What’s a Data Connection in Excel?</h4> <p>Something that some customers like to do is connect to SQL Server or other data sources within Excel files. This way you can have your Excel file magically update its data from a central repository, and it’s all very nice.  <p>The challenge arises when we move that same Excel file into SharePoint and except that same data refresh functionality to work the same. In Excel, it’s pretty straight forward; excel.exe is running under your identity so when it connects to SQL Server for example, it already has all the credentials it needs to do a refresh. Here’s the example we’re going to use:  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image00221.jpg"><img title="clip_image002" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image002_thumb19.jpg" width="542" height="246"></a>  <p>Behold, data from SQL Server via the power of data connections. Refreshes from Excel work without much drama.  <p>The problem with moving this into SharePoint however is that SharePoint isn’t running as “you” but needs to pretend to “be you” if the same data refresh is going to work.  <p>Here’s the architecture in SharePoint &amp; Office Online 2016 for a typical data refresh:  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/image759.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/04/image_thumb744.png" width="582" height="315"></a>  <p>The difference here is our claims-to-Windows token service is configured in Office Online, although there’s still the same service in SharePoint too – ignore it for now.  <h3>Network Setup &amp; Configuration</h3> <p>Here’s the relevant details for my own setup then.  <p>SQL Server is running under an account “awesomecloud\svc_sql”. It has these registered SPNs:  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image0069.jpg"><img title="clip_image006" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image006" src="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image006_thumb8.jpg" width="313" height="204"></a>  <p>On the Office Online server, Claims to Windows Token is running as local system:  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image0087.jpg"><img title="clip_image008" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image008" src="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image008_thumb6.jpg" width="329" height="133"></a>  <p>Running as local system saves a bunch of local security policies that a domain account would need to add (“impersonate a user”, “act as part of the OS”, and more). Just run as local system &amp; save some headaches.  <p>As we <i>are</i> running C2WTS as local system, the Office Online *computer* object is given delegation access to the SQL Server SPNs:  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image0105.jpg"><img title="clip_image010" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image010" src="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image010_thumb5.jpg" width="338" height="310"></a>  <p>Unconstrained delegation no less. We need this so we can then impersonate $loggedInUser to SQL Server for our refresh.  <p>Next up, the C2WTS needs to allow invocation by Office Online server. Do this by editing the file “C:\Program Files\Windows Identity Foundation\v3.5\c2wtshost.exe.config”.  <p>Uncomment the line:  <blockquote> <p>&lt;add value="NT AUTHORITY\Network Service" /&gt;</p></blockquote> <p>The file should look something like this:  <blockquote> <p>&lt;allowedCallers&gt;  <p>&lt;clear/&gt;  <p>&lt;add value="NT AUTHORITY\Network Service" /&gt;  <p>&lt;!-- &lt;add value="NT AUTHORITY\Local Service" /&gt; --&gt;  <p>&lt;!-- &lt;add value="NT AUTHORITY\System" /&gt; --&gt;  <p>&lt;!-- &lt;add value="NT AUTHORITY\Authenticated Users" /&gt; --&gt;  <p>&lt;/allowedCallers&gt;</p></blockquote> <p>Save &amp; restart the service. Now refreshes from Excel Online should work!  <h3>An Excel Data-Connection Refresh in Action</h3> <p>Assuming everything is working, this should now be possible. Here we open an Excel file, same one as above in fact, in SharePoint/Office Online. Refreshing the connections should not only not give us any errors, it should also now reflect any new data in the table.  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image0124.jpg"><img title="clip_image012" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image012" src="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image012_thumb4.jpg" width="641" height="256"></a>  <p>…and the result…  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image0144.jpg"><img title="clip_image014" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image014" src="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image014_thumb3.jpg" width="483" height="267"></a>  <p>This is the end-goal here; data refreshes just happening. If you checked on the SQL Server, as far as it was concerned, the refresh query would’ve executed under my logged-in Windows account equivalent – no claims here I’m afraid.  <h3>Stuff to Remember</h3> <p>It’s quite likely though you’ll hit some road-blocks on the way to getting it working. Here’s a few tips &amp; clarifications.  <p>Firstly, the C2WTS call uses Kerberos but authentication to SharePoint with Kerberos isn’t necessary. I did this connecting via NTLM to SharePoint just to prove a point. Double-hop isn’t happening or needed.  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image0163.jpg"><img title="clip_image016" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image016" src="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image016_thumb3.jpg" width="397" height="92"></a>  <p>Why? Because SharePoint is all claims-based for authentication; Kerberos or NTML or whatever will just end up as a claim to SharePoint; one that’s then passed to Office Online.  <p>That claim is then turned back into a Windows token, coincidentally using Kerberos to do so, but there’s no classic Kerberos double-hop happening here.  <p>Next, Kerberos is actually used however to impersonate the logged in user to the service being connected to – SQL in this instance. C2WTS will request a ticket to do so, and if the right SPNs &amp; delegation isn’t setup, it’ll fail. To make matter worse (and I’ll be honest, I’m not 100% clear why being that Kerberos isn’t my speciality), that response is cached to some extent even if you then fix the initial problem. So in other words, if you’re certain something should work – restart the Office Online server and it might just work next time you try.  <p>When it does work, you’ll see the result if you look at SQL Server profiler: <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/image760.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/04/image_thumb745.png" width="601" height="126"></a> <p>My user is connecting to SQL Server, despite me not being on the Office Online server itself – just logged in to SharePoint which uses Office Online server to do it’s refresh work. Clever! <p>&nbsp; <p>Finally, Office Online server has ULS logs, just like SharePoint. Run “Get-OfficeWebAppsFarm” to find out where they are &amp; use them for if &amp; when this doesn’t work.  <p>&nbsp; <p>That’s it for now!  <p>&nbsp; <p>Cheers,  <p>// Sam Betts]]></content:encoded>
    </item>
    <item>
      <title>SharePoint + Web Application Proxy - 2016 Edition</title>
      <link>https://docs.microsoft.com/archive/blogs/sambetts/sharepoint-web-application-proxy-2016-edition</link>
      <pubDate>Tue, 04 Apr 2017 15:46:51 GMT</pubDate>
      <dc:creator><![CDATA[Sam Betts MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sambetts/?p=2355</guid>
      <description><![CDATA[I’ve done a couple of articles already on Web Application Proxy (WAP) with SharePoint, and figured...]]></description>
      <content:encoded><![CDATA[<p>I’ve done a couple of articles already on Web Application Proxy (WAP) with SharePoint, and figured it was time to update the series now Windows Server 2016 has improved on it. Here’s how to set-up SharePoint 2016 with Windows Server Web Application Proxy 2016, up, high-level.  <p>First, a quick recap; why use WAP on-top of SharePoint &amp; ADFS? Because it gives you a way of exposing your public SharePoint applications to the internet without anyone having any line-of-sight. This is important because it means nobody could overwhelm your SharePoint infrastructure without being authenticated first.  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/image52.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/04/image_thumb50.png" width="295" height="369"></a>  <p>The idea is WAP sits in a DMZ, can be completely unconnected to any domain even, and just forward requests to SharePoint once a valid ADFS token has been gotten.  <p>This is very nice as we can isolate our precious production servers from any direct contact from outside.  <p>Also, WAP gives us extra authentication options for ADFS Server – we can insist on different security policies depending if the user has come from externally or internally.  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image0041.jpg"><img title="clip_image004" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image004" src="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image004_thumb1.jpg" width="398" height="333"></a>  <p>How does ADFS know if a user is external or internal? Simple – a user request either came via the proxy or it didn’t.  <h2>New Things in 2016</h2> <p>So what’s new then? On the SharePoint side, not much as far as ADFS/WAP is concerned.  <p>In WAP though we can now do things like:  <ul> <li>Use single wildcard certificate for publishing applications. Much easier for things like SharePoint-hosted apps which have unique domain-names per app. </li> <li>Redirect to HTTP back-ends (HTTPS no longer required). </li> <li>Some other stuff. </li></ul> <p>All in all, quite a worthy upgrade for Windows Server Web Application Proxy.  <h2>Network Requirements</h2> <p>The network setup is key to the whole thing working.  <p>As our Web Application Proxy will be the contact point for all traffic both to SharePoint &amp; ADFS, it needs to have the same SSL certificates &amp; IP associations as internal SharePoint addresses do. Behold, figure 1:  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/image53.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2017/04/image_thumb51.png" width="438" height="400"></a>  <p>WAP needs to be the external contact-point for everything needed internally; SharePoint &amp; ADFS too.  <p>It’s true though that SharePoint doesn’t necessarily need the same DNS names internally &amp; externally, but I’d highly recommend it for simplicity sake – alternative access mappings are a pain. Some network guys like to have visibly different internal &amp; external URLs, but frankly it only causes headaches for SharePoint URLs – things that work inside the network magically don’t work outside, etc.  <p>Keep URLs the same please! Seriously…  <h2>SharePoint Security Configuration</h2> <p>For my tests, I’ve taken an internal ADFS-secured SharePoint web-application &amp; simply published it externally. It is possible to have WAP convert ADFS tokens into internal Kerberos tokens for standard Windows-authenticated SharePoint web-apps instead, but I simply can’t be bothered with protocol transitioning. Why? Because ADFS is simply a better security solution that Windows auth directly on SharePoint web-applications, and ADFS can authenticate with Windows auth anyway.  <p>ADFS published websites are the way to go; forget native Windows authentication for SharePoint web-apps – you’ll be doing yourself a favour in the long-run, IMO.  <h2>Why Use ADFS Instead of Windows Auth for SharePoint?</h2> <p>ADFS give you a lot more control over identities. First, you can set what the “ID” (identifying claim) of each user will be; account-name, email address, whatever you want.  <p>Second is that, with the claims sent to each application (SharePoint in this case) we can manipulate them before sending them to the client-app (SharePoint) if we want too. This can make things like domain-mergers much easier; users from a newly absorbed domain can appear to SharePoint like users in another domain for example.  <p>Third, is the extra security you have for authentication. Multi-factor-authentication is possible for users based on certain policies, etc.  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image0081.jpg"><img title="clip_image008" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image008" src="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image008_thumb1.jpg" width="309" height="256"></a>  <p>Oh, and single-sign-on for Office 365/Azure AAD can use it.  <p>In the end, SharePoint isn’t designed to handle authentication &amp; identity policies; ADFS is and does it very well. SharePoint &amp; ADFS complement each other very nicely.  <p>Use it!  <h2>Publishing a SharePoint Web-App</h2> <p>So first up then let’s make sure the network is working – ping/nslookup from inside &amp; outside the network and verify the IP addresses are correct for each address, in all networks (internal, DMZ if you have one, and outside on the internet).  <p>Then get your certificates installed on your WAP 2016 machine(s). Obviously WAP needs line-of-sight to your ADFS instance too. Do not continue until you have this infrastructure verified.  <p>Now install the Web Application Proxy role. Configure the ADFS server being used.  <p>Finally publish your SharePoint application in WAP like so.  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image0101.jpg"><img title="clip_image010" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image010" src="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image010_thumb1.jpg" width="406" height="225"></a>  <p>That’s it!  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image012.jpg"><img title="clip_image012" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image012" src="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image012_thumb.jpg" width="386" height="261"></a>  <p>Assuming your network setup is correct, clients should now be using WAP for all requests, and it’ll just work.  <h2>Testing for Proxy Usage</h2> <p>You can tell if you’re hitting a WAP server instead of the real end-point from this header:  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image014.jpg"><img title="clip_image014" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image014" src="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image014_thumb.jpg" width="244" height="144"></a>  <p>Here’s a normal response if you’re going direct to SharePoint:  <p><a href="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image016.jpg"><img title="clip_image016" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image016" src="https://msdnshared.blob.core.windows.net/media/2017/04/clip_image016_thumb.jpg" width="244" height="120"></a>  <p>That’s it!  <p>// Sam Betts]]></content:encoded>
    </item>
    <item>
      <title>Super SQL Server Clusters for SharePoint - Part 2</title>
      <link>https://docs.microsoft.com/archive/blogs/sambetts/super-sql-server-clusters-for-sharepoint-part-2</link>
      <pubDate>Mon, 05 Dec 2016 15:22:55 GMT</pubDate>
      <dc:creator><![CDATA[Sam Betts MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sambetts/?p=2175</guid>
      <description><![CDATA[This is part two of one of how to setup the mother of all database clustering solutions for...]]></description>
      <content:encoded><![CDATA[<p>This is part two of <a href="https://blogs.msdn.microsoft.com/sambetts/2016/12/05/super-sql-server-clusters-for-sharepoint-part-1/">one</a> of how to setup the mother of all database clustering solutions for SharePoint. In part one we setup the failover cluster, installed SQL Server and configured the failover clusters.  <p><a href="https://blogs.msdn.microsoft.com/sambetts/2016/12/05/super-sql-server-clusters-for-sharepoint-part-1/">Previously</a> we’d setup our super-cluster &amp; installed SQL Server, this time with two failover clusters; one for each farm.  <p>Now we need to setup or create our SharePoint databases for both the primary &amp; secondary farms.  <h1>Create SharePoint Databases for Each Farm</h1> <p>At this point we should have all of our SQL instances ready to go. Next we need to add the databases so we can setup AlwaysOn for those databases.  <p>Using client-side SQL aliases, this is what we want to build first:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/image128.png"><img title="SharePoint High Availability" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SharePoint High Availability" src="https://msdnshared.blob.core.windows.net/media/2016/12/image_thumb95.png" width="241" height="366"></a>  <p>Both farms have separate configuration &amp; some service apps <a href="https://blogs.msdn.microsoft.com/sambetts/2015/11/20/synchronising-service-applications-between-sharepoint-disaster-recovery-farms/">where it makes sense</a> (seriously, this is important). For anything we’re going to copy between farms like content-databases for example, we’ll just create/move the databases onto the primary farm.  <p>First create/edit a SQL alias on each SharePoint server:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image003.png"><img title="SharePoint High Availability" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SharePoint High Availability" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image003_thumb.png" width="470" height="308"></a>  <p>Create new farms; one on each failover cluster for each farm, using said alias:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image0041.png"><img title="SharePoint High Availability" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SharePoint High Availability" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image004_thumb1.png" width="451" height="391"></a>  <p>…or use PowerShell if you prefer.  <p>You could just as easily move databases if you already have SharePoint farm(s) setup already; the principal is the same – we want two farms working, each one on a separate failover cluster.  <h3>Create Service-Apps</h3> <p>Once we have two farms setup &amp; ready we need to create the service-apps next.  <p>Create &amp; configure your service-applications as needed on the primary farm. Leave the secondary farm as we’ll use copies of everything from the primary farm, with one exception…  <p>Each farm should have its own separate search application + databases.  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image0066.jpg"><img title="SharePoint High Availability" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SharePoint High Availability" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image006_thumb1.jpg" width="536" height="174"></a>  <p>Search isn’t something that you want to copy between farms as we want farm redundancy on this huge chunk of SharePoint, so we’ll just fail it over to the local farm SQL instances.  <h3>Create Content Databases &amp; Web-Applications</h3> <p>Also as before, create a web-app on the <b>primary</b> farm only with either new or restored content databases.  <h1>Create AlwaysOn Availability Groups for SharePoint Farms</h1> <p>At this point we should have all of our SQL instances &amp; databases ready to go for both SharePoint farms.  <p>Now we have to create the availability-groups for them – we want the following SQL Server AlwaysOn availability groups:  <ul> <li>Farm-local failover groups.  <ul> <li>All the databases that won’t ever move between farms, one group per farm. </li></ul> <li>Service application availability group.  <ul> <li>All service-app data that both farms will share, copied between the two farms. </li></ul> <li>Content database availability group.  <ul> <li>All the content that both farms will share, copied between the two farms. </li></ul></li></ul> <p>Now, it should be pointed out that creating AlwaysOn availability groups is much (so much) easier when the database file paths are exactly the same across all instances. If this is the case, you can perform an initial “full” sync via a shared network path to backup &amp; restore the databases + transaction-logs.  <p>Otherwise you need to do the DB + transaction-log restores manually &amp; just have SQL Server join the databases. This my friends, is an epic amount of work if you have to do it by hand.  <h3>Farm + Search Availability Groups</h3> <p>We need two farm AlwaysOn availability groups; one per farm so we have farm redundancy. That means we’ll have two copies of each farm database &amp; two SQL instances we can use, with at least one instance with two member servers.  <p>We want the config DB, central admin content + the search databases in this group. All need to be in “full recovery” mode, so just make a backup of each database and they should be ready to add. Add the state service DB too if you have one.  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image0086.jpg"><img title="SharePoint High Availability" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SharePoint High Availability" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image008_thumb1.jpg" width="502" height="278"></a>  <p>We don’t care too much about the usage database because it can be very heavy on updates, and <a href="https://blogs.msdn.microsoft.com/sambetts/2015/10/23/sharepoint-usage-database-in-sql-server-alwayson/">isn’t critical</a>.  <p>Here we’re including the state service in the local farm group, meaning it won’t be synced between farms. This is because I don’t have any SharePoint 2010 style workflows so isn’t needed to be synced, but your requirements might differ (read: if you have workflows, don’t include the State Service DB in the local farm group – sync with service-apps DBs).  <p>Next up; add the secondary replica for our local farm failover AG, which in farm 1s’ case is “SQL-N1”.  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image0107.jpg"><img title="SharePoint High Availability" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SharePoint High Availability" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image010_thumb3.jpg" width="509" height="345"></a>  <p>Now we need to join the databases. In my specific setup we can’t do a full sync here as both SQL-N1 &amp; SQL-N2 use different paths for the database files (something you can <i>technically</i> avoid if you know ahead of time, but I forgot).  <p>Anyway, as mentioned earlier, the alternative is the somewhat-more-hassle restoring each database with no recovery (important) on the secondary so the wizard can just join each DB to the availability group instead of creating each one too.  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image01214.jpg"><img title="SharePoint AlwaysOn High Availability" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SharePoint AlwaysOn High Availability" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image012_thumb3.jpg" width="560" height="312"></a>  <p>Join only a pain to get DBs in sync, but nobody said this will be easy. Assuming all the databases to add are ready on the secondary instance (SQL-N1 in this example), in “restoring” mode then this will work no problem.  <p>Create availability group “SPFarm1” between instances SQL-N1 &amp; SQL-N2, and another availability group “SPFarm2” between SQL-N3 &amp; SQL-N4.  <h3>Service-Apps Availability Group</h3> <p>Next up, we want another separate availability group for service applications. On farm 1 create/mount the following service applications:  <ul> <li>Managed Metadata  <li>User profiles  <li>App Management  <li>Secure Store  <li>…  <li>Whatever service-apps you use that have databases that need syncing. </li></ul> <p>Once created &amp; working, create a new availability group between SQL-N2 &amp; SQL-N3 to synchronise the databases in those applications, <u>except</u> the sync DB for user profiles.  <p>Once mounted, primary to SQL-N3 &amp; in farm 2 add the service-applications using the existing databases setup in AlwaysOn.  <p>More on sharing service-apps between farms @ <a href="https://blogs.msdn.microsoft.com/sambetts/2016/03/21/running-sharepoint-service-applications-in-read-only-mode-for-disaster-recovery-farms">https://blogs.msdn.microsoft.com/sambetts/2016/03/21/running-sharepoint-service-applications-in-read-only-mode-for-disaster-recovery-farms</a>  <h3>Content Database Availability Group</h3> <p>Finally do the same again for content databases as you did for service-apps in a 2<sup>nd</sup> group between SQL-N2 &amp; SQL-N3, just with the content databases. One new availability group between nodes SQL-N2 &amp; SQL-N3.  <h1>Create Listeners &amp; Update SharePoint Aliases</h1> <p>Now we just need to add listeners for the SPFarm availability groups so SharePoint will failover between the farm instances transparently.  <p>I’ll add mine here; for some reason SQL doesn’t let me create one unless all possible subnets are covered, even though for the farm-specific connections were never going to cross a subnet.  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image01414.jpg"><img title="SharePoint AlwaysOn High Availability" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SharePoint AlwaysOn High Availability" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image014_thumb1.jpg" width="557" height="184"></a>  <p>Having a listener for each farm means either farm 1, for example should be able to use either SQL-N1 or SQL-N2 instances; the change-over will happen transparently.  <p>Even better, as SQL-N2 is a failover cluster of two members, SQL-N2 itself could even failover to either SQL-N2-S1 or SQL-N2-S2 and again, nothing would change. Two levels of failover transparency! My goodness.  <p>Anyway, to seal the deal, update each SharePoint farm server to use either “SPFarm1Listener” or “SPFarm2Listener” as we did before.  <h1>Everything Finished – Let’s Review the Setup</h1> <p>At this point your SQL Server cluster setup should look something like this:  <ul> <li>SQL-N1 (single member failover cluster)  <ul> <li>SPFarm 1 availability group + listener. </li></ul> <li>SQL-N2 (2-server failover cluster)  <ul> <li>SPFarm 1 availability group + listener.  <li>Service Apps availability group.  <li>Content database availability group. </li></ul> <li>SQL-N3 (2-server failover cluster)  <ul> <li>SPFarm 2 availability group + listener.  <li>Service Apps availability group.  <li>Content database availability group. </li></ul> <li>SQL-N4 (single member failover cluster)  <ul> <li>SPFarm 2 availability group + listener. </li></ul></li></ul> <p>You cluster host should now have no less than 8 roles in it:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image015.png"><img title="SharePoint AlwaysOn High Availability" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SharePoint AlwaysOn High Availability" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image015_thumb.png" width="282" height="228"></a>  <p>Four failover SQL clusters &amp; four availability groups. Clustering on steroids!  <h1>Testing Failovers &amp; Outages</h1> <p>So this is the key goal here then; which SQL Servers can die without SharePoint suffering any outage? How many before we need to use the other farm?  <h3>No Farm Failover Needed</h3> <p>First let’s see what we can kill without needing to failover to the other farm.  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/image129.png"><img title="SharePoint AlwaysOn Failover" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SharePoint AlwaysOn Failover" src="https://msdnshared.blob.core.windows.net/media/2016/12/image_thumb96.png" width="350" height="596"></a>  <p>We can technically keep working with up-to 4 SQL Servers offline &amp; just 2 left, which is quite unlikely to ever happen. In this scenario we’ve lost two clustered roles too as there’s no servers left to run them. Assuming the two offline servers weren’t in the same failover cluster, we’d still have data-synchronisation between farms too.  <p>Any one SQL Server can go offline without the slightest interruption of service, albeit we’d possibly have to failover the AlwaysOn AG manually, as automatic failover only works for standalone instances.  <h3>Farm Failover Needed</h3> <p>So what could go offline which would need an entire farm failover then?  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/image130.png"><img title="SharePoint AlwaysOn Failover" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SharePoint AlwaysOn Failover" src="https://msdnshared.blob.core.windows.net/media/2016/12/image_thumb97.png" width="359" height="613"></a>  <p>In this case we have just one SQL Server running of the six setup, and even then we could still use the 2<sup>nd</sup> farm. Synchronisation would be stopped but should in theory resume anyway.  <h1>Wrap-Up</h1> <p>Setting this kind of architecture up is very complicated, but as you can see it does give the benefit of having a zombie-like SQL backend for SharePoint – one that just won’t ever die.  <p>In all honesty I’d only recommend this over <a href="https://blogs.msdn.microsoft.com/sambetts/2016/01/20/combining-disaster-recovery-farms-with-sql-redundancy-for-sharepoint-with-sql-server-alwayson/">SQL Server AlwaysOn for SharePoint DR</a> if SQL/SharePoint uptime is absolutely critical, and so is guaranteeing data movement between SharePoint farms. In reality, it’s the guaranteed data movement that this model really gives over the standalone AlwaysOn for SP-DR model, but yet it’s quite a lot more complicated to setup.  <p>Another negative is the lack of automatic failover between AlwaysOn instances, but as each instance is a failover instance itself that shouldn’t be an issue.  <p>Anyway, in short, this is your solution if costs aren’t an issue &amp; uptime is critical.  <p>If you need an uptime solution for more reasonable costs, get AlwaysOn with just standalone instances.  <p>&nbsp; <p>Cheers,  <p>Sam Betts]]></content:encoded>
    </item>
    <item>
      <title>Super SQL Server Clusters for SharePoint - Part 1</title>
      <link>https://docs.microsoft.com/archive/blogs/sambetts/super-sql-server-clusters-for-sharepoint-part-1</link>
      <pubDate>Mon, 05 Dec 2016 15:09:28 GMT</pubDate>
      <dc:creator><![CDATA[Sam Betts MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sambetts/?p=1976</guid>
      <description><![CDATA[When I demonstrated AlwaysOn for SharePoint Disaster Recovery setups a while ago, the SQL cluster...]]></description>
      <content:encoded><![CDATA[<p>When I demonstrated AlwaysOn for SharePoint Disaster Recovery setups <a href="https://blogs.msdn.microsoft.com/sambetts/2016/01/20/combining-disaster-recovery-farms-with-sql-redundancy-for-sharepoint-with-sql-server-alwayson/">a while ago</a>, the SQL cluster model I setup wasn’t strictly speaking highly-available. This is because there’s no failover for SQL Servers synchronising data between both SharePoint farms.  <p>A couple of people have pointed this out now and as this is technically a potential fault, I wanted to expand on the previous design by turning the cluster design into a “super-cluster” (my own term). I wanted to build a SQL Server architecture to cover all the potential high-availability holes for SharePoint &amp; the SQL backend. That and, well, any excuse to fire up some epic architectures is fine by me!  <p>Before we begin, if this is your first time looking at AlwaysOn for SharePoint, you’d best read <a href="https://blogs.msdn.microsoft.com/sambetts/2016/01/20/combining-disaster-recovery-farms-with-sql-redundancy-for-sharepoint-with-sql-server-alwayson/">this quick overview first</a>.  <p>This is a two-part series just because of how big this setup guide is. We’re going to mount the backend for two SharePoint farms, with part one being the core cluster setup. Part two of the setup where we mount the SharePoint databases &amp; availability-groups is <a href="https://blogs.msdn.microsoft.com/sambetts/2016/12/05/super-sql-server-clusters-for-sharepoint-part-2/">here</a>.  <p>We’re going to setup said “super-cluster”; a cluster of clusters to some extent to serve two active/passive SharePoint farms just so we have God-like uptime &amp; availability for SharePoint.  <p>More specifically though, we have two goals for our super-cluster-architecture:  <ol> <li>The most highly-available uptime for SQL Server known to mankind.  <li>On the back of that, the most reliable content synchronising between our two SharePoint farms, also known to man. </li></ol> <p>This will be a complex setup, but still, it’s all so our users/bosses don’t complain SharePoint has gone down. If said bosses don’t want to commit to building this out then any failures aren’t a technology issue, but rather a financial one.  <h1>The Original SharePoint DR Architecture </h1> <p>Here’s our original SharePoint farms + SQL backend diagram:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/image124.png"><img title="High Availability SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="High Availability SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/image_thumb91.png" width="332" height="482"></a>  <p>As pointed out, this design isn’t actually as bullet-proof as it could be simply because a single SQL Server outage could bring down the primary SharePoint farm, unless everything was failed-over to the DR side, like so:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/image125.png"><img title="High Availability SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="High Availability SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/image_thumb92.png" width="339" height="504"></a>  <p>The same problem would be true if “SQL-N3” would go offline for any reason (patching for example); our AlwaysOn group for content will die and data synchronisation would temporarily stop, even if users won’t necessarily notice. This cannot be!  <p>Even though we still do have high-availability in that we have failover options, it would be nice to further improve uptime even further by making sure our single server (“SQL-N2”) isn’t a point of failure for the main farm.  <p>Side note: In fairness, AlwaysOn is pretty hot at resuming synchronisation when problems occur and service is resumed, but we want to make sure that isn’t necessary. In the case of “SQL-N2” going offline, it’s actually fairly serious because unless we fail-over to the other farm entirely we’re going to have fatal SQL exceptions.  <h1>The Solution: An AlwaysOn Cluster of Failover Clusters</h1> <p>In the above diagrams each server is just a standalone server in an AlwaysOn cluster. Back in the day, the only clustering in SQL Server was “failover” clustering which is somewhat different, but still available now.  <p>The solution to fill this high-available gap is we’re going to make all the servers “failover clusters” with “SQL-N2” and “SQL-N3” specifically failover clusters with multiple members, instead of single servers. The other servers will also be failover instances too as AlwaysOn clusters can’t mix &amp; match standalone &amp; failover instances, but they’ll be failover instances of just one member. You could add more servers, but for now at least there’s no need.  <h2>Background: Failover Clustering</h2> <p>First though a quick bit of history. Failover clustering is basically clustering a single SQL Server service instance, while sharing data between the cluster members. Basically turn a standalone machine into several, with only one server pretending to the clustered server at any one time. If the active server goes offline (or we failover manually), the next failover server starts the SQL Server service and pretends to be the clustered server instead, using the same data files the previous server had.  <p>Failover clustering is basically one service instance with multiple possible members. AlwaysOn is basically multiple service instances all together. The two work together quite nicely.  <p>This is the new monster we’re going to create:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/image126.png"><img title="High Availability SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="High Availability SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/image_thumb93.png" width="361" height="636"></a>  <p>Yes indeed; this setup should satisfy even the most hardcore enterprise architects. We replace all the standalone instances with failover instances (albeit some instances with only a single member, for now); high-availably &amp; maximum uptime in bag-loads. It’s quite a thing of beauty, if you like this sort of thing.  <h1>Creating a Super Cluster</h1> <p>So just for the lulz, I’ll show you how to create said super-cluster from scratch. If you had the previous model already you can just edit what you’ve got, but I’m doing it from zero just so it’s clear.  <p>For this experiment, seeing as we’re in “enterprise: expert” mode, I created 6 SQL machines + 1 witness machine over 3 subnets – 3 machines are in one subnet, 3 machines are in another with the witness in the 3<sup>rd</sup> subnet. Like this:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/image127.png"><img title="High Availability SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="High Availability SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/image_thumb94.png" width="549" height="183"></a>  <p>This gives a proper quorum, and one that’ll be designed to <a href="https://blogs.msdn.microsoft.com/sambetts/2014/05/16/building-true-multi-subnet-windows-server-failover-clusters/">handle correctly network failures too</a>.  <p>For the SQL Service, we need a network account too – “<b>awesome\svc_sql</b>” in my case.  <p>The failover machines also need some kind of shared storage between them. Ideally this should be shared SCSI disks, but in SQL Server 2012 and onwards you can use just a network path (which is much slower, so not recommended). My test lab has some limits, so I’m just using a network path for this, but be aware it’s really not that suitable for production setups normally.  <h2>Create Windows Cluster Host</h2> <p>In all 6 SQL Servers we need failover clustering Windows Server feature to be installed, and then to add each one to the parent host cluster. From one of the SQL Servers create a new cluster:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image009.png"><img title="High Availability SharePoint SQL Server" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="High Availability SharePoint SQL Server" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image009_thumb.png" width="545" height="369"></a>  <p>Next we need to validate the cluster. Normally for AlwaysOn this isn’t mandatory but for failover clustering, unless there’s a good validation report the setup won’t continue. Either way, you won’t get any support from Microsoft unless all tests are run (and passed) so run it.  <p>So run the validation tests.  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image011.jpg"><img title="High Availability SharePoint SQL Server" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="High Availability SharePoint SQL Server" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image011_thumb.jpg" width="569" height="246"></a>  <p>If you don’t validate, or have critical errors, SQL Server won’t setup as a cluster:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image013.jpg"><img title="clip_image013" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image013" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image013_thumb.jpg" width="566" height="226"></a>  <p>It’s fairly normal to have some warnings at least; proper clustering is an art-form but this is my dodgy test environment so, well, who cares. For production environments you should actually care.  <p>Once done we should be able to create our cluster-host. This is just the host object for the entire cluster super-set. Clustered SQL Services will get added to it later on...  <p>Finish the wizard, and now we can give the cluster host name.  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image015.jpg"><img title="High Availability SharePoint SQL Server" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="High Availability SharePoint SQL Server" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image015_thumb.jpg" width="579" height="393"></a>  <p>As this is a multi-subnet cluster, we’ll need to give an IP address in each subnet as servers in either subnet could host the cluster-name-object in theory.  <p>Now our cluster should show these nodes:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image017.jpg"><img title="High Availability SharePoint SQL Server" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="High Availability SharePoint SQL Server" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image017_thumb.jpg" width="586" height="266"></a>  <p>Now we’ll need to add a quorum to the cluster so we can make sure we <a href="https://blogs.msdn.microsoft.com/sambetts/2014/05/16/building-true-multi-subnet-windows-server-failover-clusters/">failover correctly</a>. We’re going to use the file-share on the witness machine on the 3<sup>rd</sup> subnet. Right-click on the cluster root, “more actions” and “configure cluster quorum settings”.  <p>Select “file share witness”; put the file-share path in:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image019.jpg"><img title="AlwaysOn High Availability SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="AlwaysOn High Availability SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image019_thumb.jpg" width="589" height="206"></a>  <p>Confirm, and that’s all the configuring you should do in the Cluster Manager now. Everything else, SQL Server will configure.  <h3><i>Install SQL Server on SQL Machines</i></h3> <p>Next step is to get SQL Server on each node. In AlwaysOn we can’t mix standalone &amp; failover clusters so we’re going to add all 4 failover clusters, 2 of which have 2 members &amp; the other 2 are just single-member clusters. That should be enough to demonstrate how this will work, and you can always add more member servers later.  <h3><i>Create New SQL Server Failover Clusters</i></h3> <p>We need to create here 4 new failover clusters, with SQL-N1 &amp; SQL-N4 (our “standalone” machines) with a cluster of just one member.  <p>I’m not going to go into detail about the process, as this technology is nearly as old as SQL Server, but here’s some details.  <p>Installing a failover cluster isn’t like installing normal SQL; there’s a separate install method for failover clusters:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image020.png"><img title="AlwaysOn High Availability SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="AlwaysOn High Availability SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image020_thumb.png" width="385" height="47"></a>  <p>Run that and get started. This I did on “SQL-N2-S1” and “SQL-N3-S1” to create two new failover clusters. Most of the wizard is pretty straightforward, until the networking configuration:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image02214.jpg"><img title="AlwaysOn High Availability SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="AlwaysOn High Availability SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image022_thumb2.jpg" width="589" height="316"></a>  <p>Here I can only put an IP address in the top box because right now the cluster only has one member (this machine), hence multi-subnet configuration isn’t available yet. We’re not planning on making these roles multi-subnet however.  <p>Another important detail: per parent cluster host, each service instance name has to be unique for failover instances at least. That means our failover clusters will technically be:  <ul> <li>SQL-N1\<u>N1</u>  <li>SQL-N2\<u>N2</u>  <li>SQL-N3\<u>N3</u>  <li>SQL-N4\<u>N4</u></li></ul> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image024.jpg"><img title="AlwaysOn High Availability SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="AlwaysOn High Availability SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image024_thumb.jpg" width="571" height="259"></a>  <p>This is because we can’t have any two cluster instances as the default “MSSQLSERVER” (or just “SQL-N2” &amp; “SQL-N3”). The instance name uniqueness seems a bit redundant but basically it’s because the service-names in the cluster have to be unique as well as the clustered object names (the virtual “server” name).  <p>Also on storage for the database instance I’m using a network path because this is just a test environment so I don’t have the cash for proper SCSI discs:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image026.jpg"><img title="AlwaysOn High Availability SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="AlwaysOn High Availability SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image026_thumb.jpg" width="561" height="420"></a>  <p>This normally is a terrible idea though, just for performance reasons if nothing else – a network location, even with decent infrastructure, is many times slower than proper SCSI disks.  <p>For the service account I’m still using “awesome\svc_sql” of course.  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image028.jpg"><img title="AlwaysOn High Availability SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="AlwaysOn High Availability SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image028_thumb.jpg" width="570" height="318"></a>  <p>Create new failover clusters on machines SQL-N1, SQL-N2-S1, SQL-N3-S1, and SQL-N4; when done you should have <b>four</b> failover clusters of <u>one</u> server only each. We’re going to add the other servers in a minute.  <p>Once you’re done, you should see the roles configured in the Cluster Manager:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image030.jpg"><img title="AlwaysOn High Availability SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="AlwaysOn High Availability SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image030_thumb.jpg" width="557" height="214"></a>  <p>Remember folks: <b>don’t even touch anything here unless you know what you’re doing</b>!  <h3>Configure Cluster Resource Ownerships</h3> <p>We need to check clustered that roles can only be taken ownership of by servers that should run the role. This isn’t just a good practise; SQL Server will fail when mounting the AlwaysOn availability group if this isn’t done right:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image031.png"><img title="AlwaysOn High Availability SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="AlwaysOn High Availability SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image031_thumb.png" width="531" height="221"></a>  <p>Anyway, in each clustered role, just uncheck any server that will never be able to run the role on the SQL Service so there’s no overlap:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image0326.png"><img title="AlwaysOn High Availability SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="AlwaysOn High Availability SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image032_thumb1.png" width="431" height="211"></a>  <p>In my case the service was set to allow SQL-N1-S1 too, even though it never could because it wasn’t a member of that failover cluster.  <p>Seriously, get this bit right because SQL Server can really get its’ knickers in a twist if it gets halfway through creating an AlwaysOn availability group later &amp; fails because these possible owners aren’t right – make sure each service can <u>only</u> be failed over to the server which are assigned to the instance.  <h3>Add SQL Server Failover Members</h3> <p>Now we have our failover clusters we need to add extra nodes to them so they can actually failover to something, for two of them at least. You could add failover members to all 4 technically, but as pointed out earlier, our high-availability vulnerable points are only really the SQL instances making up the availability group for content synchronisation, so here we’re only creating two “true” failover clusters. The others are single-member clusters because in AlwaysOn we can’t mix standalone &amp; failover cluster instances into the same AlwaysOn availability group.  <p>Anyway, to add a server to an existing failover cluster, we launch another type of installation:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image0331.png"><img title="AlwaysOn High Availability SharePoint" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="AlwaysOn High Availability SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image033_thumb1.png" width="401" height="45"></a>  <p>This time there’s not so much to configure as it’s already been done; just what instance you want to join:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image035.jpg"><img title="SQL Server AlwaysOn SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SQL Server AlwaysOn SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image035_thumb.jpg" width="510" height="274"></a>  <p>…and just confirming the IP address. In our case we’re not setting up a multi-subnet the failover instance we don’t have to do anything except join the existing configured clustered IP.  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image037.jpg"><img title="SQL Server AlwaysOn SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SQL Server AlwaysOn SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image037_thumb.jpg" width="514" height="204"></a>  <p>Also with the service-account; we can’t choose it as it’s done already, just add the password for this cluster node to save.  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image039.jpg"><img title="SQL Server AlwaysOn SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SQL Server AlwaysOn SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image039_thumb.jpg" width="515" height="219"></a>  <p>That’s pretty much it; the rest of the wizard will just join the server &amp; install the service-instance.  <h2>Enable AlwaysOn on SQL Services</h2> <p>You’ll need to check this is on each primary or standalone server, in the SQL Server Configuration Manager:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image040.png"><img title="SQL Server AlwaysOn SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SQL Server AlwaysOn SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image040_thumb.png" width="360" height="178"></a>  <p>Once you restart the service, that instance will be enabled for AlwaysOn.  <h1>Testing Failover Clusters</h1> <p>At this point we should have all our failover cluster resources ready, minus the AlwaysOn bits. Now’s a good a moment as any to test the failover clusters actually failover ok. It’s somewhat important to know our failover clusters can in fact, failover.  <p>For failover clustering, failovers are transparent to SQL Server as opposed to AlwaysOn which drives the process from SQL Server itself (for the most part). Anyway, for failover clustering we use the Cluster Manager/PowerShell to drive events, rather than SQL Server itself.  <p>Let’s check we can move each role to the other server. Open the Cluster Manager and move each one like so:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image042.jpg"><img title="SQL Server AlwaysOn SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SQL Server AlwaysOn SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image042_thumb.jpg" width="584" height="369"></a>  <p>Normally we can just say move to “best possible node” which will use the possible owner configuration in the cluster to figure out which server could take the role, but we’ll do it manually…  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image043.png"><img title="SQL Server AlwaysOn SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SQL Server AlwaysOn SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image043_thumb.png" width="354" height="243"></a>  <p>This lets you select any node, but only nodes which have the service will actually work for the move command – trying to move a role to a server that isn’t allowed/configured for the role will give an error and not actually do anything.  <p>Assuming you pick an appropriate server though, once you pick the other serer you’ll then see the cluster manager move everything there:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image044.png"><img title="SQL Server AlwaysOn SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SQL Server AlwaysOn SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image044_thumb.png" width="350" height="65"></a>  <p>…and hopefully, if everything went well we’ll have a new owner for the clustered resource (SQL):  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image045.png"><img title="SQL Server AlwaysOn SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="SQL Server AlwaysOn SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image045_thumb.png" width="360" height="69"></a>  <p>If there are any errors here, you’ll need to figure out why the other SQL node didn’t come up – application logs are a good start if the problem is the service. Sometimes though the problem can be cluster configuration (see below).  <p>Do the same test for the other failover role.  <h3>Oops. Failover Cluster Fails to Actually Failover!</h3> <p>Testing your failover clusters can actually make the leap from one server to the other is kinda critical for obvious reasons. But if your test fails, this is what it’ll likely look like…  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image047.jpg"><img title="sambetts SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="sambetts SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image047_thumb.jpg" width="590" height="58"></a>  <p>Clicking the “more information” menu shows us this:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image048.png"><img title="SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="sambetts SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image048_thumb.png" width="464" height="196"></a>  <p>So “sql-n3-s2” couldn’t accept ownership of the role for some reason or other. After poking around, it turns out the clustered IP address was misconfigured for some reason:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image049.png"><img title="AlwaysOn SharePoint" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="AlwaysOn SharePoint" src="https://msdnshared.blob.core.windows.net/media/2016/12/clip_image049_thumb.png" width="460" height="226"></a>  <p>We’ve basically told the cluster that this IP address, which is a dependency for the failover role, can only be owned by one machine. Not much failover capacity here then, which is why it didn’t failover.  <p>On investigating why in this example (this was a real slip-up on my part, not a faked problem) it turned out I’d forgotten to add SQL-N3-S2 to the failover cluster in the SQL Server Setup, so at the moment of testing “SQL-N3” really only had one possible server. <em>What a n00b!</em>  <p>Anyway; adding this server fixed it, and it nicely showed the value of testing your failover clusters ahead of time.  <p>Now we should have a super-cluster ready for SharePoint databases! <a href="https://blogs.msdn.microsoft.com/sambetts/2016/12/05/super-sql-server-clusters-for-sharepoint-part-2/">See part 2 for how</a>.]]></content:encoded>
    </item>
    <item>
      <title>Repairing OneDrive “Next-Gen” Sign-in Loop of Doom on Windows 10</title>
      <link>https://docs.microsoft.com/archive/blogs/sambetts/repairing-onedrive-next-gen-sign-in-loop-of-doom-on-windows-10</link>
      <pubDate>Thu, 29 Sep 2016 09:17:35 GMT</pubDate>
      <dc:creator><![CDATA[Sam Betts MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sambetts/?p=1445</guid>
      <description><![CDATA[So I had a long-running issue where the next-generation OneDrive sync client just wouldn’t sign-in...]]></description>
      <content:encoded><![CDATA[<p>So I had a long-running issue where the next-generation OneDrive sync client just wouldn’t sign-in to my corp account, and nothing was syncing.  <p>I had tried the nice steps laid out on <a href="https://support.office.com/en-us/article/Fix-OneDrive-sync-problems-83ab0d8a-8400-45b0-8dcf-dc8aa8a6bcf8?ui=en-US&amp;rs=en-US&amp;ad=US">the support site</a>, plus some more, but to no avail – the icon would stubbornly sit on “OneDrive for Business – Signing in” forever. <p>Adding the account again would result in a big red message saying “<font color="#ff0000">You’re already syncing this account</font>”, and even removing the cached credentials had no effect. <p>Well; I fixed it in the end, so here’s how I did it &amp; how I’d recommend you try too if you’re also struggling. <h3>1. Look at the Official Support Guide</h3> <p>Make sure you look at what the product-group has written about troubleshooting OneDrive issues - <a href="https://support.office.com/en-us/article/Fix-OneDrive-sync-problems-83ab0d8a-8400-45b0-8dcf-dc8aa8a6bcf8?ui=en-US&amp;rs=en-US&amp;ad=US">https://support.office.com/en-us/article/Fix-OneDrive-sync-problems-83ab0d8a-8400-45b0-8dcf-dc8aa8a6bcf8?ui=en-US&amp;rs=en-US&amp;ad=US</a> – make sure you’ve at least looked at the solutions there. <p>This blog-post is not gospel when it comes to what is officially supported; just my personal hacking that made OneDrive syncing finally work. <h3>2. Try Removing the OneDrive Cached Credentials</h3> <p>I noticed some users had an issue where the credentials stored became corrupt. Delete them after killing the OneDrive process, then restart OneDrive. <p><a href="https://msdnshared.blob.core.windows.net/media/2016/09/clip_image00226.jpg"><img title="clip_image002" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/2016/09/clip_image002_thumb18.jpg" width="590" height="293"></a> <p>OneDrive will of course need to re-authenticate to begin syncing, and maybe this alone will work. Not for me however… <h3>3. Try a OneDrive Client Reset</h3> <p>Kill and reset the OneDrive process(es) by running this: <blockquote> <p>%localappdata%\Microsoft\OneDrive\OneDrive.exe /reset</p></blockquote> <p>That alone might even be enough to fix your problem; run it again to see if it gets any further. Disclaimer in case it’s not obvious: this will of course reset the local sync status of any file, so you’ll have to do a full-sync again. <p>Run OneDrive again to see if it worked of not. Again, for me this wasn’t enough; it would keep trying to sync anyway, and never signing in. <h3>4. Uninstall the OneDrive Client and Reinstall</h3> <p>This is what worked for me in the end. All the Microsoft sites seem to suggest at least that OneDrive is a core component of Windows 10 at least, and it sort of is, but it’s one that can be removed &amp; upgraded aside from standard Windows patches so it isn’t really core Windows.  <p>Long story short: you can uninstall it and then install it again, which removes the configuration cache too. <p>Kill/reset the OneDrive processes with: <blockquote> <p>%localappdata%\Microsoft\OneDrive\OneDrive.exe /reset</p></blockquote> <p>Now uninstall with this: <blockquote> <p>%SystemRoot%\SysWOW64\OneDriveSetup.exe /uninstall</p></blockquote> <p>The uninstall is silent and pretty quick; don’t expect any confirmation it worked, just wait 20-30 seconds and it’s probably done. <p>Install again from the web (<a href="https://onedrive.live.com/">https://onedrive.live.com/</a>); click the download button, despite being told there’s no need: <p><a href="https://msdnshared.blob.core.windows.net/media/2016/09/clip_image00410.jpg"><img title="clip_image004" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="clip_image004" src="https://msdnshared.blob.core.windows.net/media/2016/09/clip_image004_thumb10.jpg" width="665" height="389"></a> <p>Once it’s installed, everything will have been factory-reset, which is what should clear the blockage. <p>Now configure OneDrive again like the 1<sup>st</sup> time ever, and you should be able to sign-in again.  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/09/clip_image00626.jpg"><img title="clip_image006" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="clip_image006" src="https://msdnshared.blob.core.windows.net/media/2016/09/clip_image006_thumb6.jpg" width="390" height="330"></a> <p>Finally, we have a syncing account! That said; I said to use the previous location so there’s one or two extra sync issues to solve, but at least it’s doing something now: <p><a href="https://msdnshared.blob.core.windows.net/media/2016/09/clip_image00824.jpg"><img title="clip_image008" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="clip_image008" src="https://msdnshared.blob.core.windows.net/media/2016/09/clip_image008_thumb4.jpg" width="241" height="337"></a> <p>&nbsp; <p>That’s it; I hope one of these solutions works for you too! <p>// Sam Betts]]></content:encoded>
    </item>
    <item>
      <title>SharePoint Disaster Recovery vs. Active Passive Farms</title>
      <link>https://docs.microsoft.com/archive/blogs/sambetts/sharepoint-disaster-recovery-vs-active-passive-farms</link>
      <pubDate>Thu, 14 Apr 2016 16:29:22 GMT</pubDate>
      <dc:creator><![CDATA[Sam Betts MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sambetts/?p=1295</guid>
      <description><![CDATA[Just a quick clarification on terminology &amp; methodologies for SharePoint “disaster recovery”...]]></description>
      <content:encoded><![CDATA[<p>Just a quick clarification on terminology &amp; methodologies for SharePoint “disaster recovery” (DR).  <p>In case you didn’t know already, multiple SharePoint farms can be run sharing the same content data, which is very handy if you need near 100% uptime for your SharePoint sites &amp; apps. If for any reason your primary farm dies, you have another farm waiting for you. This post <a href="https://blogs.msdn.microsoft.com/sambetts/2015/09/09/introduction-to-running-disaster-recoveryhot-standby-sharepoint-farms/">isn’t new</a> in ideas; this is mainly just a quick note on terminology &amp; why there are these differences really, as there is still some confusion.  <p>This trick is achieved by sharing certain databases between two farms, with said databases being in read/write on the “primary” side. All the users are on the whichever farm has read/write access to the databases with the other side(s) receiving any data changes &amp; running in read-only mode.  <p>If for any reason we need to switch farms, we <a href="https://blogs.msdn.microsoft.com/sambetts/2015/10/27/sharepoint-disaster-recovery-failover-techniques/">put the read-only DBs in read/write mode and send everyone to the other farm</a>.  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/04/clip_image00231.jpg"><img title="clip_image002" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/2016/04/clip_image002_thumb26.jpg" width="578" height="453"></a>  <p>SharePoint fully supports having service-application &amp; content-databases in read-only mode and can switch between the two modes without any intervention.  <h3>A Quick History – Secondary Farm for DR Only</h3> <p>Back in the day, before SQL Server databases could be kept in sync with either mirroring or log-shipping. At least in the case of <a href="https://blogs.msdn.microsoft.com/sambetts/2013/10/11/hot-standbydisaster-recovery-sharepoint-farms-basic-setup-failover/">SharePoint DR with log-shipping</a> at least (which was the most common DR method), the problem was that switching-over the read/write SQL instances was a “one-hit” use. That’s to say you could easily switch from primary SQL instance to the secondary instance (in the event of the need arising), but going back again took a lot more work.  <p>In the event of a failure on farm 1, we’d go from this:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/04/image673.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/04/image_thumb539.png" width="190" height="240"></a>  <p>…to this…  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/04/image674.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/04/image_thumb540.png" width="183" height="240"></a> <p>The only problem is that the switch back for SQL can take a while to get online &amp; ready to failover again.  <p>Anyway, because of this “one-way” failover nature, the secondary farm was strictly used for emergencies only, hence the concept of the farm being “only for disasters” and therefore the name “disaster recovery farm”.  <p>Normally this was fine because it’s rare for multiple critical, farm-wide problems to happen on both sides. Not impossible, but rare, so this was still a good option to have available even if it was just for critical failures on the primary farm only.  <h3>Enter: Quick-Switching Failovers with AlwaysOn</h3> <p>These days with <a href="https://blogs.msdn.microsoft.com/sambetts/2015/04/24/setting-up-sharepoint-disaster-recovery-sites-with-sql-alwayson/">SQL Server AlwaysOn</a>, SQL instances switching is very much easier than before. For one thing, when we switch primary SQL instances, switching back doesn’t require any extra work.  <p>What does that mean? Well it means now we can switch between the two SQL instances much quicker than before.  <p>What does <i>that</i> mean? Simple really; enter the concept of “active/passive” farms rather than the more dramatic “disaster recovery” farm model. With active/passive farms switching is much quicker; just a simple SQL failover + users redirect each time.  <p>Now we can go from this:  <p><a href="https://msdnshared.blob.core.windows.net/media/2016/04/image675.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/04/image_thumb541.png" width="184" height="240"></a> <p>…to this… <p><a href="https://msdnshared.blob.core.windows.net/media/2016/04/image676.png"><img title="image" style="border-top: 0px;border-right: 0px;border-bottom: 0px;padding-top: 0px;padding-left: 0px;border-left: 0px;padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/04/image_thumb542.png" width="195" height="240"></a> <p>…and back again. And back again; no restores or DB tricks needed except a failover.  <h3>What’s the Correct Name &amp; DR Model Then?</h3> <p>Good question; a lot depends on your original plans for the 2<sup>nd</sup> farm. In general, the old-style “only in disasters” model is a bit rubbish as it relies on having a disaster to know whether everything will even work, as it is the “nuclear option” for disasters. I’ve seen cases where everything “worked” on the DR site but when push-came-to-shove, the hardware just wasn’t ready for the same load; and of course, this only became apparent when the primary went nuclear so everyone was moved over to the DR site.  <p>Partly to avoid unpleasant surprises, my recommendation is we forget about “nuclear option DR farms” and just get used to having two equally active SharePoint farms (as in both switching between active/passive). Now we have an easy way of failing over there doesn’t seem like much reason not to, and it guarantees that both <i>could</i> work in the event of an emergency.  <h3>Remind me Again – What Could Force a Failover? </h3> <p>Patching &amp; updates mainly; it’s a necessary but risky business, on any platform.  <p>Patching Windows, SQL Server(s), SharePoint installations; all of these have risks in that there’s always a chance whatever update will break services. From Windows platform to .net to SharePoint; despite our best efforts, servers are complicated beasts so very occasionally something may slip through the cracks.  <p>This isn’t something specifically tied to Microsoft patches either; I challenge someone to find a vendor that doesn’t have occasional patching fracases. Hint: there aren’t any.  <p>The solution to this is simple: test patches first, and have another production system on stand-by in case something critical dies.  <p>Have no single points of failure in other words, and active/passive farms are the ultimate high-availability SharePoint solution because they’re the only architectures that achieve this.  <p>Patching isn’t the only reason; your own code may cause issues, and it’s nice to have quick failback options. I can think of more than more big SharePoint customer that’s benefited greatly by having this capability for handling bad code rollouts.  <p>There’s all sorts of reasons why it’s worth doubling-up on farms, but mostly it’s for the reasons you can’t think of you’ll need it the most ;)  <p>&nbsp; <p>Cheers,  <p>Sam Betts]]></content:encoded>
    </item>
    <item>
      <title>SharePoint Upgrade/Configuration Wizard Never Finishes</title>
      <link>https://docs.microsoft.com/archive/blogs/sambetts/sharepoint-upgrade-configuration-wizard-never-finishes</link>
      <pubDate>Fri, 01 Apr 2016 13:27:32 GMT</pubDate>
      <dc:creator><![CDATA[Sam Betts MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sambetts/?p=1193</guid>
      <description><![CDATA[Some people may have had issues where the SharePoint Configuration Wizard never seems to finish an...]]></description>
      <content:encoded><![CDATA[Some people may have had issues where the SharePoint Configuration Wizard never seems to finish an upgrade. This is a quick &amp; dirty post to explain how finish it, as cleanly as possible.

First; terminate the process via task-manager as closing the form will try and abort the dead upgrade process, so will never actually abort (so won’t close the wizard either).

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/clip_image0011.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="clip_image001" src="https://msdnshared.blob.core.windows.net/media/2016/04/clip_image001_thumb1.png" alt="clip_image001" width="374" height="295" border="0" /></a>

Closing programs via task manager will send it WM_CLOSE, and then drop the process by force if it doesn’t respond within a few seconds. Well, the process hasn’t crashed so the program will exit “cleanly” at least.

Now we just have to finish the upgrade from the command-line. Open a SharePoint PowerShell command-line &amp; run:
<blockquote>PSCONFIG.EXE -cmd upgrade -inplace b2b -wait</blockquote>
This will work this time:

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/clip_image003.jpg"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="clip_image003" src="https://msdnshared.blob.core.windows.net/media/2016/04/clip_image003_thumb.jpg" alt="clip_image003" width="657" height="290" border="0" /></a>

That’s the hard bit done; the databases are all upgraded.

Next, let the wizard reinstall &amp; reconfigure the application &amp; features as we skipped this bit in PSConfig:

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/clip_image004.png"><img style="padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px" title="clip_image004" src="https://msdnshared.blob.core.windows.net/media/2016/04/clip_image004_thumb.png" alt="clip_image004" width="510" height="440" border="0" /></a>

&nbsp;

That’s it! Server upgraded.

&nbsp;

Cheers,

// Sam Betts]]></content:encoded>
    </item>
    <item>
      <title>Patching SharePoint DR Farms with Replicated Service-Applications with SQL Server AlwaysOn</title>
      <link>https://docs.microsoft.com/archive/blogs/sambetts/patching-sharepoint-dr-farms-with-replicated-service-applications-with-sql-server-alwayson</link>
      <pubDate>Wed, 23 Mar 2016 17:31:20 GMT</pubDate>
      <dc:creator><![CDATA[Sam Betts MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/sambetts/?p=1124</guid>
      <description><![CDATA[So now we’ve got an active/passive SharePoint farm solution setup, the next question that is how to...]]></description>
      <content:encoded><![CDATA[<p>So now we’ve got an active/passive SharePoint farm solution setup, the next question that is how to patch both farms with as little drama as possible. We need to patch one farm while the other’s in use so that our beloved users don’t notice anything’s even happened to SharePoint – one of the key reasons to have passive/active farms in fact.</p> <p>How to patch with no downtime with SQL Server AlwaysOn has been <a href="https://blogs.msdn.microsoft.com/sambetts/2015/08/20/patching-sharepoint-with-no-downtime-using-sql-server-alwayson/">covered already</a>, but not with <a href="https://blogs.msdn.microsoft.com/sambetts/2016/03/21/running-sharepoint-service-applications-in-read-only-mode-for-disaster-recovery-farms/">service-applications in sync</a> too. This is a complex subject so be prepared!</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/03/image539.png"><img title="image" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/2016/03/image_thumb407.png" width="250" height="442"></a></p> <p>It helps greatly if content &amp; service-applications are in different SQL Server Availability Groups, but that’s not always how the back-end is setup; quite often all SharePoint databases are on the same one. This post outlines the process for both cases.</p> <p>Some key terms here:</p> <ul> <li>Primary farm = “farm1”.  <li>Secondary farm = “farm2”.  <li>SQL Server AlwaysOn Availability Group = “AG”.  <li>PSConfig = <a href="https://technet.microsoft.com/en-us/library/cc263093(v=office.14).aspx">this command-line tool</a> preferably, or the SharePoint Configuration Wizard. </li></ul> <p>Note: you can do this either way round; swap farm1 for farm2 if you like, and the processes are the same, just in reverse.</p> <h1>The Synchronised Farm Upgrade Challenge</h1> <p>First though, a bit about the challenge we’re up against. It’s quite epic if I don’t say so myself…</p> <p>In short, we have two distinct farms that share databases in active/passive mode. <b>We need to upgrade both farms without users suffering any downtime</b>.</p> <p>With a setup whereby service application databases are synchronised between two separate farms, you have an issue where you’ll need to upgrade the service application databases at some point – how to do so while also keeping them operational 100% of the time?</p> <p>PSConfig will obviously have issues if it has to upgrade a read-only service-application database, so we can’t just run this on the inactive farm without some tricks &amp; workarounds to side-step these roadblocks.</p> <p>Finally, given we want to try and keep users in read/write mode in all SharePoint sites, the challenge becomes harder still. How to let users continue working normally but also locking databases for upgrades, especially given they’re synchronised between two (temporarily) disjointed SharePoint versions?</p> <h1>Synced Farm Upgrade Strategies</h1> <p>There’s a few strategies to attack this “how to upgrade synced farms” challenge:</p> <ol> <li>All SharePoint functionality kept in read-only mode until both farms are fully upgraded.  <li>Users have read/write access while upgrade is going on. </li></ol> <p>The first strategy is the easiest, but rarely acceptable for the business needs – users need to update, and if they can’t it shouldn’t be for long. SharePoint patching can potentially be a long process!</p> <p>The second strategy is more commonplace, but with a couple of different approaches to getting there.</p> <h2>Upgrading with Read/Write Functionality</h2> <p>Two approaches to patching SharePoint while users can still edit content:</p> <ol> <li>Disconnect service-applications from 1<sup>st</sup> upgraded farm so we can keep all SharePoint databases in read-only mode during PSConfig.  <li>Upgrade the service-app databases on 1<sup>st</sup> farm to be upgraded; overwrite the 2<sup>nd</sup> farms’ databases once all farms are fully upgraded. </li></ol> <p>The first approach basically involves upgrading each farm without anything attached &amp; mounting the service-apps again with the yet-to-be-upgraded databases:</p> <ul> <li>Users &amp; SharePoint databases active on farm1  <ul> <li>Remove all synced service-apps &amp; content DBs from farm2.  <li>Upgrade farm2  <li>Add all synced service-apps &amp; content DBs to farm2 again. </li></ul> <li>Switch users &amp; databases to farm2  <ul> <li>Remove all synced service-apps &amp; content DBs from farm1.  <li>Upgrade farm1  <li>Add all synced service-apps &amp; content DBs to farm1 again. </li></ul> <li>Now finish farm upgrade with <a href="https://msdn.microsoft.com/EN-US/library/microsoft.sharepoint.administration.spdatabase.upgrade.aspx">SPDatabase.Upgrade</a> on everything previously disconnecte. </li></ul> <p>I don't think this is the best way so I’m focusing on the last option because it <span style="text-decoration: underline">doesn’t</span> involve recreating service-applications, which can be quite a big task admin task potentially. Also, it is (in my opinion) safer as there's more chance to react &amp; rollback should you have any upgrade problems, even if both methods are valid.</p> <h1>How to Upgrade Synchronised Farms Without Deleting Service-Applications</h1> <p>As if it wasn't complicated enough already, <em>how</em> then to upgrade via my preferred approach also depends on if you’ve put all your SharePoint databases in a single SQL Server Availability Group or not (probably you have)…</p> <h2>All Databases in One Availability Group (AG)</h2> <p>This is the most common setup, but the most complex to update. For this configuration, we’ll patch the farm2 service-application DBs while users are still on farm1 (in full read/write mode for content databases). That does means we have to make sure farm1 <span style="text-decoration: underline">doesn’t</span> allow updates to (only) service-applications while we upgrade the same service-apps on farm2. This is easily done by making the service-apps read-only on farm1 during farm2s’ upgrade.</p> <p><b>Short version</b>:</p> <ol> <li>Patch farm2 while users &amp; DBs stay on farm1.  <ul> <li>Install binaries.  <li>Dismount content DBs on farm2.  <li>Disconnect service-app DBs from availability group.  <ul> <li>Make databases on farm1 read-only.  <li>Allow read/write for databases on farm2. </li></ul> <li>Finish upgrade on farm2 with PSConfig - <strong>upgrade service-applications too</strong>.  <li>Mount content-databases to farm2.  <li>Switch users and databases to farm2. </li></ul> <li>Patch farm1 while users on farm2  <ul> <li>Install binaries.  <li>Dismount content DBs  <li>Drop read-only service-app databases on farm1 SQL instance.  <li>Add service-app DBs from farm2 SQL instance back to availability group.  <li>Finish upgrade on farm1 with PSConfig now farm1 has <span style="text-decoration: underline">already-upgraded</span> service-app DBs. </li></ul> <li>Upgrade content databases in PowerShell. All done! </li></ol> <p>We need to make service-app DBs read-only on the active farm (farm1) because farm2 service-app databases will ultimately overwrite them, so any data we change on farm1 in any service-app during upgrade would be lost. Users can still edit <i>content</i> while farm2 is being patched, just not taxonomies, user profiles, etc. Small note: this doesn’t include search btw; that’s a whole different game.</p> <p>So far so good. But the complication is that farm1 has read/write access to the AG while we patch farm2 so our beloved users can still keep working in normal read/write mode for their content &amp; sites. Of course though farm1 having full read/write access to the synced databases means therefore farm2 only has <i>read-only</i> access to everything in the AG, which will break the PSConfig stage of the upgrade if we don’t workaround this.</p> <h3>Patch farm2 while users use farm1</h3> <p>So in this example, our users keep using the normal primary site &amp; we’re patching the secondary (farm2) in preparation.</p> <ol> <li>Install patch binaries on farm2; all servers at once. You may need to reboot afterwards. </li></ol> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image0036.png"><img title="clip_image003" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image003" src="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image003_thumb4.png" width="358" height="124"></a></p> <p>In the meantime, we have farm1 to handle traffic and farm2 will have read-only access to everything not configuration.</p> <ol> <li>Farm2 now has latest binaries; now needs to run PSConfig to update databases and <a href="https://blogs.msdn.microsoft.com/sambetts/2013/08/22/farm-patching-explained-high-availability-sharepoint/">other stuff</a>. </li></ol> <ul> <ul> <li>Dismount content-DBs from farm2 to avoid PSConfig errors. </li></ul></ul> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image0052.jpg"><img title="clip_image005" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image005" src="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image005_thumb2.jpg" width="645" height="84"></a></p> <p>Next-up, how to deal with service-app upgrades.</p> <h3>Upgrade Service-Applications on Farm2</h3> <p>As mentioned above, we now have the issue that read-only service app DBs aren’t upgradable in PSConfig, which is a problem as we’re currently upgrading a farm with everything in read-only.</p> <p>We’re going to deal with this by actually upgrading our service-apps now. That’s a bit awkward given we can’t do so easily as we’re in one AG for all databases, so time to remove the service-app databases from the AG sow farm2 can upgrade them.</p> <ul> <li>Remove service-apps from the availability group.  <ul> <li>Run this for <span style="text-decoration: underline">each</span> service-app database on the <b>primary</b> SQL AlwaysOn instance (change the database name as necessary): </li></ul></li></ul> <blockquote> <p><span style="font-size: small"><span style="color: #0000ff">ALTER AVAILABILITY GROUP</span> [SP2013]</span></p> <p><span style="font-size: small"><span style="color: #0000ff">REMOVE DATABASE</span> [App_Management];</span></p> <p><span style="font-size: small;color: #0000ff">GO</span></p></blockquote> <ul> <ul> <li>The database in question will no long be replicating between SQL instances as it's no long in the AG, with the secondary SQL instance having the database in a “restoring” state. </li></ul></ul> <p>&nbsp;</p> <ul> <li>Set farm1 databases as read-only &amp; enable read/write for farm2 databases. Run on the <b>primary</b> SQL node: </li></ul> <blockquote> <p><span style="font-size: small"><span style="color: #0000ff">ALTER DATABASE</span> [App_Management] <span style="color: #0000ff">SET READ_ONLY WITH ROLLBACK IMMEDIATE</span></span></p> <p><span style="font-size: small;color: #0000ff">GO</span></p></blockquote> <ul> <ul> <li>The database on the primary AlwaysOn SQL instance will now be read-only.  <ul> <li>Later, we’re going to overwrite the primary instance with the upgraded secondary instance one it’s upgraded &amp; we’re ready. </li></ul> <li>Now we need to restore normal operation to the database on the <b>secondary</b> SQL instance so we can read &amp; write to it. Run this on the <b>secondary</b> SQL node: </li></ul></ul> <blockquote> <p><span style="font-size: small"><span style="color: #0000ff">RESTORE DATABASE</span> [App_Management] </span></p> <p><span style="font-size: small;color: #0000ff">GO</span></p></blockquote> <p>Make sure you repeat this process for all service-app DBs.</p> <p>Now farm2 should have full read/write access to the service-application DBs &amp; farm1 with read-only access to the same databases. Farm1 still has full read/write access to content databases.</p> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image0066.png"><img title="clip_image006" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image006" src="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image006_thumb5.png" width="327" height="404"></a></p> <p>This is how your farm1 SQL instance should look like. Nobody can edit these service-apps, which is good for the time-being. Content databases are in read/write mode at least, so unlikely to be a big deal.</p> <ul> <li>Run PSConfig on farm2 to finish upgrade, upgrading the now R/W service-apps too. </li></ul> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image0084.jpg"><img title="clip_image008" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image008" src="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image008_thumb4.jpg" width="448" height="386"></a></p> <ul> <li>Attach content DB to upgraded secondary farm (content DB still un-upgraded). </li></ul> <p>Congratulations, farm2 is all upgraded (minus the content DB).</p> <h3>Patch Farm1 site while users use Farm2</h3> <p>With one down, there’s one to go. This is a bit simpler.</p> <ul> <li>Failover users + content databases to upgraded farm2.  <ul> <li>Users now have full read/write (upgraded) service-apps as well as read/write content-databases too. </li></ul> <li>Detach content-database from farm1.  <li>Install binaries on farm1 now nobody’s using it. </li></ul> <p>Once everything’s been installed &amp; rebooted (if necessary), we need to run PSConfig. But this time we don’t need to upgrade the service-app databases as we did that already, so…</p> <ul> <li>Drop all read-only service-app databases on farm1 SQL instance. </li></ul> <blockquote> <p><span style="font-size: small"><span style="color: #0000ff">DROP DATABASE</span> [App_Management]</span></p> <p><span style="font-size: small;color: #0000ff">GO</span></p></blockquote> <ul> <li>On farm2 SQL instance, add service-application databases back into availability group. </li></ul> <p><a href="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image0105.jpg"><img title="clip_image010" style="border-left-width: 0px;border-right-width: 0px;border-bottom-width: 0px;padding-top: 0px;padding-left: 0px;padding-right: 0px;border-top-width: 0px" border="0" alt="clip_image010" src="https://msdnshared.blob.core.windows.net/media/2016/03/clip_image010_thumb5.jpg" width="426" height="435"></a></p> <p>When this completes, farm 1 will also have the upgraded service-application databases, and they’ll be back in sync again.</p> <ul> <li>Run PSConfig to finish upgrade.  <ul> <li>Here’s the clever bit: <b>it won’t need to upgrade the service-application databases</b> as they’ve already been upgraded (copies from farm2). </li></ul></li></ul> <p>Congratulations! Farm1 is now also upgraded. Finish off the process with:</p> <ul> <li>Upgrade content-database with <a href="https://technet.microsoft.com/en-us/library/ff607813.aspx">Upgrade-SPContentDatabase</a>. </li></ul> <h2>Content &amp; Service-Apps in Different AGs</h2> <p>If you have your service-app DBs &amp; content DBs in separate Availability Groups, then well done you for forward-thinking - it'll now pay off. This is the better setup as it gives greater failover dexterity – one SharePoint farm can have service-applications in read-only but content in full-read/write at the same time. Each group fails-over independently; very handy for patching &amp; upgrading SharePoint databases!</p> <p><b>Short version</b>:</p> <ol> <li>Patch farm2 while users &amp; DBs stay on farm1.  <ul> <li>Install binaries.  <li>Dismount content DBs on farm2.  <li>Failover “service-apps” AG to farm2 SQL instance.  <ul> <li>No hacks needed here; it’ll just work. </li></ul> <li><b>Suspend data movement for all service-app DBs.</b>  <ul> <li>You’ll break farm1 if it receives the patched databases without having the equivalent binaries installed, which right now it doesn’t have. <b></b></li></ul> <li>Finish upgrade on farm2 with PSConfig. Service-apps upgraded because they’re read/write  <li>Mount content-databases to farm2.  <li>Switch users and <span style="text-decoration: underline">content</span>-databases to farm2. </li></ul> <li>Patch farm1 while users on farm2  <ul> <li>Install binaries.  <li>Dismount content DBs  <li>Resume data movement in service-app AG so farm1 gets patch changes for service-app DBs.  <li>Finish upgrade on farm1 with PSConfig. </li></ul> <li>Upgrade content database in PowerShell. </li></ol> <p>Ah, so much cleaner!</p> <h1>Wrap-Up</h1> <p>That’s it for now. If anything’s not clear, let me know in the comments below – it’s a complex subject so it’s possible.</p> <p>&nbsp;</p> <p>Cheers,</p> <p>Sam Betts</p>]]></content:encoded>
    </item>
  </channel>
</rss>