<?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>while (alive) { writeCode(); }</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/brporter/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/brporter/feed.xml</link>
    <description />
    <lastBuildDate>Tue, 16 Apr 2019 04:50:14 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Blog Moved!</title>
      <link>https://docs.microsoft.com/archive/blogs/brporter/blog-moved</link>
      <pubDate>Sun, 30 Aug 2015 09:36:02 GMT</pubDate>
      <dc:creator><![CDATA[Bryan L. Porter]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brporter/2015/08/30/blog-moved/</guid>
      <description><![CDATA[I've moved my blog to bryanporter.com. Come visit me there!

]]></description>
      <content:encoded><![CDATA[I've moved my blog to <a href="https://bryanporter.com">bryanporter.com</a>. Come visit me there!

]]></content:encoded>
    </item>
    <item>
      <title>How To: Update Site Collection Quotas For Existing Site Collections</title>
      <link>https://docs.microsoft.com/archive/blogs/brporter/how-to-update-site-collection-quotas-for-existing-site-collections</link>
      <pubDate>Fri, 25 Feb 2011 13:28:00 GMT</pubDate>
      <dc:creator><![CDATA[Bryan L. Porter]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brporter/2011/02/25/how-to-update-site-collection-quotas-for-existing-site-collections/</guid>
      <description><![CDATA[Setting the default quota template for site collections in a web application is easy enough. But...]]></description>
      <content:encoded><![CDATA[<p>Setting the default quota template for site collections in a web application is easy enough. But what do you do when you want to change the template associated with some or all of the site collection in a web application? Out of the box, there are no good tools to do this. While we certainly have a UI to manipulate the quota template associated to a site collection, it's a single-site-collection-at-a-time affair - a daunting task when you're dealing with more than even a few site collections.</p>
<p>Take the example of My Sites. When planning your My Site deployment, you'll probably spend good bit of time planning out the storage neccessary to support your end user adoption rate of My Sites, and also spend a fair bit of time discussing how much space (maximum) you want to allow your users to consume. You'll enforce this with a template. But what happens in 6 months, when you decide that your estimates were too high, or too low, and you need to either increase the storage that end users can use, or decrease the storage? Manually adjusting 1000's of site collections would take days!</p>
<p>Enter a wee bit of PowerShell script and the SharePoint 2010 Management Shell. We have to use a few bits of the SharePoint object model to make this work, but this task is simple enough to be approachable by even the most code-averse IT pro's out there:</p>
<p><code># Replace all site collection quotas in a web application with a new template<br />$TemplateName = "My Template Name"<br />$WebApplicationUrl = "https://my/"<br /><br />$contentService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService<br />$quotaTemplate = $contentService.QuotaTemplates[$TemplateName]<br />$webApplication = Get-SPWebApplication $WebApplicationUrl<br />$webApplication.Sites | ForEach-Object { try { $_.Quota = $quotaTemplate; } finally { $_.Dispose(); } }<br /></code></p>
<p>&nbsp;In the above, just replace "My Template Name" with the name of the new or updated quota template you'd like to assign, and https://my/ with the URL of the web application you'd like updated. This script will replace the quota template on every site collection within that web application.</p>
<p>Too heavy handed for you? What if you only wanted to replace the template assigned to a site collection if it was already assigned a specific template? So, for instance, you've got some sites using a quota template called "Bad Template", but you don't want to use that template anymore, and you want to replace the quota templates assigned to those folks with a new template, "Good Template". What to do?</p>
<p>Enter a nother wee bit of script:</p>
<p><code># Replace all site collections having a specific quota template with a new quota template<br />$OldTemplateName = "Bad Template"<br />$NewTemplateName = "Good Template"<br />$WebApplicationUrl = "https://my/"<br /><br />$contentService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService<br />$quotaTemplate = $contentService.QuotaTemplates[$OldTemplateName]<br />$replaceQuotaTemplate = $contentService.QuotaTemplates[$NewTemplateName]<br /><br />$webApplication = Get-SPWebApplication $WebApplicationUrl<br /><br />$webApplication.Sites | ForEach-Object { try { if ($_.Quota.QuotaID -eq $quotaTemplate.QuotaID) { $_.Quota = $replaceQuotaTemplate } } finally { $_.Dispose(); } }<br /></code></p>
<p>Again, simply replace "Bad Template" with the template you want to replace, "Good Template" with the name of the new template to replace "Bad Template" with, and https://my/ with the URL of the web application you want to process.</p>
<p>But wait! What if you don't want *any* quota templates! How do I remove the quota templates from all sites with a specific quota template already applied? Easy enough:</p>
<p><code># Replace all site collections having a specific quota template with a new quota template<br />$OldTemplateName = "Bad Template"<br />$WebApplicationUrl = "https://my/"<br /><br />$contentService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService<br />$quotaTemplate = $contentService.QuotaTemplates[$OldTemplateName]<br /><br />$webApplication = Get-SPWebApplication $WebApplicationUrl<br /><br />$webApplication.Sites | ForEach-Object { try { if ($_.Quota.QuotaID -eq $quotaTemplate.QuotaID) { $_.Quota = $null } } finally { $_.Dispose(); } }<br /></code></p>
<p>Hope that helps those of you struggling with ex-post-facto updates to site collection quotas!</p>]]></content:encoded>
    </item>
    <item>
      <title>Adding users and claims to a site from PowerShell</title>
      <link>https://docs.microsoft.com/archive/blogs/brporter/adding-users-and-claims-to-a-site-from-powershell</link>
      <pubDate>Thu, 02 Dec 2010 09:02:23 GMT</pubDate>
      <dc:creator><![CDATA[Bryan L. Porter]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brporter/2010/12/02/adding-users-and-claims-to-a-site-from-powershell/</guid>
      <description><![CDATA[Update: Astute readers will note that the following examples make use of the scratch custom claims...]]></description>
      <content:encoded><![CDATA[<p><font style="background-color: #ffff00">Update: Astute readers will note that the following examples make use of the <a href="https://blogs.msdn.com/b/brporter/archive/2010/12/01/the-scratch-custom-claims-provider.aspx">scratch custom claims provider</a>.</font></p>  <p>Recently, the question of automating custom claim assignments to SharePoint groups has come up. For example, if you’ve got a custom claim provider that provides a custom claim of type <a href="https://schemas.bryanporter.com/favoriteColor">https://schemas.bryanporter.com/favoriteColor</a>, how could you add all users that present that claim to your farm into the Visitors group of a SharePoint site?</p>  <p>Managing users is pretty straightforward. So, if you had a user <em>CONTOSO\brporter</em> that already existed in a SharePoint site, you could simple run the following PowerShell to add them to the site and assign them to the Team Site Visitors group:</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:27c4262a-88a9-44c5-8ca1-68fa07652b0b" class="wlWriterEditableSmartContent"><pre style=" width: 558px; height: 89px;background-color:White;overflow: auto;"><div><!--

code highlighting produced by Actipro CodeHighlighter (freeware)
https://www.CodeHighlighter.com/

--><span style="color: #008080;">1</span> <span style="color: #008000;">#</span><span style="color: #008000;"> If the user already exists in the site...</span><span style="color: #008000;">
</span><span style="color: #008080;">2</span> <span style="color: #008000;"></span><span style="color: #800080;">$user</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> Get</span><span style="color: #000000;">-</span><span style="color: #000000;">SPUser </span><span style="color: #000000;">-</span><span style="color: #000000;">Identity (New</span><span style="color: #000000;">-</span><span style="color: #000000;">SPClaimsPrincipal </span><span style="color: #000000;">-</span><span style="color: #000000;">Identity CONTOSO\brporter </span><span style="color: #000000;">-</span><span style="color: #000000;">IdentityType WindowsSamAccountName).ToEncodedString() </span><span style="color: #000000;">-</span><span style="color: #000000;">Web http:</span><span style="color: #000000;">//</span><span style="color: #000000;">&lt;web site URL</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #008080;">3</span> <span style="color: #000000;">Set</span><span style="color: #000000;">-</span><span style="color: #000000;">SPUser </span><span style="color: #000000;">-</span><span style="color: #000000;">Identity </span><span style="color: #800080;">$user</span><span style="color: #000000;"> </span><span style="color: #000000;">-</span><span style="color: #000000;">Web http:</span><span style="color: #000000;">//</span><span style="color: #000000;">&lt;web site URL</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"> </span><span style="color: #000000;">-</span><span style="color: #000000;">Group </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Team Site Visitors</span><span style="color: #800000;">&quot;</span></!--

code></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></!--></div>

<p>If your user was new to the site, replace Get-SPUser with New-SPUser and you are all set:</p>

<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:766afae0-617b-466c-9c3a-bc0d6cca88d6" class="wlWriterEditableSmartContent"><pre style=" width: 558px; height: 93px;background-color:White;overflow: auto;"><div><!--

code highlighting produced by Actipro CodeHighlighter (freeware)
https://www.CodeHighlighter.com/

--><span style="color: #008080;">1</span> <span style="color: #008000;">#</span><span style="color: #008000;"> If the user is new to the site</span><span style="color: #008000;">
</span><span style="color: #008080;">2</span> <span style="color: #008000;"></span><span style="color: #800080;">$user</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> New</span><span style="color: #000000;">-</span><span style="color: #000000;">SPUser </span><span style="color: #000000;">-</span><span style="color: #000000;">UserAlias (New</span><span style="color: #000000;">-</span><span style="color: #000000;">SPClaimsPrincipal </span><span style="color: #000000;">-</span><span style="color: #000000;">Identity CONTOSO\tuser </span><span style="color: #000000;">-</span><span style="color: #000000;">IdentityType WindowsSamAccountName).ToEncodedString() </span><span style="color: #000000;">-</span><span style="color: #000000;">Web http:</span><span style="color: #000000;">//</span><span style="color: #000000;">&lt;web site URL</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #008080;">3</span> <span style="color: #000000;">Set</span><span style="color: #000000;">-</span><span style="color: #000000;">SPUser </span><span style="color: #000000;">-</span><span style="color: #000000;">Identity </span><span style="color: #800080;">$user</span><span style="color: #000000;"> </span><span style="color: #000000;">-</span><span style="color: #000000;">Web http:</span><span style="color: #000000;">//</span><span style="color: #000000;">&lt;web site URL</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"> </span><span style="color: #000000;">-</span><span style="color: #000000;">Group </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Team Site Visitors</span><span style="color: #800000;">&quot;</span></!--

code></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></!--></div>

<p>But what about a claim? What if you only want to allow users that present, say, a <em>favoriteColor </em>claim with a value of <em>Blue</em> to be able to visit a particular site? To make sure that ardent adorers of the color <em>Blue</em> can visit your site:</p>

<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:13f7e562-a03b-4652-a49f-9900e345fe8b" class="wlWriterEditableSmartContent"><pre style=" width: 558px; height: 142px;background-color:White;overflow: auto;"><div><!--

code highlighting produced by Actipro CodeHighlighter (freeware)
https://www.CodeHighlighter.com/

--><span style="color: #008080;">1</span> <span style="color: #008000;">#</span><span style="color: #008000;"> If you are securing based on a claim</span><span style="color: #008000;">
</span><span style="color: #008080;">2</span> <span style="color: #008000;"></span><span style="color: #800080;">$claimProvider</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> Get</span><span style="color: #000000;">-</span><span style="color: #000000;">SPClaimProvider </span><span style="color: #000000;">|</span><span style="color: #000000;"> where { </span><span style="color: #800080;">$_</span><span style="color: #000000;">.DisplayName </span><span style="color: #008080;">-eq</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">The Name Of My Claim Provider</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">}
</span><span style="color: #008080;">3</span> <span style="color: #000000;"></span><span style="color: #800080;">$claim</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> New</span><span style="color: #000000;">-</span><span style="color: #000000;">SPClaimsPrincipal </span><span style="color: #000000;">-</span><span style="color: #000000;">ClaimValue Blue </span><span style="color: #000000;">-</span><span style="color: #000000;">ClaimType http:</span><span style="color: #000000;">//</span><span style="color: #000000;">schemas.bryanporter.com</span><span style="color: #000000;">/</span><span style="color: #000000;">favoriteColor </span><span style="color: #000000;">-</span><span style="color: #000000;">ClaimProvider </span><span style="color: #800080;">$claimProvider</span><span style="color: #000000;">.ClaimProvider
</span><span style="color: #008080;">4</span> <span style="color: #000000;">
</span><span style="color: #008080;">5</span> <span style="color: #000000;"></span><span style="color: #800080;">$user</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> New</span><span style="color: #000000;">-</span><span style="color: #000000;">SPUser </span><span style="color: #000000;">-</span><span style="color: #000000;">UserAlias </span><span style="color: #800080;">$claim</span><span style="color: #000000;">.ToEncodedString() </span><span style="color: #000000;">-</span><span style="color: #000000;">Web http:</span><span style="color: #000000;">//</span><span style="color: #000000;">&lt;web site URL</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">
</span><span style="color: #008080;">6</span> <span style="color: #000000;">Set</span><span style="color: #000000;">-</span><span style="color: #000000;">SPUser </span><span style="color: #000000;">-</span><span style="color: #000000;">Identity </span><span style="color: #800080;">$user</span><span style="color: #000000;"> </span><span style="color: #000000;">-</span><span style="color: #000000;">Web http:</span><span style="color: #000000;">//</span><span style="color: #000000;">&lt;web site URL</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"> </span><span style="color: #000000;">-</span><span style="color: #000000;">Group </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Team Site Visitors</span><span style="color: #800000;">&quot;</span></!--

code></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></!--></div>

<p>The non-obvious bit here is that we continue to deal with New-SPUser, even when we’re actually talking about a custom claim. </p>

<p>I should also point out that unless your custom claim provider successfully resolves the claim value and type you won’t get a claim reference that can return a proper encoded string – effectively preventing you from securing on the claim. For more infromation on implementing claim resolution, see <a href="https://blogs.technet.com/b/speschka">Steve Peschka’s</a> most excellent walkthrough on <a href="https://msdn.microsoft.com/en-us/library/ff699494.aspx">MSDN</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>The Scratch Custom Claims Provider</title>
      <link>https://docs.microsoft.com/archive/blogs/brporter/the-scratch-custom-claims-provider</link>
      <pubDate>Wed, 01 Dec 2010 06:52:12 GMT</pubDate>
      <dc:creator><![CDATA[Bryan L. Porter]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brporter/2010/12/01/the-scratch-custom-claims-provider/</guid>
      <description><![CDATA[Frequently, I find it useful to have a common starting point – what Raymond Chen describes as a...]]></description>
      <content:encoded><![CDATA[<p>Frequently, I find it useful to have a common starting point – what <a href="https://blogs.msdn.com/b/oldnewthing">Raymond Chen</a> describes as a “<a href="https://blogs.msdn.com/b/oldnewthing/archive/2003/07/23/54576.aspx">scratch program</a>” (or a <a href="https://blogs.msdn.com/b/oldnewthing/archive/2005/04/22/410773.aspx">new scratch program</a>, for those update-minded types). Within SharePoint, things are never that simple – a scratch SharePoint solution is an empty whiteboard, for better or for worse.</p>  <p>There are plenty of extensibility points within SharePoint that certainly offer up opportunities for scratch programs, though, and one place I find myself sharing – over and over again – my personal scratch implementation is with Custom Claims Providers. And so I submit for your approval, the SimpleClaimsProvider in all its <em>favoriteColor</em> issuing claim glory. This will serve as a starting point for future posts involving custom claims providers, and in the meantime might give a few of you the bits you need in order to make the details of Custom Claims Providers real. For a complete walkthrough, see <a href="https://blogs.technet.com/b/speschka">Steve Peschka’s</a> most excellent write up over on <a href="https://msdn.microsoft.com/en-us/library/ff699494.aspx">MSDN</a>.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:724d9a67-9672-4c98-bd47-ef22daf56e3c" class="wlWriterEditableSmartContent"><pre style=" width: 558px; height: 680px;background-color:White;overflow: auto;"><div><!--

code highlighting produced by Actipro CodeHighlighter (freeware)
https://www.CodeHighlighter.com/

--><span style="color: #008080;">  1</span> <span style="color: #0000FF;">using</span><span style="color: #000000;"> System;
</span><span style="color: #008080;">  2</span> <span style="color: #000000;"></span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.Collections.Generic;
</span><span style="color: #008080;">  3</span> <span style="color: #000000;"></span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.Linq;
</span><span style="color: #008080;">  4</span> <span style="color: #000000;"></span><span style="color: #0000FF;">using</span><span style="color: #000000;"> System.Text;
</span><span style="color: #008080;">  5</span> <span style="color: #000000;">
</span><span style="color: #008080;">  6</span> <span style="color: #000000;"></span><span style="color: #0000FF;">using</span><span style="color: #000000;"> Microsoft.SharePoint;
</span><span style="color: #008080;">  7</span> <span style="color: #000000;"></span><span style="color: #0000FF;">using</span><span style="color: #000000;"> Microsoft.SharePoint.WebControls;
</span><span style="color: #008080;">  8</span> <span style="color: #000000;"></span><span style="color: #0000FF;">using</span><span style="color: #000000;"> Microsoft.SharePoint.Administration;
</span><span style="color: #008080;">  9</span> <span style="color: #000000;"></span><span style="color: #0000FF;">using</span><span style="color: #000000;"> Microsoft.SharePoint.Administration.Claims;
</span><span style="color: #008080;"> 10</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 11</span> <span style="color: #000000;"></span><span style="color: #0000FF;">namespace</span><span style="color: #000000;"> BryanPorter.SP.CCP
</span><span style="color: #008080;"> 12</span> <span style="color: #000000;">{
</span><span style="color: #008080;"> 13</span> <span style="color: #000000;">    </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">class</span><span style="color: #000000;"> SimpleClaimsProvider
</span><span style="color: #008080;"> 14</span> <span style="color: #000000;">        : SPClaimProvider
</span><span style="color: #008080;"> 15</span> <span style="color: #000000;">    {
</span><span style="color: #008080;"> 16</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">static</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> m_claimValueType </span><span style="color: #000000;">=</span><span style="color: #000000;"> Microsoft.IdentityModel.Claims.ClaimValueTypes.String;
</span><span style="color: #008080;"> 17</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">static</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> m_claimType </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">https://schemas.bryanporter.com/favoriteColor</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 18</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 19</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">private</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> m_sharedState </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">null</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 20</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 21</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> SimpleClaimsProvider(</span><span style="color: #0000FF;">string</span><span style="color: #000000;"> displayName)
</span><span style="color: #008080;"> 22</span> <span style="color: #000000;">            : </span><span style="color: #0000FF;">base</span><span style="color: #000000;">(displayName)
</span><span style="color: #008080;"> 23</span> <span style="color: #000000;">        { }        
</span><span style="color: #008080;"> 24</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 25</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">protected</span><span style="color: #000000;"> </span><span style="color: #0000FF;">override</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> FillClaimTypes(List</span><span style="color: #000000;">&lt;</span><span style="color: #0000FF;">string</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"> claimTypes)
</span><span style="color: #008080;"> 26</span> <span style="color: #000000;">        {
</span><span style="color: #008080;"> 27</span> <span style="color: #000000;">            </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (claimTypes </span><span style="color: #000000;">==</span><span style="color: #000000;"> </span><span style="color: #0000FF;">null</span><span style="color: #000000;">)
</span><span style="color: #008080;"> 28</span> <span style="color: #000000;">                </span><span style="color: #0000FF;">throw</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> ArgumentNullException(</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">claimTypes</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">);
</span><span style="color: #008080;"> 29</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 30</span> <span style="color: #000000;">            claimTypes.Add(m_claimType);
</span><span style="color: #008080;"> 31</span> <span style="color: #000000;">        }
</span><span style="color: #008080;"> 32</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 33</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">protected</span><span style="color: #000000;"> </span><span style="color: #0000FF;">override</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> FillClaimValueTypes(List</span><span style="color: #000000;">&lt;</span><span style="color: #0000FF;">string</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"> claimValueTypes)
</span><span style="color: #008080;"> 34</span> <span style="color: #000000;">        {
</span><span style="color: #008080;"> 35</span> <span style="color: #000000;">            </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (claimValueTypes </span><span style="color: #000000;">==</span><span style="color: #000000;"> </span><span style="color: #0000FF;">null</span><span style="color: #000000;">)
</span><span style="color: #008080;"> 36</span> <span style="color: #000000;">                </span><span style="color: #0000FF;">throw</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> ArgumentNullException(</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">claimValueTypes</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">);
</span><span style="color: #008080;"> 37</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 38</span> <span style="color: #000000;">            claimValueTypes.Add(m_claimValueType);
</span><span style="color: #008080;"> 39</span> <span style="color: #000000;">        }
</span><span style="color: #008080;"> 40</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 41</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">protected</span><span style="color: #000000;"> </span><span style="color: #0000FF;">override</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> FillClaimsForEntity(Uri context, SPClaim entity, List</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">SPClaim</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"> claims)
</span><span style="color: #008080;"> 42</span> <span style="color: #000000;">        {
</span><span style="color: #008080;"> 43</span> <span style="color: #000000;">            </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (entity </span><span style="color: #000000;">==</span><span style="color: #000000;"> </span><span style="color: #0000FF;">null</span><span style="color: #000000;">)
</span><span style="color: #008080;"> 44</span> <span style="color: #000000;">                </span><span style="color: #0000FF;">throw</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> ArgumentNullException(</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">entity</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">);
</span><span style="color: #008080;"> 45</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 46</span> <span style="color: #000000;">            </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (claims </span><span style="color: #000000;">==</span><span style="color: #000000;"> </span><span style="color: #0000FF;">null</span><span style="color: #000000;">)
</span><span style="color: #008080;"> 47</span> <span style="color: #000000;">                </span><span style="color: #0000FF;">throw</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> ArgumentNullException(</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">claims</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">);
</span><span style="color: #008080;"> 48</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 49</span> <span style="color: #000000;">            claims.Add(CreateClaim(m_claimType, </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Blue</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">, m_claimValueType));
</span><span style="color: #008080;"> 50</span> <span style="color: #000000;">        }
</span><span style="color: #008080;"> 51</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 52</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">protected</span><span style="color: #000000;"> </span><span style="color: #0000FF;">override</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> FillEntityTypes(List</span><span style="color: #000000;">&lt;</span><span style="color: #0000FF;">string</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"> entityTypes)
</span><span style="color: #008080;"> 53</span> <span style="color: #000000;">        {
</span><span style="color: #008080;"> 54</span> <span style="color: #000000;">            entityTypes.Add(SPClaimEntityTypes.FormsRole);
</span><span style="color: #008080;"> 55</span> <span style="color: #000000;">        }
</span><span style="color: #008080;"> 56</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 57</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">protected</span><span style="color: #000000;"> </span><span style="color: #0000FF;">override</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> FillHierarchy(Uri context, </span><span style="color: #0000FF;">string</span><span style="color: #000000;">[] entityTypes, </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> hierarchyNodeID, </span><span style="color: #0000FF;">int</span><span style="color: #000000;"> numberOfLevels, Microsoft.SharePoint.WebControls.SPProviderHierarchyTree hierarchy)
</span><span style="color: #008080;"> 58</span> <span style="color: #000000;">        {
</span><span style="color: #008080;"> 59</span> <span style="color: #000000;">            </span><span style="color: #0000FF;">throw</span><span style="color: #000000;"> </span><span style="color: #0000FF;">new</span><span style="color: #000000;"> NotImplementedException();
</span><span style="color: #008080;"> 60</span> <span style="color: #000000;">        }
</span><span style="color: #008080;"> 61</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 62</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">protected</span><span style="color: #000000;"> </span><span style="color: #0000FF;">override</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> FillResolve(Uri context, </span><span style="color: #0000FF;">string</span><span style="color: #000000;">[] entityTypes, SPClaim resolveInput, List</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Microsoft.SharePoint.WebControls.PickerEntity</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"> resolved)
</span><span style="color: #008080;"> 63</span> <span style="color: #000000;">        {
</span><span style="color: #008080;"> 64</span> <span style="color: #000000;">            </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (</span><span style="color: #000000;">!</span><span style="color: #000000;">EntityTypesContain(entityTypes, SPClaimEntityTypes.FormsRole))
</span><span style="color: #008080;"> 65</span> <span style="color: #000000;">                </span><span style="color: #0000FF;">return</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 66</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 67</span> <span style="color: #000000;">            PickerEntity pe </span><span style="color: #000000;">=</span><span style="color: #000000;"> CreatePickerEntity();
</span><span style="color: #008080;"> 68</span> <span style="color: #000000;">            pe.Claim </span><span style="color: #000000;">=</span><span style="color: #000000;"> CreateClaim(m_claimType, </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Blue</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">, m_claimValueType);
</span><span style="color: #008080;"> 69</span> <span style="color: #000000;">            pe.Description </span><span style="color: #000000;">=</span><span style="color: #000000;"> Name </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">:</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Blue</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 70</span> <span style="color: #000000;">            pe.DisplayText </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Blue</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 71</span> <span style="color: #000000;">            pe.EntityData[PeopleEditorEntityDataKeys.DisplayName] </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Blue</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 72</span> <span style="color: #000000;">            pe.EntityType </span><span style="color: #000000;">=</span><span style="color: #000000;"> SPClaimEntityTypes.FormsRole;
</span><span style="color: #008080;"> 73</span> <span style="color: #000000;">            pe.IsResolved </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">true</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 74</span> <span style="color: #000000;">            pe.EntityGroupName </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Favorite Color</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 75</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 76</span> <span style="color: #000000;">            resolved.Add(pe);
</span><span style="color: #008080;"> 77</span> <span style="color: #000000;">        }
</span><span style="color: #008080;"> 78</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 79</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">protected</span><span style="color: #000000;"> </span><span style="color: #0000FF;">override</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> FillResolve(Uri context, </span><span style="color: #0000FF;">string</span><span style="color: #000000;">[] entityTypes, </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> resolveInput, List</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Microsoft.SharePoint.WebControls.PickerEntity</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"> resolved)
</span><span style="color: #008080;"> 80</span> <span style="color: #000000;">        {
</span><span style="color: #008080;"> 81</span> <span style="color: #000000;">            </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (</span><span style="color: #000000;">!</span><span style="color: #000000;">EntityTypesContain(entityTypes, SPClaimEntityTypes.FormsRole))
</span><span style="color: #008080;"> 82</span> <span style="color: #000000;">                </span><span style="color: #0000FF;">return</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 83</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 84</span> <span style="color: #000000;">            </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (resolveInput.ToUpper().Contains(</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">BLUE</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">))
</span><span style="color: #008080;"> 85</span> <span style="color: #000000;">            {
</span><span style="color: #008080;"> 86</span> <span style="color: #000000;">                PickerEntity pe </span><span style="color: #000000;">=</span><span style="color: #000000;"> CreatePickerEntity();
</span><span style="color: #008080;"> 87</span> <span style="color: #000000;">                pe.Claim </span><span style="color: #000000;">=</span><span style="color: #000000;"> CreateClaim(m_claimType, </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Blue</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">, m_claimValueType);
</span><span style="color: #008080;"> 88</span> <span style="color: #000000;">                pe.Description </span><span style="color: #000000;">=</span><span style="color: #000000;"> Name </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">:</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Blue</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 89</span> <span style="color: #000000;">                pe.DisplayText </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Blue</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 90</span> <span style="color: #000000;">                pe.EntityData[PeopleEditorEntityDataKeys.DisplayName] </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Blue</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 91</span> <span style="color: #000000;">                pe.EntityType </span><span style="color: #000000;">=</span><span style="color: #000000;"> SPClaimEntityTypes.FormsRole;
</span><span style="color: #008080;"> 92</span> <span style="color: #000000;">                pe.IsResolved </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">true</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 93</span> <span style="color: #000000;">                pe.EntityGroupName </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Favorite Color</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">;
</span><span style="color: #008080;"> 94</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 95</span> <span style="color: #000000;">                resolved.Add(pe);
</span><span style="color: #008080;"> 96</span> <span style="color: #000000;">            }
</span><span style="color: #008080;"> 97</span> <span style="color: #000000;">
</span><span style="color: #008080;"> 98</span> <span style="color: #000000;">        }
</span><span style="color: #008080;"> 99</span> <span style="color: #000000;">
</span><span style="color: #008080;">100</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">protected</span><span style="color: #000000;"> </span><span style="color: #0000FF;">override</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> FillSchema(Microsoft.SharePoint.WebControls.SPProviderSchema schema)
</span><span style="color: #008080;">101</span> <span style="color: #000000;">        {
</span><span style="color: #008080;">102</span> <span style="color: #000000;">            schema.AddSchemaElement(</span><span style="color: #0000FF;">new</span><span style="color: #000000;"> SPSchemaElement(PeopleEditorEntityDataKeys.DisplayName, </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Display Name</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">, SPSchemaElementType.Both));
</span><span style="color: #008080;">103</span> <span style="color: #000000;">        }
</span><span style="color: #008080;">104</span> <span style="color: #000000;">
</span><span style="color: #008080;">105</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">protected</span><span style="color: #000000;"> </span><span style="color: #0000FF;">override</span><span style="color: #000000;"> </span><span style="color: #0000FF;">void</span><span style="color: #000000;"> FillSearch(Uri context, </span><span style="color: #0000FF;">string</span><span style="color: #000000;">[] entityTypes, </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> searchPattern, </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> hierarchyNodeID, </span><span style="color: #0000FF;">int</span><span style="color: #000000;"> maxCount, Microsoft.SharePoint.WebControls.SPProviderHierarchyTree searchTree)
</span><span style="color: #008080;">106</span> <span style="color: #000000;">        {
</span><span style="color: #008080;">107</span> <span style="color: #000000;">            </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (</span><span style="color: #000000;">!</span><span style="color: #000000;">EntityTypesContain(entityTypes, SPClaimEntityTypes.FormsRole))
</span><span style="color: #008080;">108</span> <span style="color: #000000;">                </span><span style="color: #0000FF;">return</span><span style="color: #000000;">;
</span><span style="color: #008080;">109</span> <span style="color: #000000;">
</span><span style="color: #008080;">110</span> <span style="color: #000000;">            </span><span style="color: #0000FF;">if</span><span style="color: #000000;"> (searchPattern.ToUpper().Contains(</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">BLUE</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">))
</span><span style="color: #008080;">111</span> <span style="color: #000000;">            {
</span><span style="color: #008080;">112</span> <span style="color: #000000;">                PickerEntity pe </span><span style="color: #000000;">=</span><span style="color: #000000;"> CreatePickerEntity();
</span><span style="color: #008080;">113</span> <span style="color: #000000;">                pe.Claim </span><span style="color: #000000;">=</span><span style="color: #000000;"> CreateClaim(m_claimType, </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Blue</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">, m_claimValueType);
</span><span style="color: #008080;">114</span> <span style="color: #000000;">                pe.Description </span><span style="color: #000000;">=</span><span style="color: #000000;"> Name </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">:</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> </span><span style="color: #000000;">+</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Blue</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">;
</span><span style="color: #008080;">115</span> <span style="color: #000000;">                pe.DisplayText </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Blue</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">;
</span><span style="color: #008080;">116</span> <span style="color: #000000;">                pe.EntityData[PeopleEditorEntityDataKeys.DisplayName] </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Blue</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">;
</span><span style="color: #008080;">117</span> <span style="color: #000000;">                pe.EntityType </span><span style="color: #000000;">=</span><span style="color: #000000;"> SPClaimEntityTypes.FormsRole;
</span><span style="color: #008080;">118</span> <span style="color: #000000;">                pe.IsResolved </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #0000FF;">true</span><span style="color: #000000;">;
</span><span style="color: #008080;">119</span> <span style="color: #000000;">                pe.EntityGroupName </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">Favorite Color</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">;
</span><span style="color: #008080;">120</span> <span style="color: #000000;">
</span><span style="color: #008080;">121</span> <span style="color: #000000;">
</span><span style="color: #008080;">122</span> <span style="color: #000000;">                searchTree.AddEntity(pe);
</span><span style="color: #008080;">123</span> <span style="color: #000000;">            }
</span><span style="color: #008080;">124</span> <span style="color: #000000;">        }
</span><span style="color: #008080;">125</span> <span style="color: #000000;">
</span><span style="color: #008080;">126</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">override</span><span style="color: #000000;"> </span><span style="color: #0000FF;">string</span><span style="color: #000000;"> Name
</span><span style="color: #008080;">127</span> <span style="color: #000000;">        {
</span><span style="color: #008080;">128</span> <span style="color: #000000;">            </span><span style="color: #0000FF;">get</span><span style="color: #000000;"> { </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">SimpleCCP</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">; }
</span><span style="color: #008080;">129</span> <span style="color: #000000;">        }
</span><span style="color: #008080;">130</span> <span style="color: #000000;">
</span><span style="color: #008080;">131</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">override</span><span style="color: #000000;"> </span><span style="color: #0000FF;">bool</span><span style="color: #000000;"> SupportsEntityInformation
</span><span style="color: #008080;">132</span> <span style="color: #000000;">        {
</span><span style="color: #008080;">133</span> <span style="color: #000000;">            </span><span style="color: #0000FF;">get</span><span style="color: #000000;"> { </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> </span><span style="color: #0000FF;">true</span><span style="color: #000000;">; }
</span><span style="color: #008080;">134</span> <span style="color: #000000;">        }
</span><span style="color: #008080;">135</span> <span style="color: #000000;">
</span><span style="color: #008080;">136</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">override</span><span style="color: #000000;"> </span><span style="color: #0000FF;">bool</span><span style="color: #000000;"> SupportsHierarchy
</span><span style="color: #008080;">137</span> <span style="color: #000000;">        {
</span><span style="color: #008080;">138</span> <span style="color: #000000;">            </span><span style="color: #0000FF;">get</span><span style="color: #000000;"> { </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> </span><span style="color: #0000FF;">false</span><span style="color: #000000;">; }
</span><span style="color: #008080;">139</span> <span style="color: #000000;">        }
</span><span style="color: #008080;">140</span> <span style="color: #000000;">
</span><span style="color: #008080;">141</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">override</span><span style="color: #000000;"> </span><span style="color: #0000FF;">bool</span><span style="color: #000000;"> SupportsResolve
</span><span style="color: #008080;">142</span> <span style="color: #000000;">        {
</span><span style="color: #008080;">143</span> <span style="color: #000000;">            </span><span style="color: #0000FF;">get</span><span style="color: #000000;"> { </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> </span><span style="color: #0000FF;">true</span><span style="color: #000000;">; }
</span><span style="color: #008080;">144</span> <span style="color: #000000;">        }
</span><span style="color: #008080;">145</span> <span style="color: #000000;">
</span><span style="color: #008080;">146</span> <span style="color: #000000;">        </span><span style="color: #0000FF;">public</span><span style="color: #000000;"> </span><span style="color: #0000FF;">override</span><span style="color: #000000;"> </span><span style="color: #0000FF;">bool</span><span style="color: #000000;"> SupportsSearch
</span><span style="color: #008080;">147</span> <span style="color: #000000;">        {
</span><span style="color: #008080;">148</span> <span style="color: #000000;">            </span><span style="color: #0000FF;">get</span><span style="color: #000000;"> { </span><span style="color: #0000FF;">return</span><span style="color: #000000;"> </span><span style="color: #0000FF;">true</span><span style="color: #000000;">; }
</span><span style="color: #008080;">149</span> <span style="color: #000000;">        }
</span><span style="color: #008080;">150</span> <span style="color: #000000;">    }
</span><span style="color: #008080;">151</span> <span style="color: #000000;">}</span></!--

code></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></!--></div>]]></content:encoded>
    </item>
    <item>
      <title>How often will FillClaimsForEntity in my Custom Claims Provider be called?</title>
      <link>https://docs.microsoft.com/archive/blogs/brporter/how-often-will-fillclaimsforentity-in-my-custom-claims-provider-be-called</link>
      <pubDate>Tue, 30 Nov 2010 19:18:17 GMT</pubDate>
      <dc:creator><![CDATA[Bryan L. Porter]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brporter/2010/11/30/how-often-will-fillclaimsforentity-in-my-custom-claims-provider-be-called/</guid>
      <description><![CDATA[This was the question I posed to a colleague this morning. His answer surprised me – “Every time you...]]></description>
      <content:encoded><![CDATA[<p>This was the question I posed to a colleague this morning. His answer surprised me – “Every time you authenticate.”</p>  <p>Before we move on, let’s just call this <em>foreshadowing</em>.</p>  <p>Problem is, this statement was at odds with the behavior that I, and many of you, were seeing/have seen. It just didn’t seem to be true. Clearly, I was seeing that very nearly every single time a page load occurred, my custom claims provider was invoked. Looking at a Fiddler trace, it was also obvious that I wasn’t receiving a 401 on every page request, either. This was certainly different than a web application configured for Windows Classic authentication – where you can sometimes see a 401 on every page load.</p>  <p>First, a refresher on the oddities of a claims based web application.</p>  <p>When a web application is configured for claims based authentication, the IIS binding has Anonymous access enabled on it. This is because, unlike with Windows Classic, authentication is a SharePoint problem with claims (SAML or Windows). SharePoint 2010 manages this via a module (or two) within the IIS pipeline. The enablement of anonymous access generally goes unnoticed by most administrators, since its one of a myriad of settings that the product sets on the IIS binding for a web application. My personal experience is that when administrators do notice this, they generally freak out. It’s okay. The product did this on purpose; if it didn’t you wouldn’t have all that fancy claims-based authentication federating with your partner ADFS instances and delegating the pain of user management. <em>This is a feature</em>.</p>  <p>Refresher over.</p>  <p>So, why do I see a ton of 401’s when running under Windows Classic, but only one, at session start, under Windows Claims? And how does this influence the frequency with which my custom claims provider is going to get called?</p>  <p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/04/83/metablogapi/1212.image_58E33321.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-04-83-metablogapi/1212.image_5F00_58E33321.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/04/83/metablogapi/6102.image_thumb_30D08402.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-04-83-metablogapi/6102.image_5F00_thumb_5F00_30D08402.png" width="374" height="121" /></a>     <br /><em>401’s with Windows Classic</em></p>  <p>Under Windows Classic, IIS is in charge of authentication. And IIS says that if a request doesn’t include an Authorization header, it is challenging for credentials based on the configuration of the site. Therefore, you’ll see a lot more 401’s under Windows Classic. Now, a 401 is expensive. With NTLM authentication, every 401 means that an Active Directory Domain Controller was interrogated to validate the passed credentials. </p>  <p>When you’ve got a web application that is configured for Windows Claims only, and Windows Claims is the only authentication type specified for that web application, you execute a very unique code path within the authentication system. If you run a Fiddler trace you’ll notice that after the initial 401, a cookie, WSS_KeepSessionAuthenticated, is set on the browser. This cookie is an index into a token cache maintained by SharePoint, and is actually a chunk of code left over from SharePoint 2007 that is only invoked when a site is:</p>  <ol>   <li>Configured for Claims Based Authentication </li>    <li>Only configured for <em>Windows Claims</em> (i.e. NTLM or Kerberos authentication) </li> </ol>  <p>Remember that integrated mode module that we talked about before? The one that handles authentication for claims based web applications? When this module sees the WSS_KeepSessionAuthenticated cookie, it checks the state of the cached token that the cookie value points to on the server, and in so doing executes a code path that iterates over all registered claim providers and, as a result, winds up calling FillClaimsForEntity on each one that returns <em>true</em> from SupportsEntityInformation (For more information, see the <a href="https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.claims.spclaimprovider.aspx">SPClaimProvider documentation on MSDN</a>).</p>  <p>We’ll cache the token according to settings specified on the security token services configuration (accessible via PowerShell by calling Get-SPSecurityTokenServiceConfig). As a side benefit, we don’t wind up issuing a 401 on ever page request in this model, significantly reducing authentication overhead and domain controller impact, but we do wind up calling any registered claim providers a lot. <em>Lesson: Optimize your claim providers – slow downs in authentication will equal a slow site</em>.</p>  <p>Now, add a second authentication mechanism, and things suddenly change. Under Windows Claims, if a second authentication method is defined for the URL – say, Forms, or a Trusted Identity Provider – we stop issuing the WSS_KeepSessionAuthenticated cookie, and start issuing a FedAuth cookie instead. The FedAuth cookie is the the cookie we issue when you are using SAML Claims, FBA, or Windows Claims with multiple authentication providers. The details of authentication when a FedAuth cookie is used are significantly different; for instance, we’ll only call registered claim providers when an actual FedAuth cookie is issued, as that’s the time authentication really occurs; we’ll only re-execute registered claim providers when the cookie expires and an authentication is forced again.</p>  <p>All this talk of Windows Authentication and cookies might have some folks wondering – cookies can be a real pain, I went with Windows Authentication to avoid cookies and the pain they bring. Remember the death by a thousand cuts that was the integration&#160; of Office 2007 and SharePoint FBA applications under SharePoint 2007 before Service Pack 2 (and a litany of other conditions)?</p>  <p>Using cookies to streamline the authentication process is actually okay with Windows Authentication, because the browser first authenticated with Windows Auth, and will respond seamlessly if it receives a 401 down the road. The fact that it’s not getting 401’s mean faster browsing for you, less chatter between the server and the domain controller infrastructure (in the case of NTLM authentication), etc. Should a 401 be issued, the client will know just what to do.</p>  <p>Remember earlier, when my colleague tried telling me that my custom claims provider will have its FillClaimsForEntity called on every authentication? Turns out, he was right – every time I authenticate, even if the authentication process is short circuited (ala WSS_KeepSessionAuthenticated and Windows Claims), my custom claims provider will be invoked. Sometimes, though, I authenticate a lot less than I thought I would!</p>  <p>I hope this helps those folks that are trying to understand the complexities behind custom claims providers and the logic behind their invocation. </p>]]></content:encoded>
    </item>
    <item>
      <title>Configuring Failover Databases - and Removing That Configuration</title>
      <link>https://docs.microsoft.com/archive/blogs/brporter/configuring-failover-databases-and-removing-that-configuration</link>
      <pubDate>Fri, 26 Nov 2010 20:49:00 GMT</pubDate>
      <dc:creator><![CDATA[Bryan L. Porter]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brporter/2010/11/26/configuring-failover-databases-and-removing-that-configuration/</guid>
      <description><![CDATA[SharePoint 2010 supports database mirroring for just about every database you can think of (there...]]></description>
      <content:encoded><![CDATA[<p>SharePoint 2010 supports database mirroring for just about every database you can think of (there are some exceptions - the Synchronization database of the User Profile service, for instance). This allows SharePoint to make use of the Failover Partner attribute within the connection to specify the failover server to the underlying data access stack, making use of a failover database seamless. We just use the plumbing the data access (ADO.NET for the most part, and the components of its stack) provides, and get to take advantage of Other Peoples Code that just Does The Right Thing.</p>  <p>Once you've created a database, though, going back and adding a failover partner can only be done via PowerShell - the Central Administration UI is disabled for this purpose. This is easy enough to do:</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:1d7b0f2e-b345-4e5b-a58b-496cbe3346df" class="wlWriterEditableSmartContent"><pre style=" width: 653px; height: 92px;background-color:White;overflow: auto;"><div><!--

code highlighting produced by Actipro CodeHighlighter (freeware)
https://www.CodeHighlighter.com/

--><span style="color: #008080;">1</span> <span style="color: #008000;">#</span><span style="color: #008000;"> Set failover database server</span><span style="color: #008000;">
</span><span style="color: #008080;">2</span> <span style="color: #008000;"></span><span style="color: #800080;">$database</span><span style="color: #000000;"> </span><span style="color: #000000;">=</span><span style="color: #000000;"> Get</span><span style="color: #000000;">-</span><span style="color: #000000;">SPDatabase </span><span style="color: #000000;">|</span><span style="color: #000000;"> where { </span><span style="color: #800080;">$_</span><span style="color: #000000;">.Name </span><span style="color: #008080;">-eq</span><span style="color: #000000;"> </span><span style="color: #800000;">&quot;</span><span style="color: #800000;">SomeSharePointDB</span><span style="color: #800000;">&quot;</span><span style="color: #000000;"> }
</span><span style="color: #008080;">3</span> <span style="color: #000000;"></span><span style="color: #800080;">$database</span><span style="color: #000000;">.AddFailoverServiceInstance(</span><span style="color: #800000;">&quot;</span><span style="color: #800000;">FailoverSQLServerName\OptionalInstanceIfUsed</span><span style="color: #800000;">&quot;</span><span style="color: #000000;">)
</span><span style="color: #008080;">4</span> <span style="color: #000000;"></span><span style="color: #800080;">$database</span><span style="color: #000000;">.Update();</span></!--

code></div></pre><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  https://dunnhq.com --></!--></div>

<p>What's less obvious is what you need to do when you want to turn things off. For instance, when you are adjusting your mirroring configuration and need to replace (or even remove altogether) the failover partner for a time. If you are just changing the name/instance of the failover partner, you can just re-run the script above to adjust the failover partner server name. If, on the other hand, you are removing the failover partner entirely, you'll need to execute the above script but specify either the PowerShell special variable $null as the failover partner server name, or an empty string - either will work. In so doing, you'll remove the failover server configuration for that database, and SharePoint will adjust the connection string it uses when connecting to that database, removing the Failover Partner attribute.</p>]]></content:encoded>
    </item>
    <item>
      <title>Trusted Identity Providers &amp; User Profile Synchronization</title>
      <link>https://docs.microsoft.com/archive/blogs/brporter/trusted-identity-providers-user-profile-synchronization</link>
      <pubDate>Mon, 19 Jul 2010 18:41:59 GMT</pubDate>
      <dc:creator><![CDATA[Bryan L. Porter]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brporter/2010/07/19/trusted-identity-providers-user-profile-synchronization/</guid>
      <description><![CDATA[Recently, a few people have been trying to figure out how to get user profile synchronization...]]></description>
      <content:encoded><![CDATA[<p>Recently, a few people have been trying to figure out how to get user profile synchronization working when doing claims authentication via a trusted identity provider, as is the case in many federation scenarios involving ADFS, for instance. I've heard of people writing one-off jobs that iterate over their profile store updating the <em>Account Name</em> attribute to gets things to match up properly; luckily this isn't required, as SharePoint profile sychronization already has support for doing this for you during profile imports. It just take a wee bit of configuration to get working.</p>
<p>It's not obvious, but there are some hints in the user interface regarding how to make this kind of configuration work. Namely, when configuring a directory synchronization connection, you can specify the type of authentication provider that'll be used to access the imported profiles, and in the case of a trusted claims provider, you can even select the specific trusted provider configured in the farm.</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/04/83/3465.connection_details.gif" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-04-83/3465.connection_5F00_details.gif" border="0" /></p>
<p>Unfortunately, if you stopped here - and most people do - you'll be dissapointed to fine that while your profile imports succeeds just fine, when you log in as a user via the trusted claims provider you specified your login won't be associated to its corresponding profile in the user profile store. What gives?</p>
<p>Well, it turns out that in order to give the user profile system enough information to map your imported profiles to incoming authetnicated users, you have to tell it what imported attribute is going to correspond to the authenticated users identity claim. Remember, when you configured your trusted identity provider, you specified a claim as the identity claim - this claim is immutable, you can't change it once you've configured the trusted identity provider. In order to map users properly, you have to tell the user profile system which of the innumerable attributes it may be importing is going to be used as the identity claim. Once you give the profile system that information, it'll have enough information to calculate what the identity claim of the profile will be when someone logs in for it.</p>
<p>So, what property do we need to map? Well, obviously enough, it's the Claim User Identifier property.</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/04/83/7282.idclaim_mapping.gif" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-04-83/7282.idclaim_5F00_mapping.gif" border="0" /></p>
<p>In the screenshot above, you'll notice that I've got my property mapped to the <em>mail</em> incoming attribute. This is just the claim I chose to use in my setup - you can use whatever you'd like, but remember it'll need to be the attribute that's being presented as the identity claim from the trusted identity provider. </p>
<p>Once this is in place, firing off a user profile import will result in your users suddenly getting associated to the correct profile. Yay!</p>
<p>Hope this helps anyone out there who's been struggling with getting this working!</p>]]></content:encoded>
    </item>
    <item>
      <title>Multiple Authentication Providers in SharePoint 2010, Part II</title>
      <link>https://docs.microsoft.com/archive/blogs/brporter/multiple-authentication-providers-in-sharepoint-2010-part-ii</link>
      <pubDate>Wed, 23 Jun 2010 09:10:59 GMT</pubDate>
      <dc:creator><![CDATA[Bryan L. Porter]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brporter/2010/06/23/multiple-authentication-providers-in-sharepoint-2010-part-ii/</guid>
      <description><![CDATA[The folks over at Orbit One Internet Solutions took my blog posting regarding automatic selection of...]]></description>
      <content:encoded><![CDATA[<p>The folks over at <a href="https://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/Orbit One Internet Solutions" title="https://www.orbitone.com/">Orbit One Internet Solutions</a> took my <a href="https://blogs.msdn.com/b/brporter/archive/2010/05/10/temp.aspx">blog posting regarding automatic selection of authentication providers</a> in SharePoint 2010 and really ran with it. They've posted what looks to be a fine solution adding and extending all the things that I pointed out would be needed in order to turn my original sample into a full solution - read all about it over at the <a href="https://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/OrbitOne Blog" title="https://www.orbitone.com/en/blog/archive/2010/06/23/sharepoint-2010-mixed-authentication-automatic-login.aspx">OrbitOne Blog</a> (<a href="https://www.orbitone.com/en/blog/archive/2010/06/23/sharepoint-2010-mixed-authentication-automatic-login.aspx">https://www.orbitone.com/en/blog/archive/2010/06/23/sharepoint-2010-mixed-authentication-automatic-login.aspx</a>).</p>
<p>Great job, guys!</p>]]></content:encoded>
    </item>
    <item>
      <title>User Profiles &amp; Service Application Associations</title>
      <link>https://docs.microsoft.com/archive/blogs/brporter/user-profiles-service-application-associations</link>
      <pubDate>Thu, 17 Jun 2010 09:11:00 GMT</pubDate>
      <dc:creator><![CDATA[Bryan L. Porter]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brporter/2010/06/17/user-profiles-service-application-associations/</guid>
      <description><![CDATA[I ran into a completely understandable, but rather funny error condition today and thought I'd write...]]></description>
      <content:encoded><![CDATA[<p><span class="ms-error" style="padding-left: 5px;">I ran into a completely understandable, but rather funny error condition today and thought I'd write up a quick note in case anyone else out there bumps against this, too.</span></p>
<p><span class="ms-error" style="padding-left: 5px;">In&nbsp;SharePoint 2010, service applications sometimes have dependencies on <em>other</em> service applications. Take User Profiles for instance. While in 2007, the SSP managing user profiles also handled multi-value profile properties, in 2010, things are different; User Profiles store multi-valued properties as tags within an instance of the Managed Metadata service. While playing around on one of my test farms, I stumbled upon a weird error condition that took me a minute to diagnose and fix.</span></p>
<p><span class="ms-error" style="padding-left: 5px;"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/04/83/7585.profileeditorerror.GIF" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-04-83/7585.profileeditorerror.GIF" border="0" /></span></p>
<p>If you do even a cursory search for the error <em>"There was a problem retrieving data for this field. Updating values in this field is disabled temporarily. You can still update values in other fields."</em>, you'll find a variety of postings that'll tell you that you forgot to provision a Managed Metadata service application. Imagine my surprise, then, when I pulled up my list of service applications for this farm:</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/04/83/8424.serviceapps.GIF" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-04-83/8424.serviceapps.GIF" border="0" /></p>
<p>As you can see in the image above, there is my User Profiles application, and there is my Managed Metadata application. I'm not partitioned, or consuming from a services farm, so this is all pretty straighforward. </p>
<p>All applications - service applications, Web applicatoins, etc. - are associated with other service applications that they may consume by way of <em>proxy group</em>. While you get to configure explicit proxy associations when you are provisioning a web application, service applications don't give you that option - they are always associated by default to the default proxy group. </p>
<p>Navigating to Application Management -&gt; Configure Service Application Associations and choosing the Service Application view revealed my problem.</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/04/83/5224.appassociations.gif" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-04-83/5224.appassociations.gif" border="0" /></p>
<p>&nbsp;The default proxy group didn't contain my Managed Metadata proxy - which meant that even though it was provisioned, my User Profile service application couldn't make use of it! I can fix this two ways - I can customize the service application associations for the User Profile service application, or I can&nbsp;just click on the <em>default </em>proxy group link from the Configure Service Application Associations page and add my Managed Metadata proxy to that proxy group...</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/04/83/5415.defaultsa.GIF" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-04-83/5415.defaultsa.GIF" border="0" /></p>
<p>Press <em>OK</em> on that dialog and a quick check of my My Sites profile edit page shows that all is well. </p>
<p>&nbsp;</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Why Is Central Administration Broken?</title>
      <link>https://docs.microsoft.com/archive/blogs/brporter/why-is-central-administration-broken</link>
      <pubDate>Fri, 11 Jun 2010 13:52:00 GMT</pubDate>
      <dc:creator><![CDATA[Bryan L. Porter]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/brporter/2010/06/11/why-is-central-administration-broken/</guid>
      <description><![CDATA[Answer: It's not. You just followed our guidance, and we probably should've told you a few...]]></description>
      <content:encoded><![CDATA[<p><strong>Answer:</strong> It's not. You just followed our guidance, and we probably should've told you a few additional things.</p>
<p>We frequently give people the advice that they should run Central Administration on more than a single machine in the SharePoint farm. The thought goes that, if something really bad were to happen and you lost the machine in your farm that runs Central Administration, if you've got a second machine, you can use that instance of Central Administration while you work out the problems on the first machine. I believe there are even&nbsp;rules in the <a href="https://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/best practices analyzer">best practices analyzer</a> we ship that will warn you if it detects that you aren't running multiple copies of Central Administration.</p>
<p>The problem with this guidance is that it neglects two fundamental truths about humans:</p>
<ol>
<li>We're lazy, by nature. If you tell us to do X&nbsp;and Y, don't just assume that we'll also do Z.&nbsp;You may have expected us to realize that we needed to, but we are lazy. If you'd like us to do Z, you should tell us so.</li>
<li>We're forgetful in stressful situations. If you tell me a phone number I can remember it. If you tell me a phone number while I'm in the middle of taking a test, I'm going to have a hard time remembering it; my brain is doing other things (like bathing in adrenaline, amongst other chemicals).</li>
</ol>
<p>The first instance of Central Administration that is installed can be thought of as the default instance. The URL of this instance becomes the public URL for all subsequent installations of Central Administration. When you add Central Administration to a second server, you are not only configuring that server to serve the Central Administration web site, you are also configuring an additional internal URL in the Alternate Access Mappings (AAM) for the Central Administration site - but the public URL remains the same, no matter how many instance of the Central Administration web site you configure. Take the following scenario:</p>
<ul>
<li>I install Central Administation on APP1 on port 1234; this is the first server in my farm.</li>
<li>I install Central Administration on APP2; this is the second server in my farm.</li>
</ul>
<p>In this scenario, you'll notice three things: </p>
<ol>
<li>If, on APP2, you click the link in the Start Menu for Central Administration, that you are taken directly to https://APP1:1234, not the local instance of Central Administration (https://APP2:1234)</li>
<li>If you try and navigate to https://APP2:1234 you are immediately redirected to https://APP1:1234/default.aspx.</li>
<li>If you try and navigate to https://APP2:1234/default.aspx, you stay put - for a little while. Eventually, you click something and find yourself whisked away to https://APP1:1234/ again.</li>
</ol>
<p>To understand what's going on, you have to first understand a little bit about something called Alternate Access Mappings, or AAM. AAM was a feature introduced in SharePoint 2003 SP1, and further refined in SharePoint 2007, that allows SharePoint to accept requests on one URL, but reply with another. This was intended to support scenarios like SSL offloading, where you terminate the (computationally expensive) SSL connection between the clients browser and the server at a proxy or load balancer, freeing the web front ends CPU to focus on serving requests and not decrypting HTTP traffic. When this happens, SharePoint receives the request with an https:// URL, but when it responds, needs to make sure it responds with an https:// URL anywhere that SharePoint would send a full URL (and not a relative one, like an &lt;img&gt; tag). This happens in lots of places, in view state data, in a few places where we dynamically generate JavaScript, etc. And it also happens when you request the root page of a SharePoint web application and we send you a 302 redirect to the correct page.</p>
<p>Which would explain why, in item #2 above, when you type in https://APP2:1234, you are immediately sent elsewhere. SharePoint received a request, looked at the AAM table to determine what URL to send back, and sent back a 302 redirect with a Location header of https://APP1:1234/default.aspx. https://APP1:1234 is the Public URL of the only zone configured for the Central Administration site.</p>
<p>What about item #1 and item #3? Well, for Item #1, the link to Central Administration in the Start Menu is actually a link to run the local instance of PSConfigUI, with a flag that says, "Open Internet Explorer and navigate to the Central Administration site". PSConfigUI determines the URL of the Central Administration by looking at a registry key - a value that is not updated once set on a server. It's the value of the Public URL of the default zone of the AAM settings for Central Administration, as it was set at the time that that server joined the farm. You can find this registry key (for SharePoint 2010) at HKLM\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0\WSS\CentralAdministrationURL. You can change the Public URL in the AAM table for Central Administration all day long, and this key will never get updated. You have to update it by hand.</p>
<p>As for Item #3, you postponed the inevitable - namely, SharePoint didn't have to send you a 302 redirect, and therefore didn't have to calculate the full URL using the Public URL of the zone your request was mapped to, in order to satisfy the request.&nbsp; Now, eventually you'll take some action in which SharePoint will either instruct your browser to request the configured Public URL or you'll get an outright 302 for any of a myriad of&nbsp;reasons, at which point you'll be whisked off to the original URL.</p>
<p>There. That's the behavior. Whew. What were we talking about again? Oh, yeah - the guidance that you should run multiple instances of Central Administration in your farm.</p>
<p>So, based on all the above material (hereinafter referred to as <em>background</em>), you may be wondering just what good a second instance of Central Administration is really going to do you. Well, the bad news is that unless you document a few things, not a whole lot. This takes me back to my second fundamental truth of humans - that we don't operate as effectively in stressful situations as in non-stressful situations. Think of it - it's 2:00AM, and you've just been paged because one of the servers in your corporate SharePoint farm just decided to go visit it's mother in Toledo. It's shot, gone, <em>sind gebrochen</em>. Whatever. You jump on a different box, go to pull up Central Administration, and *bam* get an error because that box is directing you to a URL on a server that is busted - which is the whole reason you're up at 2:00AM anyway. So you think, "I've got CA loaded on APP2, I'll just jump on that", and you crack open Internet Explorer and type in (frantically) https://app2:1234/.</p>
<p>And you get another error message - the same error message you got by following the Central Administration link. You look at the URL - it shows https://app2:1234 - and you start panicking. <em>Both </em>boxes are down? How can that be?</p>
<p>You then devolve into a puddle of troubleshooting mush as you start flailing around, your sleep and caffeine deprived brain struggling to come to grips with the imagined enormity of the outage you begin to believe you are looking at. </p>
<p>Now, this behavior is perfectly reasonable given what we now know about Central Administration and AAM. Specifically, the first link broke because we have a dead server; that one should be obvious. But why the second failure? The second failed because SharePoint sent us a 302 redirect, and it used the public URL of the Default AAM zone (the only zone configured for Central Administration) to do it - and unfortunately, that means we got a 302 redirect that sent Internet Explorer off looking for the dead server again. Since the 302 redirect failed, though, Internet Explorer didn't change the address in the&nbsp; browser bar. While at first blush it would seem that it should have, an argument could be made - one that I'd come down in support of - that&nbsp;Internet Explorer shouldn't reflect a redirected URL when it hasn't actually redirected you anywhere. The fact that this is a case in which the predictability of browser behavior&nbsp;tends to cause more confusion that it reduces is another matter entirely.</p>
<p>So, when you find yourself in this pickle, what to do? Well, it's simple really. The command line always works. For SharePoint 2007, you can manipulate the Public URL for the default AAM zone to reflect the address of the second server; for SharePoint 2010, you can use PowerShell. To do this in 2010, you'd type something similar to:</p>
<p>New-SPAlternateURL -WebApplication &lt;old CA URL&gt; -Url &lt;new CA URL&gt; -Zone Default</p>
<p>Taking our example above, this would result in a command that looks like:</p>
<p>New-SPAlternateURL -WebApplication https://app1:1234 -Url https://app2:1234 -Zone Default</p>
<p>We do actually have this procedure documented in the article <a href="https://technet.microsoft.com/en-us/library/cc288510.aspx#Section3">Rename a stand-alone server</a>. While the cause in the articles scenarios and the one with which we've concerned ourselves today are entirely dissimilar, the symptom and remedy are not.</p>
<p>It's also an entirely unsupported fact that, even when the Public URL is configured for a URL that would be different for&nbsp;your second&nbsp;Central Administration hosting&nbsp;server, it just so happens that Central Administration does work well enough and long enough to manipulate AAM entries into something proper, all through the UI. Just note that you'll need to explicitly specify <em>default.aspx</em> - as in https://app2:1234/default.aspx - in your request, otherwise you'll be redirected by the calculated 302 redirect.</p>
<p>And lastly, I'll leave you with this thought: Central Administration is just another web application, albeit a slightly special one due to the manner with which it is provisioned. But ultimately, it operates in a fashion not entirely dissimilar to other SharePoint web applications. Given that you have control over the AAM url configured for the Central Administration web site, there really is nothing stopping someone from load balancing Central Administration. As crazy as it sounds, you could edit the default public and internal URL to be <a href="https://centraladministration.contoso.com">https://centraladministration.contoso.com</a>, and configure a load balancer to balance requests at that URL across a few different boxes. It would (and does) work fine. But that'd be just <em>crazy</em>?</p>
<p>Wouldn't it?</p>
<p><span style="background-color: #ffff00;"><strong>[Update: For the sake of completeness, no it's not crazy, and in fact my friend Spence has written up a quite lengthy and most splendid article describing how to do just that. Read all about it at <a href="https://www.harbar.net/articles/spca.aspx">https://www.harbar.net/articles/spca.aspx</a>!]</strong></span></p>]]></content:encoded>
    </item>
  </channel>
</rss>