Nik Patel's SharePoint World

An adventure in SharePoint and Microsoft in general.

Archive for December, 2011

Prescriptive Guidance – InfoPath List Forms Implementation Lifecycle for SharePoint 2010

Posted by nikspatel on December 23, 2011

Have you ever wondered how to use InfoPath List Forms for the SharePoint 2010 and what really happens behind the screen? Have you ever wondered how would you retract customized SharePoint List form and cleanup the form completely from your SharePoint systems? Have you ever wished you had end to end guidance to design, deploy, and maintain InfoPath List forms for the SharePoint 2010? To me, these are the real questions asked by SharePoint/InfoPath developers while designing forms in the real world scenarios. With this article, hopefully you have a reference material which will provide all these answers.

Ever since I have presented “Real Word InfoPath 2010 List vs. Library Forms”, I had promised attendees that I will write detailed blog articles on real world best practices to design, develop, and maintain InfoPath 2010 List and Library forms with SharePoint 2010. Although everyone likes benefits of quick rapid forms design and development using InfoPath 2010 for SharePoint 2010, I have seen more often or not they would get frustrated quickly. In most cases, their frustration is not because of the InfoPath product itself, but because of the developer or development process itself. It is important to remember that InfoPath 2010 development with SharePoint 2010 requires discipline and it must follow specific pattern or guidelines. Based on my experience, one of the biggest things we are lacking in SharePoint 2010 is prescriptive guidance on how to use any feature from end to end in real world scenarios. This article would try to fill the gap between most of the books written on InfoPath 2010 with SharePoint 2010 and real world scenarios.

Although late is better than never, here is the blog article on Prescriptive Guidance for InfoPath List Forms Implementation Lifecycle. Please note that this article discusses InfoPath List Forms, not Library Forms. If you want to read the differences between List and Library Forms and when to use which one, please read this article. Additionally, please note that this is not detailed step by step guide to demonstrate end to end example using lots of screenshots. It will take reader to typical real-world situations during InfoPath forms lifecycle in SharePoint 2010 – Prepare the Environment, Design the InfoPath 2010 Form, Deploy InfoPath 2010 forms to SharePoint 2010, Upgrade/Maintain InfoPath 2010 forms to SharePoint 2010, and Retract/Cleanup InfoPath 2010 forms to SharePoint 2010.

Here is prescriptive guidance on how to create and maintain sample “Project Request Form” by walking through end of end example and what really happens behind the screen.

Step 1 => Prepare the SharePoint and InfoPath Environment

First step of the SharePoint and InfoPath 2010 development is to make sure you have all the tools installed for InfoPath form design and all the SharePoint services configured. Follow this step to ensure your environment is prepared for the SharePoint and InfoPath development.

  • Prepare SharePoint 2010 Environment
    • Have SharePoint Server Enterprise CAL Installed. Browser based InfoPath Forms available in SharePoint Enterprise CAL as InfoPath Form Services.
    • InfoPath Form Services enabled on SharePoint 2010 Enterprise by default. You can Configure InfoPath Form Services Settings on the Central Administration -> General Application Settings -> InfoPath Forms Services -> Configure InfoPath Form Services -> Enable/Disable User Browser Enabled Form Templates
  • Prepare Development Environment
    • Install InfoPath 2010 using Office Professional Plus 2010 – InfoPath Designer 2010 and InfoPath Filler 2010

Step 2 => Design the InfoPath List Forms and SharePoint Application

This step will create sample SharePoint List (e.g. Projects) to host InfoPath List Form (e.g. Project Requests Form) and customize the form using InfoPath Form Designer 2010.

  • Create the Custom List (Projects List) to hold the Project Requests
    • Add List Columns. In real world, I like to standardize the lists or library metadata with Site Content Type.  For this example, create list columns directly on the list.
      • Basic Info
        • Fiscal Year – 2011-2015 – Required – Choice
        • Project Name – Required (Rename Title Column)
        • Project Description – Single Line of Text
        • Department – IT, HR, Finance, Legal, Sales, Marketing, Other – Required – Choice
        • Project Requester – Required – Person & Group
        • Project Sponsor – Single Line of Text
        • Project Priority – High, Medium, Low – Choice
        • Project Type – New Implementation, Modifications, Enhancements, Replacement – Choice
      • Business Case
        • Problem Statements – Multiple lines of Text – Rich Text Field
        • Project Mission (including Project Scope) – Multiple lines of Text – Rich Text Field
        • Project Benefits – Multiple lines of Text – Rich Text Field
        • Business Dependencies – Multiple lines of Text – Rich Text Field
        • IT Dependencies – Multiple lines of Text – Rich Text Field
    • Configure Advanced List Properties as needed
      • Enable the Versioning (Version Settings)
      • If you have created content types for Project Request Item, Enable the Content Type (Advance Settings) and Add Projects Content Type and Delete the Default Item Content Type
      • Configure Default View – Remove unnecessary column

    • In the Out of box SharePoint Lists, If you add new item without customizing the forms, item view form would look like this as Standard UI.

    • Behind the screen – What really happens?
      • Three out of box List Form Web Parts available on the List Ribbon UI.

        

      • You can open the site collection in SharePoint Designer and navigate to the All Files -> Lists -> <List Name> -> <Content Type (e.g. Item)> folder. Folder should be empty and there won’t be any custom InfoPath templates and forms.

  •  Customize the InfoPath Lists Forms
    • Use “Customize Form” from the Projects List Ribbon bar and it should open the InfoPath 2010 Designer to customize the Lists Forms.

    • Projects Request InfoPath Form will be automatically configured in the InfoPath Form Designer
      • InfoPath Form Fields are linked to the Underlying SharePoint List
      • InfoPath Form Publishing Location is already configured as Underlying SharePoint List
    • Design Projects Request Data Entry InfoPath Form
      • Configure Views (UI and Branding), Rules, and Data Sources.
      • Configure Forms Options – Toolbar options, default display view
    • Review Data Connections – Main Data Connection would be configure to retrieve and submit data to the underlying SharePoint List. You can notice from the following screenshot, publishing location is already configured to underlying List URL.

Step 3 => Deploy InfoPath List Forms

  • Publish the InfoPath Forms to the SharePoint List
    • Publish the Form using Quick Publish from InfoPath Designer.

    • Behind the screen – What really happens?
      • As you soon as you publish the form first time, Newly publish form will be deployed to the Site Collection Content Database along with the List contents.
      • Three additional Form Web Parts Customization Menu Items will be added to the List Ribbon UI.

      • You can open the site collection in SharePoint Designer and navigate to the All Files -> Lists -> <List Name> -> <Content Type (e.g. Item)> folder. Folder should contain InfoPath template (template.xsn) and three additional default Edit, Add, and Display forms (newifs.aspx, editifs.aspx, and displayifs.aspx). All your forms and form template gets stored in the content database.

      • Three new Edit, Add, and Display forms contains the newly introduced web part in SharePoint 2010 “InfoPath web part” and configured by adding InfoPath Form Template with  default
        • Display Form Markup – location – list infopath from, content type id, list form mode – Readonly
          •  <WpNs0:BrowserFormWebPart runat=”server” AllowEdit=”True” AllowConnect=”True” SubmitBehavior=”FormDefault” ConnectionID=”00000000-0000-0000-0000-000000000000″ Title=”InfoPath Form Web Part” IsIncluded=”True” Dir=”Default” ExportMode=”All” IsVisible=”True” ShowFormRibbon=”True” AllowMinimize=”True” ExportControlledProperties=”True” ZoneID=”Main” ID=”g_64f73c52_bc1c_4f65_9e84_eae4ce99e904″ FormLocation=”~list/Project Request/template.xsn” FrameState=”Normal” SendDataOnPostback=”True” AllowHide=”True” SuppressWebPartChrome=”False” DetailLink=”" ChromeType=”None” HelpLink=”" MissingAssembly=”Cannot import this Web Part.” PartImageSmall=”" AllowRemove=”True” ListFormMode=”ReadOnly” ContentTypeId=”0x010094C0C4EE6041654B87BF74AF58C0253000AACADF5B2CC621429FBDD7D807134CF8″ HelpMode=”Modeless” FrameType=”None” AllowZoneChange=”True” PartOrder=”2″ Description=”Use this Web Part to display an InfoPath browser-enabled form.” PartImageLarge=”" IsIncludedFilter=”" __MarkupType=”vsattributemarkup” __WebPartId=”{64F73C52-BC1C-4F65-9E84-EAE4CE99E904}” WebPart=”true” Height=”" Width=”"></WpNs0:BrowserFormWebPart>
        • Edit Form  Markup – location – list infopath from, content type id, list form mode – Editable
          • <WpNs0:BrowserFormWebPart runat=”server” AllowEdit=”True” AllowConnect=”True” SubmitBehavior=”FormDefault” ConnectionID=”00000000-0000-0000-0000-000000000000″ Title=”InfoPath Form Web Part” IsIncluded=”True” Dir=”Default” ExportMode=”All” IsVisible=”True” ShowFormRibbon=”True” AllowMinimize=”True” ExportControlledProperties=”True” ZoneID=”Main” ID=”g_0bda7a45_0e6c_4e4e_b861_1492d88ce90c” FormLocation=”~list/Project Request/template.xsn” FrameState=”Normal” SendDataOnPostback=”True” AllowHide=”True” SuppressWebPartChrome=”False” DetailLink=”" ChromeType=”None” HelpLink=”" MissingAssembly=”Cannot import this Web Part.” PartImageSmall=”" AllowRemove=”True” ListFormMode=”Editable” ContentTypeId=”0x010094C0C4EE6041654B87BF74AF58C0253000AACADF5B2CC621429FBDD7D807134CF8″ HelpMode=”Modeless” FrameType=”None” AllowZoneChange=”True” PartOrder=”2″ Description=”Use this Web Part to display an InfoPath browser-enabled form.” PartImageLarge=”" IsIncludedFilter=”" __MarkupType=”vsattributemarkup” __WebPartId=”{0BDA7A45-0E6C-4E4E-B861-1492D88CE90C}” WebPart=”true” Height=”" Width=”"></WpNs0:BrowserFormWebPart>
        • New Form Markup – location – list infopath from, content type id, list form mode – Editable
          • <WpNs0:BrowserFormWebPart runat=”server” AllowEdit=”True” AllowConnect=”True” SubmitBehavior=”FormDefault” ConnectionID=”00000000-0000-0000-0000-000000000000″ Title=”InfoPath Form Web Part” IsIncluded=”True” Dir=”Default” ExportMode=”All” IsVisible=”True” ShowFormRibbon=”True” AllowMinimize=”True” ExportControlledProperties=”True” ZoneID=”Main” ID=”g_29a83ffc_f17a_47ff_8812_ad34639e713f” FormLocation=”~list/Project Request/template.xsn” FrameState=”Normal” SendDataOnPostback=”True” AllowHide=”True” SuppressWebPartChrome=”False” DetailLink=”" ChromeType=”None” HelpLink=”" MissingAssembly=”Cannot import this Web Part.” PartImageSmall=”" AllowRemove=”True” ListFormMode=”Editable” ContentTypeId=”0x010094C0C4EE6041654B87BF74AF58C0253000AACADF5B2CC621429FBDD7D807134CF8″ HelpMode=”Modeless” FrameType=”None” AllowZoneChange=”True” PartOrder=”2″ Description=”Use this Web Part to display an InfoPath browser-enabled form.” PartImageLarge=”" IsIncludedFilter=”" __MarkupType=”vsattributemarkup” __WebPartId=”{29A83FFC-F17A-47FF-8812-AD34639E713F}” WebPart=”true” Height=”" Width=”"></WpNs0:BrowserFormWebPart>

    • Best Practices – Do not customize the InfoPath Form Web Part properties on the Add, Edit, and Display InfoPath forms from the SharePoint Designer. Instead customize web part propreties from the browser UI. Form the List Ribbon, customize the form web parts from the content types section.
    • With the Customized InfoPath List Form, SharePoint List item view form would look like this.

 Step 4 => Upgrade InfoPath List Forms

  • Modify/Enhance/Upgrade the InfoPath List Form
    • Any list schema changes requires updating the InfoPath form. Any major schema changes in the SharePoint List would make associated InfoPath Form Invalid. Use “Customize Form” from the Projects List Ribbon bar.
    • Update/Redesign the List Form and republish it to sync the List changes to the InfoPath Form Schema

Step 5 => Retract InfoPath List Forms

  • Clean up the InfoPath List Form
    • From List Settings -> Form Options, you have option to revert back to the out of the box ASP.NET forms and option to permanently delete the associated list form or preserve the InfoPath forms

Hopefully this will be helpful designing your next InfoPath List Form for SharePoint 2010.

Posted in SP2010 & InfoPath | Leave a Comment »

InfoPath 2010 and SharePoint 2010 – List Forms vs Library Forms

Posted by nikspatel on December 23, 2011

Not many aware of two different kinds of InfoPath forms available in SharePoint 2010 – List Forms and Library Forms. Having understanding of both kind of InfoPath forms is one of the most fundamental knowledge one need to have to be better InfoPath Developer for SharePoint 2010. Since you can’t switch from List forms to library forms or vice-a-versa (Yes, you read it right, you can’t switch or migrate forms from one to another), deciding on List vs Library form becomes one of the most fundamental architectural decisions part of InfoPath-SharePoint solution.

This article highlights high level differences between SharePoint 2010 List and Library forms and guidance on when to use which kind of forms. Microsoft has published wonderful article on this topic and my article is extension of what’s been published on InfoPath blog with some additional notes I have taking over the last two years.

InfoPath Team Blog Referencehttp://blogs.msdn.com/b/infopath/archive/2010/04/22/comparing-list-and-form-library-forms.aspx

 List Forms – Tied to the List – New in SharePoint 2010

  • Key Characteristics
    • InfoPath Form Tied to specific SharePoint list, Not reusable
    • InfoPath Form Schema tied to SharePoint List Schema
    • InfoPath Form data stored in the SharePoint List.
    • Each control (e.g. text box) in the InfoPath Form is bound to a column in the SharePoint List.
    • Supported on Simple SharePoint Lists like Custom List, Tasks, Announcements, Links, Contacts from Browser Interface
    • Not supported in Document Libraries and advanced SharePoint Lists like Calendar
    • You can customize or edit the published form template by clicking the “Customize Form” on the List Ribbon Bar
    • Requires SharePoint Designer to customize the External Lists Forms
  • Limitations
    • Tied to only 1 list and data stored directly in list
    • No Custom Code Support
    • No Digital Signatures
    • Because it’s tied to specific list, No Custom Submit or Publish Behavior
    • No Repeating and Nested Data
    • No Print Support – No Print Button
    • Not available to the Document Library
  • Use cases
    • To customize the out of the box List New Form, List Edit Form, and List Display Forms
    • Ideal for Prototypes or quickly get started building InfoPath forms on SharePoint
    • Ideal for No-code solutions using SharePoint Designer and Browser Customization for Pre-Packaged Departmental SharePoint Sites designed on production farm.
    • To use forms offline with SharePoint Workspace
  • Important Note => Do not use List InfoPath Forms in formal code management and deployment scenarios from development to staging to production.

Library Forms – Tied to the form libraries – Same as SharePoint 2007

  • Key Characteristics
    • Form data stored as the XML document in SharePoint Form Library
    • More complex and requires more disciplined/structured approach
    • Can be deployed as Sandbox or Farm Level Solutions
    • Unlike list forms, Form library forms can be deployed as a template to associate the forms to multiple form libraries across multiple sites or site collections or multiple web applications within farm
  • Publishing Mechanism
    • Single Library
      • Deploy/Publish to specific form library
      • Not reusable in another library
      • Only one form template per form library, Same benefits as list InfoPath forms. If Form is directly published to form library, another form can’t be published or used in the form library.
    • Reusability across Site Collection – Multiple libraries or sites within Site Collection
      • Deploy/Publish as a Form Content Type and Later use Content Type in the Form Library
      • Enables deployment to multiple document libraries
      • Supports multiple content type per library. It means,  multiple types of Form Templates can be tied to the Form Library using multiple Form Content Types
    • Reusability across Farm – Multiple Site Collections or Web Applications
      • Deploy/Publish as a Administrator Approved Form Templates
      • Once deployed and activated on the site collection, Administrator-Approved Form Templates behaves same as Content Type Form
      • Deploy as features and solutions framework, PowerShell, or manual upload
  • Use cases
    • Form Templates with Code
    • Form Templates with Tabular Structure (Nested or Repeated Data) or Complex Schema
    • Form Templates with Printing Support from Ribbon Bar
    • Form Templates with Custom Submit Behavior
    • From Templates needs to be digitally signed
    • Great fit for Enterprise Level Form Solutions with Advanced and Reusable Functionality
    • Admin Approved forms eases future enhancements, upgrade, maintenance, and deployment
    • Fits perfectly in formal deployment process of moving features from development to staging to production.
    • Form is not hosted in SharePoint or you need to store results as an XML document

Posted in SP2010 & InfoPath | Leave a Comment »

Step by Step Guide to Configure SharePoint 2010 Forms Based Authentication with SQL

Posted by nikspatel on December 22, 2011

It is very common to use SQL Server database to store external users and roles in extranet environments for physical separation of the internal and external users. Typically external identity systems require specific schema changes and AD administrators don’t allow applications to store their users in the main organization domain directory for security concerns.

I have recently wrote an article on step by step guide to configure SharePoint 2010 FBA with ADLDS. This article follows same pattern to configure SharePoint FBA with SQL Server. As you may notice, most of the steps are same and web configuration file changes are similar. This article describes 5-Steps guide to configure SQL Users and Roles in Single-Server SharePoint 2010 environment on Windows 2008 R2 server for Forms Based Authentication.

Note: If you are looking for detailed step by step guide with lots of screenshots, you can download 35-pages step by step PDF guide demonstrating same steps discussed in this article.

 Step 1 – Create SQL Server Database to host FBA Accounts

  • Run C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_regsql.exe to create the SQL DB – aspnetdb
  • Verify that Niks\Administrator is running Application Pools for the Content and Central Admin Web Application and it’s added as dbowner role on the aspnetdb database.

Step 2 – Add SQL Users and Roles for FBA

  • Download the MembershipSeeder to load users for form-based authentication – http://cks.codeplex.com/releases/view/7450
  • How to use MembershipSeeder tool?
    • Open the  \Bin\Release\MembershipSeeder.exe and Update the SQL Server Name by clicking “Configure” button and close the tool
    • Reopen the tool and use following guidelines to add users.
      • Add 1 user at a time from membership section using “create” button
      • Add 1 role at a time from roles section using “create” button
      • Add 1 user to the role at a time from roles section using “Add to Role” button

  • Add SQL Roles and Users as following
    • Roles – sqlowners, sqlcontributors, sqlreaders
    • Users – sqlowner, sqlcontributor, sqlreader and add them to specific groups

Step 3 – Create New Web Application with Forms Based Authentication

  • Add DNS entries for the host headers – sqlportal.niks.local
  • Create New Web Application with Claims Based Authentication
    • Specify Port-80 and Host Header – sqlportal.niks.local
    • Select Windows Authentication and Forms Based Authentication
      • Specify Membership Provider – SqlMember and Role Provider – SqlRole
    • Specify proper content database name and leave everything else as it is
    • Create New Site Collection and specify Niks\Administrator as Site Collection Admin
    • Verify the Windows Authentication by logging to http:\\sqlportal.niks.local as Using Niks\Administrator

Step 4 – Update the Web Config Files for FBA – Content Web App, Central Admin Web App, and STS


  <connectionStrings>
     <clear />
     <add name="AspNetSqlMembershipProvider" connectionString="data source=SP2010VM;Integrated Security=SSPI;Initial Catalog=aspnetdb"  providerName="System.Data.SqlClient" />
  </connectionStrings>

    • Replace the  <PeoplePickerWildcards> entry with following XML

  <PeoplePickerWildcards>
   <clear />
   <add key="AspNetSqlMembershipProvider" value="%" />
   <add key="SqlMember" value="%"/>
   <add key="SqlRole" value="%"/>
  </PeoplePickerWildcards>

    • Locate the <membership> entry and Replace everything from <membership> to </membership> with the following XML

   <membership defaultProvider="i">
      <providers>
        <clear />
        <add connectionStringName="AspNetSqlMemberShipProvider"
           enablePasswordRetrieval="false"
           enablePasswordReset="true"
           requiresQuestionAndAnswer="true"
           passwordAttemptWindow="10"
           applicationName="/"
           requiresUniqueEmail="false"
           passwordFormat="Hashed"
           name="SqlMember"
           type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0,
  Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
        <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
     </providers>
    </membership>

    • Locate the <roleManager> entry and Replace everything from <roleManager> to </roleManager> with the following XML

   <roleManager defaultProvider="c" enabled="true" cacheRolesInCookie="false">
      <providers>
          <clear />
           <add connectionStringName="AspNetSqlMemberShipProvider"
              applicationName="/"
              name="SqlRole"
              type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0,
  Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
           <add name="c" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthRoleProvider,
  Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
     </providers>
  </roleManager>

  • Central Admin Web Application 
    • Update Central Admin Web Application web.config file (to find central admin web.config – go to the IIS, select central admin, and click Explore to find contents)
    • Find the </configSections> entry and add following XML directly below it

    <connectionStrings>
         <clear />
         <add name="AspNetSqlMembershipProvider" connectionString="data source=SP2010VM;Integrated Security=SSPI;Initial Catalog=aspnetdb"  providerName="System.Data.SqlClient" />
      </connectionStrings>
    • Replace the  <PeoplePickerWildcards> entry with following XML

<PeoplePickerWildcards>
   <clear />
   <add key="AspNetSqlMembershipProvider" value="%" />
   <add key="SqlMember" value="%"/>
   <add key="SqlRole" value="%"/>
</PeoplePickerWildcards>

    • Find the <system.web> entry and add the following XML directly below it. By default, there should be 1 blank Membership or RoleManager entry. Double check whether the <membership> and <rolemanager> entries only exist ones. Delete any double entries.

  <membership defaultProvider="i">     
    <providers>
        <clear />
        <add connectionStringName="AspNetSqlMembershipProvider"
           enablePasswordRetrieval="false"
           enablePasswordReset="true"
           requiresQuestionAndAnswer="true"
           passwordAttemptWindow="10"
           applicationName="/"
           requiresUniqueEmail="false"
           passwordFormat="Hashed"
           name="SqlMember"
           type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
        <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
   </providers>
 </membership>
      
 <roleManager defaultProvider="AspNetWindowsTokenRoleProvider" enabled="true" cacheRolesInCookie="false">
    <providers>
        <clear />
        <add connectionStringName="AspNetSqlMembershipProvider"
           applicationName="/"
           name="SqlRole"
           type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
        <add applicationName="/"
           name="AspNetWindowsTokenRoleProvider"
           type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </providers>

 </roleManager>

  • Modify STS web.config file 
    • From the IIS, select the SecurityTokenServiceApplication under SharePoint Web Services and click Explore – it should take you to the C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\WebServices\SecurityToken
    • Find the </system.net> entry and add the following XML directly below it

  <connectionStrings>
     <clear />     
     <add name="AspNetSqlMembershipProvider" connectionString="data source=SP2010VM;Integrated Security=SSPI;Initial Catalog=aspnetdb"  providerName="System.Data.SqlClient" />
  </connectionStrings>   
  <system.web>
    <membership defaultProvider="i">
     <providers>
        <clear />
       <add connectionStringName="AspNetSqlMembershipProvider"
          enablePasswordRetrieval="false"
          enablePasswordReset="true"
          requiresQuestionAndAnswer="true"
          passwordAttemptWindow="10"
          applicationName="/"
          requiresUniqueEmail="false"
          passwordFormat="Hashed"
          name="SqlMember"
          type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0,
  Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
     </providers>
   </membership>
  
   <roleManager defaultProvider="c" enabled="true">
     <providers>
     <clear />
        <add connectionStringName="AspNetSqlMembershipProvider"         applicationName="/"
           name="SqlRole"
           type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
        <add name="c" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthRoleProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
     </providers>
   </roleManager>
  </system.web>   

Step 5 – Configure the SharePoint Authorization and Verify the Access for the both AD (Windows) and SQL(Forms Based) Users

  • Verify AD Groups and Users are available to test
    • Sample Global Security Groups – adowners,adcontributors,adreaders
    • Sample Users – adowner,adcontributor,adreader
    • Add AD Groups and SQL Roles as SharePoint Security Groups – Readers, Contributors, and Owners
  • Verify that central admin and content web application people picker finds both AD groups/users and SQL roles/users – Please note that SQL Roles can be searched with the full role name while SQL user names can be searched via wildcard

  • Add AD users and SQL users into SharePoint Security Groups via AD Groups/SQL Roles and verify proper access – read-only, contribute, full control

Following screenshot demonstrate that I was able to successfully login as SQL User – SQLOwner

More Resources

Posted in Admin General | Leave a Comment »

Code Snippet – Programmatically Access Root Site Collection in Multi-Site Collection Heirarchy

Posted by nikspatel on December 21, 2011

It’s fairly common need in multi-site collection environment to access root site collection programmatically from the current sub site collection or sub site. It’s kind of ironic that one of my colleagues asked me same question while working on our multi-site collection environment this week.

To access the root site collection from the sub site or sub site collections in given web application, you have to somehow access the SPWebApplication object. It’s easy to access SPWebApplication object using SPSite object’s WebApplication property. Once you have access to the SPWebApplication object, you can access first site collection from SPWebApplication.Sites collection to get the handle of the root site collection.

From the sub site, use the following line of code to access root site collection and its URL.

string rootSiteCollectionURL = SPContext.Current.Web.Site.WebApplication.Sites[0].Url;

Posted in Code Snippets | Leave a Comment »

Step by Step Guide to Configure SharePoint 2010 Forms Based Authentication with ADLDS

Posted by nikspatel on December 12, 2011

It is very common to use Active Directory Lightweight Directory Services – ADLDS in Windows 2008 environments (ADAM in Windows 2003 environments) to store external users in extranet environments for physical separation of the internal and external users. Typically external identity systems require specific schema changes and AD administrators don’t allow applications to store their users in the main organization domain directory for security concerns.

Recently I was able to successfully configure SharePoint 2010 Claims based authentication for the ADLDS using Forms based authentication. This article describes 5-Steps guide to configure ADLDS in Single-Server SharePoint 2010 environment on Windows 2008 R2 server for Forms Based Authentication in non-SSL environment. You can easily adopt this guide to use in SSL environment.

Note: If you are looking for detailed step by step guide with lots of screenshots, you can download 55-pages step by step PDF guide demonstrating same steps discussed in this article.

Step 1 – Configure ADLDS Environment

 Step 2 – Create New Web Application with Forms Based Authentication

  • Add DNS entries for the host headers (e.g. adldsportal.niks.local)
  • Create New Web Application with Claims Based Authentication
    • Specify Port-80 and Host Header (e.g. adldsportal.niks.local)
    • Select Windows Authentication and Forms Based Authentication
      • Specify Membership Provider – LdapMember and Role Provider – LdapRole
    • Specify proper content database name and leave everything else as it is
    • Create New Site Collection and specify Niks\Administrator as Site Collection Admin
    • Verify the Windows Authentication by logging to http:\\adldsportal.niks.local as Using Niks\Administrator

Step 3 – Grant “Application Pool” accounts READ Permission on ADLDS instance

  • Add Content SharePoint Web Application “Application Pool”, Central Administration Web Application “Application Pool”, and Security Token Service “Application Pool”  accounts READERS Roles on ADLDS instance. This would allow SharePoint to browse ADLDS store in least privileged scenario.
  • In My Sandbox, both ADLDS Administrators and SharePoint Application Pool accounts are same so, there is no need for explicit setting of permissions but in real world least privileged environment, these application pool accounts will be different and must be granted permission on the ADLDS. Failure of granting permissions for STS application Pool account may cause login failure issues. Failure of granting permissions for Web Application Pool accounts may cause people picker failure.

Step 4 – Update the Web Config Files for FBA – Content Web App, Central Admin Web App, and STS

  • Follow Mirjam’s blog, it works – http://sharepointchick.com/archive/2010/05/06/configuring-claims-and-forms-based-authentication-for-use-with-an.aspx
  • Before you make any changes, Please make sure to have a copy of all the original web.config files before making changes.
  • Please note that these web.config entries would work for ADLDS Containers, ADLDS Group Objects, and ADLDS Users Objects. If you are using either OUs, Persons, or other ADLDS objects, please modify the LDAP membership and roles providers entries as needed.
  • Content Web App Configuration
    • Update adldsportal.niks.local web application web.config – C:\inetpub\wwwroot\wss\VirtualDirectories\adldsportal.niks.local80\web.config
    • Replace the  <PeoplePickerWildcards> entry with following XML

      <PeoplePickerWildcards>
        <clear />
        <add key="AspNetSqlMembershipProvider" value="%" />
        <add key="LdapMember" value="*" />
        <add key="LdapRole" value="*" />
      </PeoplePickerWildcards>

  • Locate the <membership> entry and Replace everything from <membership> to </membership> with the following XML

      <membership defaultProvider="i">
        <providers>
          <clear />
          <add name="LdapMember" type="Microsoft.Office.Server.Security.LdapMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" server="SP2010VM.niks.local" port="52983" useSSL="false" userDNAttribute="distinguishedName" userNameAttribute="userPrincipalName" userContainer="CN=WPSCN,O=NIKSADLDS,C=LOCAL" userObjectClass="user" userFilter="(ObjectClass=user)" scope="Subtree" otherRequiredUserAttributes="cn" />
          <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        </providers>
      </membership>

  • Locate the <roleManager> entry and Replace everything from <roleManager> to </roleManager> with the following XML

      <roleManager defaultProvider="c" enabled="true" cacheRolesInCookie="false">
        <providers>
          <clear />
          <add name="LdapRole" type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" server="SP2010VM.niks.local" port="52983" useSSL="false" groupContainer="CN=WPSCN,O=NIKSADLDS,C=LOCAL" groupNameAttribute="cn" groupMemberAttribute="member" dnAttribute="distinguishedName" userNameAttribute="userPrincipalName" groupFilter="(ObjectClass=group)" userFilter="(ObjectClass=user)" scope="Subtree" />
          <add name="c" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthRoleProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
        </providers>
      </roleManager>

  • Central Admin Web Application
    • Update Central Admin Web Application web.config file (to find central admin web.config – go to the IIS, select central admin, and click Explore to find contents)
    • Replace the  <PeoplePickerWildcards> entry with following XML

      <PeoplePickerWildcards>
        <clear />
        <add key="AspNetSqlMembershipProvider" value="%" />
        <add key="LdapMember" value="*" />
        <add key="LdapRole" value="*" />
      </PeoplePickerWildcards>

  • Find the <system.web> entry and add the following XML directly below it. By default, there should be 1 blank Membership or RoleManager entry. Double check whether the <membership> and <rolemanager> entries only exist ones. Delete any double entries.

    <membership defaultProvider="i">
      <providers>
        <clear />
        <add name="LdapMember"
   type="Microsoft.Office.Server.Security.LdapMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
   server="SP2010VM.niks.local"
   port="52983"
   useSSL="false"
   userDNAttribute="distinguishedName"
   userNameAttribute="userPrincipalName"
   userContainer="CN=WPSCN,O=NIKSADLDS,C=LOCAL"
   userObjectClass="user"
   userFilter="(ObjectClass=user)"
   scope="Subtree"
   otherRequiredUserAttributes="cn" />
        <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
     </providers>
    </membership>
  
  <roleManager defaultProvider="AspNetWindowsTokenRoleProvider" enabled="true" cacheRolesInCookie="false">
        <providers>
          <clear />
         <add name="LdapRole"
   type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
   server="SP2010VM.niks.local"
   port="52983"
   useSSL="false"
   groupContainer="CN=WPSCN,O=NIKSADLDS,C=LOCAL"
   groupNameAttribute="cn"
   groupMemberAttribute="member"
   dnAttribute="distinguishedName"
   userNameAttribute="userPrincipalName"
   groupFilter="(ObjectClass=group)"
   userFilter="(ObjectClass=user)"
   scope="Subtree" />
        <add applicationName="/"
           name="AspNetWindowsTokenRoleProvider"
           type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
       </providers>
  </roleManager>

  • Modify STS web.config file
    • From the IIS, select the SecurityTokenServiceApplication under SharePoint Web Services and click Explore – it should take you to the C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\WebServices\SecurityToken
    • Find the </system.net> entry and add the following XML directly below it

<system.web> 
   <membership defaultProvider="i">
      <providers>
         <clear />
         <add name="LdapMember"
    type="Microsoft.Office.Server.Security.LdapMembershipProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
    server="SP2010VM.niks.local"
    port="52983"
    useSSL="false"
    userDNAttribute="distinguishedName"
    userNameAttribute="userPrincipalName"
    userContainer="CN=WPSCN,O=NIKSADLDS,C=LOCAL"
    userObjectClass="user"
    userFilter="(ObjectClass=user)"
    scope="Subtree"
    otherRequiredUserAttributes="cn" />
       <add name="i" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthMembershipProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
      </providers>
   </membership>
   
   <roleManager defaultProvider="c" enabled="true">
      <providers>
    <clear />
    <add name="LdapRole"
     type="Microsoft.Office.Server.Security.LdapRoleProvider, Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
     server="SP2010VM.niks.local"
     port="52983"
     useSSL="false"
     groupContainer="CN=WPSCN,O=NIKSADLDS,C=LOCAL"
     groupNameAttribute="cn"
     groupMemberAttribute="member"
     dnAttribute="distinguishedName"
     userNameAttribute="userPrincipalName"
     groupFilter="(ObjectClass=group)"
     userFilter="(ObjectClass=user)"
     scope="Subtree" />
         <add name="c" type="Microsoft.SharePoint.Administration.Claims.SPClaimsAuthRoleProvider, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
      </providers>
   </roleManager>
</system.web>

Step 5 – Configure the SharePoint Authorization and Verify the Access for the both AD (Windows) and ADLDS (Forms Based) Users

  • Verify ADLDS Users and Groups are available to test
    • Sample Roles – adldsowners, adldscontributors,adldsreaders
    • Sample Users – adldsowner,adldscontributor,adldsreader and add them to specific groups
  • Verify AD Groups and Users are available to test
    • Sample Global Security Groups – adowners,adcontributors,adreaders
    • Sample Users – adowner,adcontributor,adreader
  • Verify that central admin people picker finds for both AD groups/users and ADLDS roles/users – Please note that ADLDS roles can be searched with the full role name while ADLDS user names can be searched via wildcard
  • Configure AD Groups/Users and ADLDS Roles/Users Membership to the SharePoint Security Groups – Readers, Contributors, and Owners
  • Verify that AD users and ADLDS users added in SharePoint Security Groups via AD Groups/ADLDS Roles have proper access – read-only, contribute, full control

Following screenshot demonstrate that I was able to successfully login as ADLDS User – WPSCNAdminUser

More Resources

Posted in Admin General | Leave a Comment »

What really happens during SharePoint 2010 Solution Deployment/Retraction and Feature Activation/Deactivation Process?

Posted by nikspatel on December 5, 2011

Have you ever wondered what really happens when you deploy/retract SharePoint WSPs and Activate/Deactivate site collection or sub site level features at the farm level? As you execute different PowerShell commands or activate/deactivate features from browser interface, SharePoint 2010 makes several changes at the different places on the servers and databases.

This article provides high level overview of what really happens when you execute different farm level PowerShell commands. Hopefully it will be helpful. 

  Central Admin Site/Web Level Features GAC Web.Config 14-Root Features SharePoint Config DB, Objects Table – Solutions SharePoint Config DB, Objects Table – Features Web App Content DB, Features Table
Add-SPSolution Solution Added but Not Deployed N/A N/A N/A N/A Yes – Solution Definition Added N/A N/A
Install-SPSolution Deployed to Web App Installed Feature Yes – DLLs Added Yes – Safe Control Entries Added Yes – Features Added Yes – Solution Definition Still Exists Yes – Feature Definition Added N/A
Enable-SPFeature Solution Still Deployed Activated feature to Site/Web Yes – Still Exists Yes – Still Exists Yes – Still Exists Yes – Solution Definition Still Exists Yes – Feature Definition Still Exists YES – Feature Activation Link Added
Disable-SPFeature Solution Still Deployed Deactivated feature from Site/Web Yes – Still Exists Yes – Still Exists Yes – Still Exists Yes – Solution Definition Still Exists Yes – Feature Definition Still Exists NO – Feature Activation Link Deleted
UnInstall-SPFeature Solution Still Deployed Uninstalled feature Yes – Still Exists Yes – Still Exists Yes – Still Exists Yes – Solution Definition Still Exists No – Feature Definition Deleted N/A
UnInstall-SPSolution Retracted from Web App Uninstalled feature No – DLLs Deleted No – Safe Control Entries Deleted No – Features Deleted Yes – Solution Definition Still Exists No – Feature Definition Deleted N/A
Remove-SPSolution Solution Deleted N/A N/A N/A N/A Yes – Solution Definition Deleted N/A N/A
 
 
 

Posted in Dev General, Dev PowerShell | Leave a Comment »

Code Snippet – Programmatically Create Web Application Managed Paths in SharePoint 2010

Posted by nikspatel on December 5, 2011

While creating site collections, it is fairly common to create site collections at the more user friendly URLs. By default, each web application has two managed paths – Explicitly named single site collection managed path “(root)” which would allow only 1 site collection at the root path, http://<WebAppURL>/ and Wildcard managed path “sites” to host multiple site collections which would allow users to create multiple site collections at the http://<WebAppURL>/sites/ path.

To automate hundreds or thousands of site collections creation process for a given web application, you can create either explicit or wildcard managed path programmatically. Following code snippets shows two different ways to create managed paths. Both ways shows different ways to access the SPWebApplication application object – using URI or SPSite to create managed path.


using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace CodeSnippets
{
    class Program
    {
        static void Main(string[] args)
        {
            //Retrieve the Input Arguments
            string url = string.Empty;
             if (args.Length > 0)
            {
                Console.WriteLine("Input Web App URL: " + args[0].ToString());
                url = args[0].ToString();
            }
            else
            {
                url = "<a href="http://sp2010vm:1000/">http://sp2010vm:1000</a>";
            }

            //Create Managed Path
            CreateManagedPathUsingWebAppURI(url, "teamsUri", true);
            CreateManagedPathUsingWebAppURI(url, "salesUri", false);
            CreateManagedPathUsingSPSite(url, "teamsSpSite", true);
            CreateManagedPathUsingSPSite(url, "salesSpSite", false);
        }

        ////Method 1 - Create Web App object using URI
        private static void CreateManagedPathUsingWebAppURI(string webAppURL, string NewSiteCollectionName, bool isWildCardInclusion)
        {
            SPWebApplication spWebApp = SPWebApplication.Lookup(new Uri(webAppURL));
            SPPrefixCollection prefixColl = spWebApp.Prefixes;
            if (prefixColl.Contains(NewSiteCollectionName) == false)
            {
                if (isWildCardInclusion)
                {
                    SPPrefix prefix = spWebApp.Prefixes.Add(NewSiteCollectionName, SPPrefixType.WildcardInclusion);
                }
                else
                {
                    SPPrefix prefix = spWebApp.Prefixes.Add(NewSiteCollectionName, SPPrefixType.ExplicitInclusion);
                }
            }
        }

        //Method 2 - Reference Web App Object from SPSite
        private static void CreateManagedPathUsingSPSite(string webAppURL, string NewSiteCollectionName, bool isWildCardInclusion)
        {
            using (SPSite spSite = new SPSite(webAppURL))
            {
                SPWebApplication spWebApp = spSite.WebApplication;
                SPPrefixCollection prefixColl = spWebApp.Prefixes;
                if (prefixColl.Contains(NewSiteCollectionName) == false)
                {
                    if (isWildCardInclusion)
                    {
                        SPPrefix prefix = spWebApp.Prefixes.Add(NewSiteCollectionName, SPPrefixType.WildcardInclusion);
                    }
                    else
                    {
                        SPPrefix prefix = spWebApp.Prefixes.Add(NewSiteCollectionName, SPPrefixType.ExplicitInclusion);
                    }
                    spWebApp.Update(true);
                }
            }
        }
    }
}

Posted in Code Snippets | Leave a Comment »

SharePoint 2010 Recycle Bin Capabilities – Do you know how it really works?

Posted by nikspatel on December 4, 2011

Do you really know how 2-stage SharePoint Recycle bin works? If your answer is yes, please beware and ensure you are aware of what’s in this article. Recently one of my clients asked me question regarding how 2-stage SharePoint Recycle bin works and its impact on the database sizing. It was interesting because recycle bin and its impact on database sizing is one of the most overlooked topic in the SharePoint world. Not many people know that by default, SharePoint 2nd stage recycle bin would increase site collection storage quota to 50% of originally specified during site collection creation process. For the small site collection, it may not matter but for the larger site collections, this would make huge impact on overall architectural decisions.

I had been taking notes on how 2-stage SharePoint recycle bin works since MOSS 2007 days but never blogged about it because of its trivial nature. Knowing how 2-stage recycle bin really works is one of the most important weapons in SharePoint architect armory. Thanks to Todd Klindt and Shane Young’s SharePoint 2010 Administration book, I was able to refine my notes and here are hopefully all the information you need to know how 2-stage SharePoint recycle bin really works and how it can help you to make intelligent decisions around this most overlooked functionality.

First-Stage/Site Level/End-User Recycle Bin

 

  • Accessible from the “Recycle Bin” link on the Quick Launch bar at the top level or sub site level
  • Available to the users with Contribute, Design, or Full Control Permissions
  • When user deletes the item in the list/library, items are moved to the first level recycle bin. It stays there until it remains purged by either the user or automatically deleted after number of days based on central admin recycle bin retention settings.
  • Users can restore the item from the recycle bin or permanently delete the item from the recycle bin
  • If second-stage recycle bin is not enabled, items deleted or automatically purged from this recycle bin will be permanently deleted from the content database.
  • Items located in this stage counts towards the Site Collection Quota.

Second-Stage/Site Collection Level Recycle Bin

  •  Accessible from the Site Collection Administration section from the Site Settings page
  • Available to the users with Site Collection Administrators Role
  • When end-user deletes the items from their site recycle bin, it will be moved to the Site Collection recycle bin. It stays there until site collection administrators flush them or automatically deleted after number of days defined in central admin recycle bin retention settings or until the second stage recycle bin has reached its allocated size limit defined in the central admin second stage quota settings, in which case the oldest items are permanently deleted.
  • Items located in this stage doesn’t count towards the Site Collection Quota. Second-Stage Recycle Bin quota separately defined in the Central Administration per application basis.
  • Site Collection Administrator can manage both recycle bin
    • Rollup View of All First-Level/End-User Recycle Bin – Site Collection Admin can restore one or many items, delete one or many items or empty end-user recycle bin. This is rollup view of all the site level recycle bin at the Site Collection level.

    • Site Collection Second-Stage Recycle Bin – All the items deleted from site level/first-level recycle bin gets moved to the second-stage recycle bin. Site Collection Admin can restore one or many items or permanently delete the items from the 2nd stage recycle bin and content database. Items deleted from this recycle bin is not recoverable.

 

Recycle bin settings are managed at the Web Application Level.

 

  • By default, Recycle bin is ON.
  • You can enable/disable recycle bin at the web application from the Central Admin -> Application Management -> Manage Web Applications -> Select Web Application -> Select General Settings from the Ribbon
    • Disabling Recycle in at the web application level will still show the “Recycle Bin” link on all the pages but it wouldn’t hold any information to restore at the site or site collection level.
    • Please note. This is very Important Info => Disabling Recycle bin even for a minute will immediately flush all the data from both recycle bins and those contents are unrecoverable.
  • Configure the recycle bin retention period – define when items in the recycle bin will automatically purged – by default is after 30 days.
    • You can configure to never purge from the recycle bin.
    • Note that this retention period reflects the total time after the item was initially deleted. In other words, total time spent by the item in both recycle bins.
    • Example: With the default value of 30 days, if item never deleted by the user in the first recycle bin, it will be automatically deleted permanently from the first and second recycle bin after 30 days. If item is deleted from the first recycle bin after 10 days, item will be permanently deleted from the second stage recycle bin after 20 days.
  • Configure the second-stage recycle bin – You can define the second stage recycle bin storage quota. by default, it’s a 50% of site quota. Maximum is 100% of site quota.
    • You can completely turn off the second-stage recycle bin which will disable the second-stage recycle bin.
    • Keep in mind that first stage of the recycle bin counts towards your site collection quota but Second stage of recycle bin has its own quota defined by these settings.
    • Example: If you define 100 GB site quota per site collection in the web application and allocate 50% quota for the second stage recycle bin, SharePoint will allocate 50 GB storage quota to the second-stage recycle bin making it 150 GB storage quota per site collection on the web application in the content database. This may have large implication of content database sizing and SQL Server storage requirements.
    • Here is most important and potentially scary nature of 2nd stage recycle bin => If site quota is not configured at the site collection level then recycle bin quota is unlimited.

Posted in Architecture | Leave a Comment »

 
Follow

Get every new post delivered to your Inbox.