Point Deep

Mundeep's Tech Blog

Posts Tagged ‘Sharepoint’

Sharepoint 2010 Remote Debugging

Posted by mundeep on August 5, 2011

The following is a realy good article about Remote Debugging Sharepoint 2010 webparts and worth a read if you are ever having trouble getting it working:
http://lemonharpy.wordpress.com/2011/03/17/remote-debugging-sharepoint-2010-solutions/

Essentially the main things to ensure are:

  1. You are running Visual Sudio Remote Debugger (msvsmon.exe)
  2. You are using an account with permissions to debug.
  3. You have placed the pdb files in the approriate folder (usually in GAC)
  4. The version of code running on the remote server is exactly the same as in the Visual Studio project you have opened (If possible it is always good to perform fresh build and deployment before trying to debug.
Advertisements

Posted in .NET, Sharepoint | Tagged: , , | 1 Comment »

Powershell Script to Import Sharepoint Organization Profiles from Active Directory

Posted by mundeep on November 8, 2010

Here is one of my first Powershell scripts (so improvement suggestions welcome 🙂

The requirement was to script the creation of SharePoint Organization Profiles from Active Directory Organizational Units, including building the hierarchy and setting the Profile Subtype appropriately. Creation of the Organizational Profiles was based on the C# code in the How to: Create User Profiles and Organization Profiles MSDN article.

Before running this note that i had a predefined list of profile subtypes that corresponded to the level of the organizational unit in the hierarchy. The top level was Root, next level was Group, then Division, Branch & finally Section. The following is an example of the organizational structure in terms of Profile Subtypes.

  • Department (Root Level)
    • Group #1
      • Division #1
        • Branch #1
          • Section #1
      • Division #2
        • Branch #2
          • Section #2
          • Section #3
          • Section #4
        • Branch #3
          • Section #5
          • Section #6
      • Division #4
        • Branch #7
    • Group #2
      • Division #5
        • Branch #8
          • Section #9
      • Division #6
        • Branch #9
          • Section #10
          • Section #11
          • Section #12
      • Division #6
        • Branch #9
#Create All Organisation Profiles from AD OU's
#Load Sharepoint Snapin
Add-PSSnapin Microsoft.SharePoint.PowerShell
#Declare Some Globals for Profile Management
$context = Get-SPServiceContext -Site http://{sharepointwebappurl}/
$psm = [Microsoft.Office.Server.UserProfiles.ProfileSubtypeManager]::Get($context);
$opm = New-Object Microsoft.Office.Server.UserProfiles.OrganizationProfileManager($context)
$rootOrg = $opm.RootOrganization

#Find All Children OU's Based on Parent OU's Distinguished Name (DN)
function Find-Child-OUs
{
Param ([string]$sParentDN)
	$ldapPath = "LDAP://" + $sParentDN
	$query = new-object system.directoryservices.directorysearcher([ADSI]$ldapPath)
	#Only Search for OUs
	$query.filter = "(objectClass=organizationalUnit)"
	#Only Search One Level Deep (ie. Children)
	$query.SearchScope = "OneLevel"
	$results = $query.findAll()
	Write-Host $sParentDN " has " $results.Count " children"
	return $results
}

#Create an Organization Profile under parentOrg for provided OU
function Create-Organization {
Param ($ou, $parentOrg, $levelTitle)
	Write-Host "Creating:" $ou.description "under" $parentOrg.DisplayName "of type" $levelTitle
	$subType = $psm.GetProfileSubtype($levelTitle);
	$orgProfile = $opm.CreateOrganizationProfile($subType, $parentOrg)
	$orgProfile.DisplayName = $ou.description
	$orgProfile.Commit()
	return $orgProfile
}

#Determine Subtype Based on Level
function Get-Level-ProfileSubtype {
Param ($level)
	$subtypeTitle = $level
	switch ($level) {
		0 { $subtypeTitle = "Root"; break }
		1 { $subtypeTitle = "Group"; break }
		2 { $subtypeTitle = "Division"; break }
		3 { $subtypeTitle = "Branch"; break }
		4 { $subtypeTitle = "Section"; break }
		default { $subtypeTitle = "Other" }
	}
	return $subtypeTitle
}

#Create Organization Profiles for All OU's underneath the provided OU and Organization Profile
function Create-Child-Orgnizations
{
Param ([string]$currentOuDn, $parentOrg, $level)
	#Create the Organization
	Write-Host "Searching for Children for: " $currentOuDn
	$children = Find-Child-OUs $currentOuDn
	if ($children -ne $null) {
		Write-Host -ForegroundColor red $children.Count "OU's found under:" $currentOuDn
		Foreach($childOu in $children)
		{
			$ou = $childOu.GetDirectoryEntry()
			$ouDn = $ou.distinguishedname
			$levelTitle = Get-Level-ProfileSubtype($level)

			#Create the Child Organization
			$newOrg = Create-Organization $ou $parentOrg $levelTitle
			Write-Host -ForegroundColor green "OU Created: " $newOrg.DisplayName " = " $newOrg.ProfileSubtype.Name
			$nextLevel = $level + 1
			Create-Child-Orgnizations $ouDn $newOrg $nextLevel
		}
	}
}

#Create All Organization Profiles Starting from Provided OU DN
function Create-All-Organizations {
Param ([string]$rootOuDn)
	Create-Child-Orgnizations $rootOuDn $rootOrg 1
}

Once you have loaded all the globals and declared all the functions above the following two lines (can be done in one) will begin the profile creation.

#Run Creation From Root Orgnization Unit, Make sure the following matches the LDAP query to the Root OU in your AD structure.
$rootOu = "OU=Department,DC=depttest,DC=gov,DC=au"
Create-All-Organizations $rootOu

To help with testing & re-running code i also created a couple of functions to (a) List all Organizational Profiles under a parent and (b) Delete all Organization Profiles under a parent.

#Retrieve existing Org Profiles
function List-OrgProfiles {
Param($parentOrg)
	if ($parentOrg.HasChildren) {
		foreach ($childOrg in $parentOrg.GetChildren()) {
			Write-Host $parentOrg.DisplayName "-" $childOrg.DisplayName
			List-OrgProfiles $childOrg
		}
	}
}

#Delete existing Org Profiles
function Delete-OrgProfiles {
Param($parentOrg)
	# If Parent Has Children Delete them first
	if ($parentOrg.HasChildren) {
		foreach ($childOrg in $parentOrg.GetChildren()) {
			#Write-Host $childOrg.DisplayName " - " $parentOrg.DisplayName
			Delete-OrgProfiles $childOrg
		}
		#Once children are deleted remove the current org
		if ($parentOrg.RecordId -ne $opm.RootOrganization.RecordId) {
			$opm.RemoveOrganizationProfile($parentOrg.RecordId)
			Write-Host "Removing(" $parentOrg.DisplayName ")"
		}
		else {
			Write-Host "KEEP (" $parentOrg.DisplayName ")"
		}
	}
	else {
		#If not children then delete the current org
		if ($parentOrg.RecordId -ne $opm.RootOrganization.RecordId) {
			$opm.RemoveOrganizationProfile($parentOrg.RecordId)
			Write-Host "RemovingChildless(" $parentOrg.DisplayName ")"
		}
		else {
			Write-Host "Childless KEEP(" $parentOrg.DisplayName ")"
		}
	}
}

Posted in Powershell, Sharepoint | Tagged: , , , , | Leave a Comment »

Updating the Created Date of a Document or List Item Programmatically

Posted by mundeep on May 22, 2009

A common tasks developers are required to do with Sharepoint is migrated documents from either legacy systems or older Sharepoint sites into a document library. There are many ways to do this documented out there (most commonly using the Files.Add method of the API), but one of the common requirements during this ‘migration’ is to retain the Created Date or Created By fields. Sowmyan’s blog has a good description of how to set the Created By/Modified By user fields here.

Updating the Created Date of a document or list item in Sharepoint is even easier, simply set the “Created” field of the item to the value you wish to set. For example if using the Files.Add methods in the API (as described by Dave Hunter) then the following code snippet will update the Created Date:

// add the file   
SPFile file = docLib.RootFolder.Files.Add(newFileName, inputStream);   
// get the list item for that file   
SPItem item = file.Item;   
//Set the Created Date
item["Created"] = "2009-02-26 15:00:00";
item.Update();

Posted in .NET, Sharepoint | Tagged: , , , | Leave a Comment »

Checking if a SPFolder Exists

Posted by mundeep on February 24, 2009

Ran into a colleague’s code that was incorrectly trying to check if a folder existed. It was something like:

private bool CheckFolderExists(SPWeb parentWeb, string folderName) {
    SPFolder folder = parentWeb.GetFolder(folderName);
    if (folder == null) {
        return false;
    }
    else {
         return true;
    }
}

however this always returns an actual SPFolder object, and the correct way is to check the Exists property of the returned object ie:

private bool CheckFolderExists(SPWeb parentWeb, string folderName) {
    SPFolder folder = parentWeb.GetFolder(folderName);
    return folder.Exists;
}

NB: Yes, this post is almost identical to my earlier one about checking if an SPWeb object exists.

Posted in .NET, Sharepoint | Tagged: , , | 10 Comments »

InfoPath Forms Services is not turned on

Posted by mundeep on February 17, 2009

While trying to deploy an InfoPath Form to sharepoint via stsadm commands i received the error:

InfoPath Forms Services is not turned on.

Initially thinking that the Enterprise features where not enabled in the Site Collection i was deploying to i tried activating the “Office SharePoint Server Enterprise Site Collection features”, however that did not make a difference.

Turns out the problem was that the account i was trying to deploy under (my own) did not have sufficient permissions (to what i am not sure – but i am guessing the configuration database), running the deployment under an account with more priveleges solved the problem.

Summary: If you get the above error make sure to try your deployment/stsadm commands under an account with higher priveleges (most likely access to the config database).

Posted in Sharepoint | Tagged: , , , | Leave a Comment »

stsadm runs slowy

Posted by mundeep on October 21, 2008

Ran into problems in a virtualised (vmware) sharepoint environment where stsadm commands would take a long time to run (upto 30 seconds for a simple stsadm -?) when running under my account but it would run fine (couple of seconds) under a different user account.

After scratching our heads and trying to determine if any security groups where missing from my account (and the other people this would happen to) we  narrowed it down to occuring only on machines where we did not perform the sharepoint install.

This didn’t really help solve the problem but some googling bought me to Mark Rhode’s blog where he explains that the problem is usually due to stsadm trying to query crl.microsoft.com before executing – hence our issue being that internet proxies where not correctly setup for some users.

The simplest solution to the problem is to correct the proxy so the environment has internet access. However for those that don’t want to (or can’t) open their virtual environments to the internet, Mark has a couple of other suggestions (such as adding a host entry for crl.microsoft.com pointed to 127.0.0.1).  Paul Horsfall also explains how he found the problem using Ethereal and then used proxycfg.exe to setup his proxy.

Posted in Sharepoint | Tagged: , , | Leave a Comment »

Hiding Mapped Property Images in User Profiles

Posted by mundeep on September 9, 2008

While working with Sharepoint User Profiles I have had to perform a hack to remove Mapped property images or Warning property images from the Sharepoint User Profiles edit page. Using the default ShowMappedIcon or ShowWarningIcon properties of the “UserProfileEditor” control easily allow you to hide the warnings and mapping information however it destroys the layout of the rest of the editing page by missing lots of table cells and results in an ugly looking page.

As a result i had to instead leave ShowMappedIcon=”true” and then use the following javascript to hide all the mapping images and wording:

/// <summary>
/// Hide mapping text and images.
/// </summary>
function clearMappingDisplay() {
    try {
        //Hide Mapping Images
        //Find all images on page
        var images = document.getElementsByTagName('IMG');
        for (var i=0; i < images.length; i++) {
            var curImage = images&#91;i&#93;;
            //If image is for "Mapped" property
            if(curImage.alt == "Mapped") {
                //Replace image with blank.gif & hide image
                curImage.src = curImage.src.replace("mapped", "blank");
                curImage.style.visibility = "hidden";
            }
        }
        //Hide mapping text
        //Get tblMain container
        var mainTable = document.getElementById('tblMain');
        //Get all tables within main table
        var subTables = mainTable.getElementsByTagName('TABLE');
        for (var i=0; i < subTables.length; i++) {
            var curTable = subTables&#91;i&#93;;
            //Find the table that includes the mapping text
            if(curTable.innerText.indexOf("mapped for profile import") > -1) {
                for (var k=0; k < curTable.cells.length; k++) {
                    var cell = curTable.cells&#91;k&#93;;
                    //Find the cell that contains the mapping text
                    if(cell.innerText.indexOf("mapped for profile import") > -1) {
                        //Clear the mapping text
                        cell.innerText = "";
                    }
                }
            }
        }
    }
    catch (ex) {
        //TODO: Handle error.
    }
}
//Ensure sharepoint runs the clearMappingDisplay method on Page (Body) Load
_spBodyOnLoadFunctionNames.push("clearMappingDisplay");

Posted in Sharepoint | Tagged: , | 2 Comments »

What accounts does the people picker show?

Posted by mundeep on August 20, 2008

My colleague Ishai Sagi recently did some research into what accounts the people picker shows and determined the LDAP query that was being used to display accounts if you are using Windows authentication. I did some further research into this and i have noticed that aswell as your authentication provider source (eg. LDAP accounts for sites using Windows Authentication/Active Directory) the picker also shows accounts from the User Information List.

This is important to note as it means that accounts that may have been deleted or disabled in your authentication provider still come up to be selected by users that are entering information into a people field.

For further details on the User Information List see this article on Andrew Connell’s blog which appears to be for Sharepoint 2003 however seems to still mostly apply for MOSS. Also Sahil Malik has done some research into User Profile Information and how it flows.

Posted in Sharepoint | Tagged: , , , , | Leave a Comment »

Value does not fall within the expected range

Posted by mundeep on August 14, 2008

I was debugging a problem today where i would get the following error recently when trying to associate a content type with a document library:

Value does not fall within the expected range. at Microsoft.SharePoint.SPFileCollection.get_Item(String urlOfFile)
at Microsoft.SharePoint.SPContentTypeCollection.Add(SPContentType contentType)
at Microsoft.SharePoint.ApplicationPages.AddContentTypeToListPage.Update(Object o, EventArgs e)
at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

After examining the elements.xml and confirming that (a) all the bound content types exists and (b) all the site columns used by the content types existed, i noticed that there was a mis-match in the name of the content-type and the url used in the module to deploy the document template. A snippet of the elements.xml specific to one of the content-types is shown below.

  <ContentType Name="Briefing (Event)" Group="Custom Document Content Types" Description="" ID="0x0101002DB264DB4656424CB8247FDE6BA03F7E021C">
    <FieldRefs>
      <FieldRef ID="{52578fc3-1f01-4f4d-b016-94ccbcf428cf}" Name="Comments" />
      <FieldRef ID="{cd94be8c-d754-4a6d-865d-7cb40375b11c}" Name="Document Status" />
	  ...
      <FieldRef ID="{130da223-b498-417c-9bdd-1fc2ac43aa6e}" Name="Country" />
    </FieldRefs>
    <DocumentTemplate TargetName="Briefing_template.doc" />
  </ContentType>
  <Module Name="Briefing" Url="_cts/Briefing" RootWebOnly="true">
    <File Url="Briefing_template.doc" Name="Briefing_template.doc" Type="Ghostable" />
  </Module>

The mistake was that the Url=”_cts/Briefing” property of the module should have been Url=”_cts/Briefing (Event)” to match the Name of the content-type.

Update: I also ran into the same error on another content type where the name of the template file in the tag did not match the actual filename.

Posted in Sharepoint | Tagged: , , | Leave a Comment »

Checking if a SPWeb Exists

Posted by mundeep on December 19, 2007

Ran into a problem today where we were incorrectly trying to check if a web existed. We were trying:

private bool ChildWebExists(SPWeb parentWeb, string childWebName) {
    return null != parentWeb.Webs[childWebName];
}

however this always returns an actual SPWeb object, turns out the correct way is to check the Exists property of the returned object ie:

private bool ChildWebExists(SPWeb parentWeb, string childWebName) {
    using (SPweb childWeb = parentWeb.Webs[childWebName]) {
        return childWeb.Exists;
    }
}

Posted in Sharepoint | Tagged: , | 1 Comment »