Once again, I am reminded of how much I can appreciate the PowerShell snap-ins for SharePoint after the 2010 release. Attempting to iterate through a farm or script out actions using only STSADM commands and direct access to the SharePoint assemblies ([System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.SharePoint”)) is much more challenging than using the built-in PowerShell capabilities of the later versions (even SharePoint Online with it’s own quirks).
I have a client who is migrating from an on-premise SharePoint 2007 environment to SharePoint Online. Yes – big jump, and yes – there will be some headaches. So many features and functions of SharePoint 2007 simply will not migrate and/or be mappable to equivalent SharePoint Online features due to the sheer difference in the way each of the platforms are laid out. Due to this, identifying some of these issues proactively before a migration rather than reacting to broken page layouts, missing site feature dependencies, and other prerequisites is greatly beneficial. To make matters a step more complicated, the client had elected to engage in a branding effort to give their SharePoint Online instance a fresh new look that resulted in a site that really didn’t look like SharePoint at all in the end.
So how do you migrate a bunch of SharePoint 2007 ASPX pages, based on deprecated site templates and layouts, into a branded SharePoint Online instance which utilizes a specific page layout for branding and the site home pages?
Lucky this client didn’t have very customized site home pages or a large extent of customized pages throughout their farm, so efforts to re-create these pages into branded SPO pages manually was feasible. In order to prepare for this work and delegate out this ASPX page recreation to site owners, the client wanted to have an inventory of all ASPX pages in their farm currently, with location. Per my normal consulting habits, I was confident in telling the client we could figure out a way to give them this report to help them plan this work out, yet I was not 100% sure how I would do it at that time. Now was time to search for how to get a SharePoint 2007 file inventory, and then strip out everything besides the ASPX pages from the list.
Through some research online, it was easy to find all arrows pointing to Gary LaPointe. The SharePoint MVP is THE man when it comes to STSADM commands. His website has WSP solutions for installing snap-ins with SharePoint 2010+ PowerShell commands, as well as some scripts here. Lucky for me, he had one script on his website which iterated through every web application in the local farm, and drilled down through each Site Collection, subsite, and document library recursively and output the results to either a grid view or a CSV file. View the script below, as well as a link to Gary’s personal blog which I would highly recommend to any SharePoint consultant or legacy farm administrator
This document will be used to outline the process for implementing Azure’s ACS namespace as a trusted identity provider to an on-premise SharePoint environment, utilizing external identity providers such as Facebook, Yahoo, or Windows Live ID to pass manipulated claims as a standardized trusted token to SharePoint
Preface, Considerations, Prerequisites
Azure ACS authentication with SharePoint is a free service as of 12/2014. The service requires a subscription to Azure, but costs no money. A $0 spending limit can be set to prevent the possibility of any charges coming through from this account.
The Azure ACS system can utilize any Identity Provider that can export an OpenID claim
SharePoint 2013 does not support SAML 2.0, SAML 1.1 must be used
As of 12/2014, Windows Live ID can only export a nameidentifier claim, but this can be mapped to an email address claim to use as a UPN for login
An x.509 SSL certificate needs to be uploaded to Azure to sign tokens, and to explicitly trust in SharePoint
Azure ACS – ACS (access control system) is a free feature of Azure that allows the developer to create a namespace that can tie external Identity Providers incoming tokens to a single claim to a web application Azure Namespace – the item in Azure that provides the URL for all Identity Providers, Relying Party Applications, Rule Group Settings, and Certificates and Keys to be trusted Identity Provider – an external service, such as Yahoo!, Facebook, or Windows Live ID, that provides the inherently trusted authentication to SharePoint Relying Party Application – these are the web applications that are connected to the namespace that receive the token that is output from the Azure ACS namespace. In this walkthrough, SharePoint 2013 is our Relying Party Application Rule Groups – Rule groups are the list of incoming claims tied to claim issuers/identity providers, how they may be mapped when exported, as well as any customizations that need to happen for the token itself
Creating the Namespace
Login to the Azure management portal at https://manage.windowsazure.com with the Azure account created prior to this work. Note: Ensure that this account has a subscription set up prior to continuing any further, any work created with a trial account will expire once the trial is over, and are unable to be transferred to a setup account
Once logged into the management console, click the large NEW button at the bottom left of the screen to begin the process of creating a namespace
Navigate App Services > Active Directory > Access Control > Quick Create:
Give the namespace a name that makes sense for the authentication set up (this won’t be an actively used URL by an end-user). Select your region, and the subscription that has been set up (Pay-As-You-Go, or another valid subscription, NOT free trial). The namespace status will change from creating to active:
Click on the newly created namespace, and click the manage button on the bottom ribbon, this will take you to the Silverlight based Windows Azure Platform Access Control Service control panel:
Utilize the Getting Started steps that appear on the homepage of this control panel for much of the work. You will now want to set up the Identity Providers:
Making Windows Live ID Work for SharePoint 2013 Authentication
Since the Windows Live ID Identity Provider is a preset default in the Azure ACS namespace, I will use it as a full example on configuring the claim issuer for authentication in SharePoint, and will later lead into how to configure additional Identity Providers.
Configure Relying Party Applications
Navigate to the Relying party applications management by clicking the URL on the left-hand side of the ACS administrative panel
Click the Add URL at the top left of the Relying Party Applications table
On the configuration page, enter in the following information: Name: a display name such as “SharePoint2013” is fine for this as it is simply a display name for SharePoint’s trust with ACS Realm: the realm will be equal the resolvable url for your SharePoint web application (https://winchestertonfieldville.ia.gov/) would work fine if this is your SharePoint web application URL Return URL: this is the URL in which ACS will return tokens to SharePoint. This will always be the same URL as the realm defined above, with “/_trust” appended to the end (https://winchestertonfieldville.ia.gov/_trust) Error URL (optional): This is the URL for an optional error page in case authentication fails Token Format: Choose SAML 1.1, SharePoint 2013 is NOT compatible with SAML 2.0 Token lifetime (secs): This value represents the seconds that the token is valid before expiring, or how long the user will be able to hit the realm URL repeat times and be auto-authenticated back in to the environment. The default value of 600 seconds is typically on the low side. Set this value to 3600 seconds (equal to the default value in ADFS). Identity Providers: the list of Identity Providers that you would like to have as optional authentication methods when users hit the realm’s login page. Each Identity Provider will show in the login drop down Rule Groups: leave the check box to create a new rule group as we will be doing this in the next step Token Signing: Choose whether to Use service namespace certificate or Use a dedicated certificate. For the purposes of this walk through, I would recommend choosing Use a dedicated server and upload the X.509 certificate .pxf file to use for when signing. Browse to the file, upload, and input the password that was created when it was exported from the server.
Configure Rule Groups
The rule groups are the configuration for what claims Azure will receive from the Identity Providers, as well as how they will map these claims to the output token.
Navigate to the Rule Groups page by clicking the URL on the left-hand navigation
Click the “Default Rule Group for <RelyingPartyApplication>” that was automatically created when we set up the Relying Party Application
On the Edit Rule Group page, feel free to edit the name for the rule group
In the Rules table, click the Generate URL. You will notice that the Rules table currently shows “No rules have been added. Click Generate to generate rules automatically, or click Add to add rules manually.” Note – If additional Identity Providers are added at a later time, use this option to generate new rules for the new identity providers
On the following page, click the checkbox next to Windows Live ID, and click Generate
You will then see the that the nameidentifier output claim from Windows Live ID is listed as a rule. Click on the nameidentifier URL.
On the resulting page, you can see how to configure the input/ouput of this claim for how ACS will prep it for the output token that will be trusted by SharePoint. By default, nameidentifier is not a usable claim for a login in SharePoint. To address this, we will map the output claim type to email address.
For everything under the If section, leave default
For the “Then” section, change the select type dropdown from http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier to http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress to map the claim from the nameidentifier URI to a usable email address login
You can leave all other items as default, or add information under “Rule Information” that will explain that we are mapping the Windows Live ID nameidentifier claim to an emailaddress output claim
Upload Token Signing Certificate
Azure ACS uses an X.509 certificate to digitally sign the tokens it generates. You can also increase the functionality of this certificate to include encryption/decryption of the tokens themselves. Many users will use the makecert utility to create a self-signed certificate for testing purposes, but do not do this in a production environment.
Click the Certificates and Keys URL on the lefthand side of the Azure ACS configuration page
Click the Add URL at the top of the Token Signing table
On the “Add Token-Signing Certificate or Key” page, select the correct Relying Party Application in the dropdown.
Select X.509 Certificate for type
Click Choose file and upload the .pfx file. Note: On this page, it also shows how to use the MakeCert utility from the Microsoft SDK to make this certificate.
SharePoint 2013 Configuration
Within SharePoint, we will move forward in this walkthrough with the assumption that the Web Application within SharePoint 2013 has already been created with a friendly URL assigned to it.
Log in to the Central Admin server
Open a PowerShell ISE session as an administrator and run the following:
#Add snapin to allow SharePoint PowerShell comamnds
#set the realm to equal the URL for the SharePoint web application. This must match the realm value used when creating the relying party application within Azure ACS
#replace <namespace> with the name of the ACS namespace created previously, select http or https depending on your SharePoint WebApp URL, replace <realm> with the URL for the SharePoint web application. This establishes a trust between SharePoint and the Azure ACS token signing certificate. This can be viewed further within Central Administration under Security > Manage Trusts. Ensure that this signin page resolves
# Set variables for the location of the certificate and create the trusted root authority. This should be the same X.509 cert used as with the token signing cert used when creating the Relying Party application within Azure
#Create New Trusted Identity Provider in SharePoint 2013 to recognize the passed on claims within the trusted token
New-SPTrustedIdentityTokenIssuer-Name"ACS"-Description"ACS Id Token Issuer"-Realm$realm-ImportTrustCertificate$cert-ClaimsMappings$map1,$map2,$map3-SignInUrl$signinurl-IdentifierClaim$map1.InputClaimType
I would recommend running the above code line by line to ensure you can identify any errors as they happen, rather than an error that you can’t attribute to a single line of code when bulk running the block
Open Central Administration and click Manage Web Applications
Click the web application that we have been using thus far, and click Authentication Providers in the ribbon.
In the appropriate zone, you should be able to see empty check boxes for the newly created Trusted Identity Providers that we have set up. Check the boxes next to Windows Live ID
SharePoint now knows to trust any SAML1.1 tokens that come from the specific Azure ACS namespace that we have created, and knows how to parse the claims within the token.
You are now complete! You now should be able to hit the SharePoint Web Application URL, be redirected to an Azure ACS hosted login page, be able to choose between windows authentication or Windows Live ID, be redirected to the Windows Live ID login page to authenticate, and automatically be pushed back to SharePoint. As of our current configuration performed thus far, the users will hit a “You are not authorized to view this page” SharePoint page. For security, I would recommend enabling Access Request settings for the root Site Collection, and setting the recipient to a HA individual, or a distribution group to be able to triage requests from possible users as they hit your environment.
Throughout the SharePoint migrations I have performed, a common ask by a client for their new environment is typically some branding. Extensive branding which includes JS and CSS markups on a page typically require an extended amount of work and effort, but deploying a simple logo and color scheme to a Web Application is a pretty straightforward process, especially with PowerShell.
To deploy a logo, first get your logo prepared for deployment. Ideally, a SharePoint site logo is no more than 60px vertically. Now that the logo is ready, you’ll need to place it in a location that can be accessed globally by all Site Collections. What I prefer to do, at least in a single Web Front End deployment, is to throw the PNG in the 15 hive for the installation directory. You can find this at C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\TEMPLATE\LAYOUTS\<Branding> where <Branding> is a newly created folder that contains specific style objects like this. In a multi-WFE farm, put this logo in this location on all WFEs.
Now to deploy the logo, use the below PowerShell script:
# Jordan Hladish
# Function: Enumerate through a WebApplication and set the logo for all Site Collections and subsites
# For singe WFE farms: Place logo in 15 hive (e.g. C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\TEMPLATE\LAYOUTS\Branding)
# Reference above location with /_layouts/15/Branding/imagename.png
# If multiple WFE exist, put logo in 15 hive on each server
The above will get the Web Application specified by $WebApp, list out all Site Collections, and then with each, will enumerate through all subsites and set the logo attribute for each site to the specific image file.
Below is an error one may receive when attempting to run SharePoint PowerShell cmdlets through the SharePoint Shell Admin:
“The local farm is not accessible. Cmdlets with FeatureDependencyID are not registered.”
Get-SPContentDatabase : The farm is unavailable.
At line:1 char:1
+ CategoryInfo : InvalidData: (Microsoft.Share...ContentDatabase:
SPCmdletGetContentDatabase) [Get-SPContentDatabase], SPException
+ FullyQualifiedErrorId : Microsoft.SharePoint.PowerShell.SPCmdletGetConte
This error can occur when the user running the commands doesn’t have the proper permissions to the correct back end content databases. The SecurityAdmin roles is necessary to run Shell commands. To resolve this error, either grant the account running the command sharepoint_shell_access and db_owner at minimum to the configuration database in SQL, or login with the SP_Admin account and run with elevated permissions.
If you already have the account granted the above permissions in SQL, you can run the following in a PowerShell console:
Add-SPShellAdmin -UserName DOMAIN\User
When working on a Sharepoint 2007 to 2013 migration, I had a need to identify SharePoint feature GUIDs in the 2007 farm to identify whether or not these items would be able to migrate to the new farm without issue. I had an application that provided documentation on each of the farms and identified all Site Collection features that were activated, but would output the resulting data with a list of these GUIDs rather than feature names.
Many features that come with SharePoint have GUIDs that you can reference by doing a quick google search for SharePoint Feature GUIDs. But for those custom features, I needed a way to pair these GUIDs with the feature names.
What to do?
When on the Site Collection you’re examining, go to Site Settings under the gear icon at the top right or Site Actions depending on what version of SharePoint you’re using:
Navigate to Site Collection Features on the Site Settings page.
You will then be given a page with a list of features activated, or available to activate, on that Site Collection. To find a specific feature’s GUID, click deactivate. Note: This will NOT deactivate the feature yet, you will be prompted with a confirmation screen before the feature is actually deactivated.
The next page will be the feature deactivation confirmation screen. We are not going to deactivate any features. The trick is that when you look at the URL on the resulting screen, it will contain the feature GUID with a FeatureID=<FeatureGUID> section in the URL: