Host Header Site Collections and SSL

Something I ran into just the other day; say you have a bunch of Host Header Site Collections running in a non-SSL webapp, and someone comes along and asks you to enable SSL on these site collection, as well as keeping non-SSL access functioning (I know, I thought it was a weird request as well).

Here’s the steps I had to go through to get this working:

1. Generate a Subject Alternate Name certificate that contains the DNS names of each of the HHSC you wish to enable SSL on. Install that cert through IIS Admin on each server.

2. Extend your non-SSL webapp to support SSL using the following PowerShell command:

Get-SPWebApplication <WebappURLToExtend> | New-SPWebApplicationExtension -Name "<NewSSLWebAppName>" -Zone "Extranet" -HostHeader "<OriginalWebappName>" -Path "<NewPathforIISFiles>" -Port "443" -url "https://<WebappName>:443" -SecureSocketsLayer

3. Once that is complete, launch IIS Admin on each SharePoint server and edit the binding for the extended webapp, and add the certificate to the extended webapp binding.

4. While in IIS Admin, go ahead and add a https binding to the extended webapp for each HHSC you need SSL access to.

5. On each SharePoint server, copy the web.config file from the non-SSL folder to the new SSL folder (this will ensure that any customizations you made to the webapp will be available in the SSL webapp).

6. Finally, you need to tell SharePoint that the SSL HHSC URLs need to be in the Extranet Zone (where you created the extended webapp). Execute this command for each HHSC you want to access via SSL:

Set-SPSiteUrl (Get-SPSite "http://<HHSCURL>") -Url "https://<HHSCURL>" -Zone Extranet

And that’s about it, your HHSC URLs will be available on port 80 and port 443.

(Now would be a great time for you to contact your load-balancer guys and remind them you have the physical load balancers start listening on port 443 as well as port 80).

Broken SP1 Language Packs

Many months ago, we battled an issue in RTM SharePoint 2013 where if you installed any additional language packs, and went to Central Admin, and tried to change the ULS Logging Levels for Search, the options would be presented to you in the last language pack you installed. Neat…well, kinda, unless the last language pack you installed was Thai, and you can’t read Thai.

We opened a case and went through the Support Mazes until we finally convinced someone at Microsoft that this was a bad thing, and not “working as designed” (oh those conversations were epic).

To our amazement, they fixed the issue in the October 2013 CU. Nice, done and done.

Now we install the SP1 patches for the language packs (after installing SP1), and guess what? You guessed!, the issue is back. So if you’ve installed SP1, and installed SP1 for any additional language packs you have, bop into Central Admin, click on Monitoring, then Configure Diagnostic Logging, the open up Search. Enjoy.

A side note, in our farms the last language pack we installed was German, and I’m not sure what “Fuzzynamenssuche” is, bit it’s hilarious…

I’ll post back when we make it through the support maze and figure out when/if this will be fixed…again.

SharePoint 2013 AD Connector Import Property Issues

If you’re like me, and you need to import a large number of users and groups into SharePoint, you were ecstatic with the release of SharePoint 2013 and the AD Connector. No more issues with FIM, no crazy start-up issues, no Sync DB issues, finally I get to take a vacation and not worry.

Or so I thought…after testing the AD Connector, it would appear that both the Manager and Assistant property are skipped during a Full Sync. After a week or so of testing, I gave up and called Microsoft for help, and looking at the issue, and reproducing it there, they have explained that this is a bug in the AD Connector. Great. It only happens on a Full Sync, or if a new user is added to AD and imported to the Profile DB. Incrementals do not remove the property data.

So, if you’re using the AD Connector (and you should be), and you’re not seeing Manager or Assistant being populated, fear not, you are not crazy (or maybe you are, it’s not my place to judge).

Is there a fix? Maybe (involves some nutty work with a sproc, jabber jabber jabber). Is there a workaround? Of course.

I wrote this script to run as a scheduled task after the profile sync is complete. It will parse through your profiles, and for each profile where Manager or Assistant are blank, will make a look-up in AD to see if there is supposed to be something there, and add it to the Profile.

If you want to use the script, feel free (At least PowerShell 3.0 please, I’m using the Active Directory snapins, and it kinda expects you to be running it from the E:\Scripts folder, so change up the log file location if needed):

# Description of Function:  This script will compare each profile and determine if the manager and assistant property
#				is missing by checking Active Directory.  If the manager or assistant propery is missing, 
#				but is valid in AD, the profile will be updated with the correct Manager and Assistant.
#				This corrects a known issue in the SharePoint 2013 AD Connector Profile Import
# Version History:  1.0
# Input parameters (if any)
# Creates a function to dispose of all variables that are disposable

function Dispose-All {
	Get-Variable -exclude Runspace | Where-Object {$_.Value -is [System.IDisposable]} | 
		Foreach-Object {$_.Value.Dispose()}
Import-Module Activedirectory

# Load up the SharePoint cmdlets if they are missing
if (!(Get-PsSnapin | Where-Object {$_.Name -match "Microsoft.SharePoint.PowerShell"}))
{Add-PsSnapin Microsoft.SharePoint.PowerShell}

$outputFile = "E:\Scripts\FixNullProperties.txt"
if (test-path $outputFile) {Remove-Item $outputFile -force}

# Grab the Central Admin webapp and connect to the Profile System
$url = Get-SPWebApplication -IncludeCentralAdministration | where {$_.IsAdministrationWebApplication}
$site = Get-SPSite $url.url
$context = Get-SPServiceContext $site
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$AllProfiles = $ProfileManager.GetEnumerator()

foreach($profile in $AllProfiles){
	Set-Variable profileCommit,adAccount,adManagerAccount,adassistantAccount,Manager,Account,distinguishedName,Assistant -value $null
	$Manager = $profile['Manager'].Value
	$Account = $profile[[Microsoft.Office.Server.UserProfiles.PropertyConstants]::AccountName].Value
	$distinguishedName = $profile['SPS-DistinguishedName'].Value
	$Assistant = $profile['Assistant'].Value

		If((!$Manager) -OR (!$Assistant)){
		$adAccount = (get-aduser -Filter 'distinguishedName -eq $distinguishedName' -Properties Manager,Assistant -ErrorAction SilentlyContinue)
		If($adAccount.Manager -AND (!$Manager)){
			$adManagerAccount = (get-aduser -Filter 'distinguishedName -eq $adAccount.Manager' -ErrorAction SilentlyContinue)
			$adManagerID = ($adManagerAccount | select -expand UserPrincipalName).Split("@")
			$MgrhomeDomain = $adManagerID[1].Split(".")[0]
			$finalMgrData = $MgrhomeDomain + "\" + $adManagerID[0]
			$profile['Manager'].Value = $finalMgrData
			If($MgrhomeDomain){$profileCommit = "1"}
			Add-Content $outputFile "Added Manager $finalMgrData to Profile $Account"
		If($adAccount.Assistant -AND (!$Assistant)){
			$adAssistantAccount = (get-aduser -Filter 'distinguishedName -eq $adAccount.Assistant' -ErrorAction SilentlyContinue)
			$adAssistantID = ($adAssistantAccount | select -expand UserPrincipalName).Split("@")
			$assistantHomeDomain = $adAssistantID[1].Split(".")[0]
			$finalAssistantData = $assistantHomeDomain + "\" + $adAssistantID[0]
			$profile['Assistant'].Value = $finalAssistantData
			If($assistantHomeDomain){$profileCommit = "1"}
			Add-Content $outputFile "Added Assistant $finalAssistantData to Profile $Account"

SP1 Re-released

Microsoft has fixed the ugliness in the original SP1 patch for SharePoint 2013 and Office Web Apps 2013. I’m sure it’s fine now, download it, install and PSConfig the heck out of your farms.

I’ll be at the Summit the week of April, 28th. Making fun of the guys talking about PowerShell and SharePoint is my life.

SharePoint 2013 SP1 Yanked!

Microsoft has found a bug in SP1 for SharePoint 2013 and has pulled it from the download site. For those of you like me that went ahead and installed it, they are working on a KB to correct the issue. It’s nothing major, just a small issue where you will never be able to patch your farm again…ever.

If you’re just about to click on the exe to start the SP1 install, I would go ahead and put the mouse down, and slowly back away from the keyboard.

Pulling a SP is new. Makes me wonder how they addressed this in O365…

Official Download Site:

Distributed Cache Services – And Why Not To Ignore It

When I first heard about the Distributed Cache Service in SharePoint 2013, I wasn’t paying as much attention as I should have, and my brain filtered all of the “Now, you want to think about this beast” talk I was hearing. Well, now I’m revisiting the DCS and realizing that if you’re going to build a multi-server farm, you should probably put some effort into how you’re going to make DCS work.

Initially, my brain heard “The DCS caches authentication information so you no longer need to set persistence on your VIPs.” This is correct, it does, but it also plays a massive role in the Social aspects of SP2013.

Fair warning, no whining about “Oh I broke DCS when I patched”, or “Why doesn’t my NewsFeed app update correctly”. You break it, you buy it…

When is a BDC not a BDC?

After standing up my SharePoint 2013 farm, I thought “Awesome!, time to try connecting some of the 2013 Service Apps to my 2010 Farm”. It’s fully supported, right? I spun up the trust between the farms, and began connecting the 2013 Service Apps to my 2010 farm. After each one was connected, I dropped the 2010 Service App.

Everything seemed to be working, but then an issue with the BDC surfaced. It appears that you cannot create a new BDC model, or edit an existing one, if your content is still on 2010. I asked Microsoft about this, seems to be a “Working as designed” kind of thing. You can consume existing BDC models from the 2010 farm, just not change or create new ones in Designer. So, like me, if you brought your 2010 BDC database over and used it to create the 2013 BDC Service App, it’ll work, but no editing.

So, if you’re out there trying this like I did, and the BDC isn’t working, you’re not crazy (well, you might be crazy, but not about the BDC). No word if this will be fixed, or even if Microsoft believes it’s broken. Guess you’ll have to keep that 2010 BDC service around until you migrate your content to 2013.

(And please, let’s not have the BCS vs BDC argument…)

UPDATE: Microsoft may or may not have confirmed that this is working as designed. I have been told that the new 2013 BDC uses oAuth to communicate while created External Content Types. Guess they didn’t think of 2010 farms consuming the 2013 BDC. Soooo, it won’t work.

Testing Webapps On Each SharePoint Server

I love single line PowerShell commands. Scripts can be boring, but it you can condense everything down to a single line, you sir, rock.

If you’re running a multi-server farm and using a load-balancer to handle getting the web requests to a Front End servers, you’ll sometimes (always) really like to know if the webapps are responding correctly on each server. If you’re like me, you place self-referencing host file entries on each server for each Web Application. No sense in having the servers send WFE request back to the load-balancer. And, magically, that’s a pre-requisite for this PowerShell command running. Without the host file entries on each server, the web requests will just go to the load-balancer, and you’ll never figure out who’s working and who’s not.

Log on to each of your SharePoint servers and fire up the handy-dandy SharePoint Management Console. Once you’re there, fire off this command:

Clear-Host;Get-SPWebApplication | Select -expand URL | %{$wa= $_;$request = [System.Net.WebRequest]::Create($_);$request.Timeout = 30000;$request.UseDefaultCredentials = $true;Try{$webcall = ($request.GetResponse());Write-Host "Site:$($webcall.ResponseUri) -- StatusCode $($webcall.StatusCode)";Write-Host "`r"} Catch [system.exception] {Write-Host "$wa Failed -- $($error[0].Exception.Message)";Write-Host "`r"}}

This will pull each URL from SharePoint and spin up a web request and show you the feedback.

Note: You may need to adjust the timeout variable in the web request if your app pools have spun down and they need longer than 30 seconds to come back up.

Hope it helps!

AD Connector Reports in SharePoint 2013

Once you start using the AD Connector in SharePoint 2013 (What?! Not use FIM? Are you Mad?!), you’ll probably want to know how the imports are running. So you drop into Central Admin, open up the User Profile Service and click on…. Nothing. That’s right, there’s no feedback in Central Admin on the status of the last Profile Sync run when using the AD Connector.

What’s an Admin to do? (Like you didn’t see this coming)
Spin up the SharePoint 2013 Management Console on the server where the Profile Service is running and fire off these commands.

Let’s say your import ran in the last 24 hours, and you’d like to know how many accounts were updated successfully, run this on the server where the Profile Service is running.
Since the message in ULS for a successful update looks like this:

User profile record of “domain\account” was changed by “profile service account”

This will get you all of those in the last 24 hours:

$dt = (get-date).addDays(-1)
get-splogevent -StartTime $dt| ?{$_.Category -eq "User Profiles" -AND $_.Message -like "User profile record of*"} | measure-Object

This will show you the running Import job (if there is one):

$upa = Get-SPServiceApplication | ?{$_.TypeName -eq "User Profile Service Application"}
$upa.service | select -expand RunningJobs

If you’d like to see all of the history for each timer job associated with the User Profile Service:

$upa = Get-SPServiceApplication | ?{$_.TypeName -eq "User Profile Service Application"}
$upa.service.JobHistoryEntries | fl

If you want to see just errors, do something like this:

$upa.service.JobHistoryEntries | ?{$_.Status -eq "Failed"} | select StartTime,ErrorMessage

And if you (for some odd reason) want to see all of the timer jobs associated with the User Profile Server, you can always do this:


The cool thing to do would be to set this up as a scheduled task and write the contents to a SharePoint list to make this much easier to review. Yeah yeah, I’ll get to that. Or you can do it… right?