Tuesday, October 18, 2011

SharePoint People Picker Filters Strike Back

Yay, Free Integration

One of the benefits of rolling out SharePoint in intranet environments is that it marries pretty well with Active Directory (and other LDAPs). An example of this is the People Picker. It allows you resolve (or look up) any user in the LDAP that you’re authenticating against.

Since LDAPs often get pretty dated/polluted there’s often a need to filter out certain sections of the LDAP or a certain genre of results. These might be old employees who have left the company, or users from a section of the organization that just aren’t relevant to the web application at hand.

An example of a filter at the Organizational Unit is below. The following filter ensures that the people pickers in the given web application only pull users from the Employees organizational unit (OU).

stsadm -o setsiteuseraccountdirectorypath -url http://webApplicationUrl -path "OU=Employees,DC=fullly,DC=quallified,DC=domain,DC=com"

Should you change your mind later, the following removes the filter above. In general, no application pool recycle or IISReset is required.

stsadm -o setsiteuseraccountdirectorypath -url http://webApplicationUrl -path ""

It’s worth mentioning that these filters don’t affect existing accounts in the site collection that have already been added. They only stop future users additions that would collide with the give filter.

There are some pretty expressive filters available out there. Many can target specific LDAP properties like title, name, organization, etc… or other fields. Examples can be found at:

The Resulting Errors

The problem with these filters is that its easy to forget about them and remember that they’re still in play. Specifically when adding users to a group, administrators/site owners are sometimes greeted with:

The user does not exist or is not unique. at Microsoft.SharePoint.Library.SPRequestInternalClass.UpdateMembers(String bstrUrl, Guid& pguidScopeId, Int32 lGroupID, Int32 lGroupOwnerId, Object& pvarArrayAdd, Object& pvarArrayAddIds, Object& pvarArrayLoginsRemove, Object& pvarArrayIdsRemove, Boolean bSendEmail) at Microsoft.SharePoint.Library.SPRequest.UpdateMembers(String bstrUrl, Guid& pguidScopeId, Int32 lGroupID, Int32 lGroupOwnerId, Object& pvarArrayAdd, Object& pvarArrayAddIds, Object& pvarArrayLoginsRemove, Object& pvarArrayIdsRemove, Boolean bSendEmail)

Which is an awfully confusing error. When you get the above, make sure that there aren’t any filters in play that would normally preclude the given user from resolving as they can cause this error.

You can check the existence of a directory path filter by running the following stsadm command:

stsadm -o getsiteuseraccountdirectorypath -url https://webApplicationUrl

If there are, remove them first and then try again. This is a step that should often be done before getting too far into a troubleshoot.

Hope that helps.

My Best,
Tyler

Friday, October 7, 2011

Customizing SharePoint 2007 Welcome and Site Actions Menus

Can We Trim That Down?

A good portion of a SharePoint branding implementation is discerning which out of the box features are working and those that need to be customized. Especially in branding engagements where we’re trying to write as little code as possible, being able to provide customizations w/out opening Visual Studio is a huge win.
Below are two very common modifications that can be done to both the Site Actions and the Welcome menu to restrict the options that appear.

Removing Options from the Site Actions Menu

There are two ways to declare a SiteActions menu, the very terse:
<SharePoint:SiteActions runat="server" />
Or the more verbose style like that found in the default.master:
<SharePoint:SiteActions runat="server"
AccessKey="<%$Resources:wss,tb_SiteActions_AK%>" id="SiteActionsMenuMain"
PrefixHtml="&lt;div&gt;&lt;div&gt;"
SuffixHtml="&lt;/div&gt;&lt;/div&gt;"
MenuNotVisibleHtml="&amp;nbsp;">
<CustomTemplate>
<SharePoint:FeatureMenuTemplate runat="server"
FeatureScope="Site"
Location="Microsoft.SharePoint.StandardMenu"
GroupId="SiteActions"
UseShortId="true">
<SharePoint:MenuItemTemplate runat="server" id="MenuItem_Create"                    
Text="<%$Resources:wss,viewlsts_pagetitle_create%>"
Description="<%$Resources:wss,siteactions_createdescription%>"
ImageUrl="/_layouts/images/Actionscreate.gif"
MenuGroupId="100"
Sequence="100"
UseShortId="true"
ClientOnClickNavigateUrl="~site/_layouts/create.aspx"
PermissionsString="ManageLists, ManageSubwebs"
PermissionMode="Any" />
<SharePoint:MenuItemTemplate runat="server" id="MenuItem_EditPage"
Text="<%$Resources:wss,siteactions_editpage%>"
Description="<%$Resources:wss,siteactions_editpagedescription%>"
ImageUrl="/_layouts/images/ActionsEditPage.gif"
MenuGroupId="100"
Sequence="200"
ClientOnClickNavigateUrl="javascript:MSOLayout_ChangeLayoutMode(false);"/>
<SharePoint:MenuItemTemplate runat="server" id="MenuItem_Settings"
Text="<%$Resources:wss,settings_pagetitle%>"
Description="<%$Resources:wss,siteactions_sitesettingsdescription%>"
ImageUrl="/_layouts/images/ActionsSettings.gif"
MenuGroupId="100"
Sequence="300"
UseShortId="true"
ClientOnClickNavigateUrl="~site/_layouts/settings.aspx"
PermissionsString="EnumeratePermissions,ManageWeb,ManageSubwebs,AddAndCustomizePages,ApplyThemeAndBorder,ManageAlerts,ManageLists,ViewUsageData"
PermissionMode="Any" />
</SharePoint:FeatureMenuTemplate>
</CustomTemplate>
</SharePoint:SiteActions>
Although there’s some testing that needs to be done, you can for the most part use either the PermissionsString/PermissionMode properties to conditionally hide menu items OR you can remove them in entire (by simply removing the menu item markup [above]).

Even when we start to work with publishing sites, it’s worth mentioning that the PublishingSiteAction menu (like that found in blueband.master) is really just a control template which pretty much does the above but adds additional controls to the menu. You can find said control at:

C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\TEMPLATE\CONTROLTEMPLATES\PublishingActionMenu.ascx.

See something you don’t like? Change it. Its worth mentioning that we typically don’t recommend altering any of the controls in the ControlTemplates folder themselves (since it has farm wide impact). If you can, either make your changes in the masterpage (using selective declarative markup like the above), or create a copy of an existing control, make your alterations in the copy and reference it from your master page.

Either way, keep your footprint as small as possible.

Removing Options from the Welcome Menu

The welcome menu works in pretty much the same way. Typically it’s declared looking like:
<%@ Register TagPrefix="wssuc" TagName="Welcome" src="~/_controltemplates/Welcome.ascx" %>
...
<wssuc:Welcome id="IdWelcome" runat="server">
Notice that similar to the PublishingSiteAction menu (above) it simply references a control template found in:

C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\TEMPLATE\CONTROLTEMPLATES\Welcome.ascx

The easiest way to work with a reduced version of the welcome menu is to replace your existing welcome menu control (above) with the actual control markup/template, and then selectively remove what you don’t want (and test). An example of such a trimmed control (which only shows the “Sign In as a Different User” and “Logout” options) would look like:
<SharePoint:PersonalActions AccessKey="<%$Resources:wss,personalactions_menu_ak%>" ToolTip="<%$Resources:wss,open_menu%>" runat="server" id="ExplicitLogout">
<CustomTemplate>
<SharePoint:FeatureMenuTemplate runat="server"
FeatureScope="Site"
Location="Microsoft.SharePoint.StandardMenu"
GroupId="PersonalActions"
id="ID_PersonalActionMenu"
UseShortId="true">
<SharePoint:MenuItemTemplate runat="server" id="ID_LoginAsDifferentUser"
Text="<%$Resources:wss,personalactions_loginasdifferentuser%>"
Description="<%$Resources:wss,personalactions_loginasdifferentuserdescription%>"
MenuGroupId="200"
Sequence="100"
UseShortId="true"/>
<SharePoint:MenuItemTemplate runat="server" id="ID_Logout"
Text="<%$Resources:wss,personalactions_logout%>"
Description="<%$Resources:wss,personalactions_logoutdescription%>"
MenuGroupId="200"
Sequence="300"
UseShortId="true"/>
</SharePoint:FeatureMenuTemplate>
</CustomTemplate>
</SharePoint:PersonalActions>
And voila, this:

Original, unmodified welcome menu.

Becomes this:

Customized Welcome Menu w/out authoring a feature or changing any controls in the controltemplates folder.

This can sometimes be super helpful, not only can you selectively pick links (and still hide the whole control with a <Sharepoint:SPSecurityTrimmedControl/> if need be), but you also don’t have to author a feature to change the menu or start messing with controls in the ControlTemplates folder (which can have a farm wide impact).

Hope this helps someone.

My Best,
Tyler