SharePoint: Getting Email Address from Username

Just a quick post – I have encountered some convoluted ways of getting somebody’s email address when you only know there login name. The best ways to get this information are typically as follows:

When the user has permissions on the SharePoint site where your code is running from, use the following:

Using (SPSite site = new SPSite(“http://url/of/site“))
{
    using (SPWeb web = site.OpenWeb())
    {
        SPUser person = web.AllUsers[“ct\loginname”];
        string email = person.email;
        string displayName = person.name;       

        // etc…
    }
}

When the user does not have permission on the SharePoint site, but belongs to the domain that your server running code is joined to:

DirectorySearcher searcher = new DirectorySearcher();
string username = “nnow”;
searcher.Filter = String.Format(“(&(objectClass=user)(cn={0}*))”, username); 
SearchResult result = searcher.FindOne();
if (result != null)
{
    string email = result.Properties[“mail”][0].ToString();
    string displayname = result.Properties[“displayname”][0].ToString();
}

Note that you need to reference the System.DirectoryServices namespace.

SharePoint: EXECUTE permission was denied on the object ‘proc_putObject’,

I was resolving an issue on a SharePoint project the other day where timer jobs would not activate from a feature (the feature was scoped to a site collection). The error message was “The EXECUTE permission was denied on the object ‘proc_putObject’, database ‘SharePoint_Config’, schema ‘dbo’.”.

I did some searching, at the few blog articles I found said to either make the app pool user as local admin on the server, turn off unsafe updates in the code, or directly modify db permissions on the SharePoint config database (note that this implies that the user is part of the SQL builtin\administrators group and hence has db_owner rights to the config db – not secure!). All of these did not seem quite right to me.

The problem turns out that timer jobs features should be scoped to the farm, and hence should be installed and activated as a farm feature, hence when activating at site scope, you the app pool account does not have rights to the stored procs. Ideally, you should therefore rescope your feature, or failing that (temporarily) add your app pool service account for the appropriate webapplication to the farm administrators group via central admin.

Attempt at building Sysprep’d VM with Server 2008, SQL 2008, MOSS

In the past I have followed excellent article on how to build a sysprep’d moss vm – http://paulhorsfall.co.uk/archive/2007/05/21/SharePoint-Sysprep-and-SQL.aspx. I wanted to do the same with all of the latest Microsoft products on Windows Server 2008, but I could not apply the everything from the quoted article, as sysprep for server 2008 now uses an answerfile. Note that sysprep is now also included as part of windows server 2008.  Note that I am still having a few issues getting this working – namely that I cannot start the osearch service via stsadm until I reboot (hence a cannot run the first logon script automatically from sysprep). This is discussed further below.

Building VM Prior to Sysprep

  1. Using Virtual PC 2007,  I created a new virtual machine with Windows Server 2008 Enterprise as the host operating system
  2. I then installed the following software (you can choose what you want to install as long as SQL is present): Microsoft Office Ultimate (includes infopath), Scite 1.5.7, Firefox, IE Developer Toolbar, .NET 3.5 Framework, SQL Server 2008 Enterprise, MOSS Enterprise with SP1, Visual Studio 2008, Visual Studio 2008 Team Explorer, Flash plugin, Adobe reader, Silverlight 2.0, Expression Blend 2, Expression Web 2, Sharepoint Designer + SP1, Fiddler
  3. I then installed MOSS Enterprise with SP1, but did not run the configuration wizard.  IT IS CRUCIAL NOT TO RUN THIS BEFORE SYSPREP.
  4. For convenience, I added C:\Program Files\Common Files\Microsoft Shared\Web Server Extension\12\bin to the path environment variable.
  5. As sysprep removes all users from SQL, except from builtin\administrators and the sa account, and security is left as windows integrated, I gave the builtin\administrators group sysadmin rights via SQL Server Enterprise Manager (otherwise you will not be able to create new databases etc after sysprep).

Building Unattend Answer File

I then built an answerfile to be used by sysprep using Microsoft Windows AIK for Windows Server 2008. To do this, I created another VM using Windows Server 2008 Enterprise and installed Microsoft Windows AIK on it. You could simple just create an answerfile using a text / xml editor if you wanted, as long as you ensure its structure is correct. My resultant answerfile is relatively simple and is as follows:

<?xml version=”1.0″ encoding=”utf-8″?>
<unattend xmlns=”urn:schemas-microsoft-com:unattend”>
    <settings pass=”windowsPE”>
        <component name=”Microsoft-Windows-Setup” processorArchitecture=”x86″ publicKeyToken=”31bf3856ad364e35″ language=”neutral” versionScope=”nonSxS” xmlns:wcm=”
http://schemas.microsoft.com/WMIConfig/2002/State” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”>
            <UserData>
                <ProductKey>
                    <WillShowUI>Always</WillShowUI>
                </ProductKey>
                <AcceptEula>true</AcceptEula>
                <FullName>Robert Nowik</FullName>
                <Organization>Microsoft</Organization>
            </UserData>
        </component>
    </settings>
    <settings pass=”oobeSystem”>
        <component name=”Microsoft-Windows-Shell-Setup” processorArchitecture=”x86″ publicKeyToken=”31bf3856ad364e35″ language=”neutral” versionScope=”nonSxS” xmlns:wcm=”
http://schemas.microsoft.com/WMIConfig/2002/State” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”>
            <FirstLogonCommands>
                <SynchronousCommand wcm:action=”add”>
                    <CommandLine>C:\sysprep\mossconfig.bat %COMPUTERNAME%\%USERNAME% %USERNAME%@%COMPUTERNAME% %COMPUTERNAME%\%USERNAME% password
</CommandLine>
                    <Order>1</Order>
                    <Description>Setup Moss</Description>
                </SynchronousCommand>
            </FirstLogonCommands>
        </component>
    </settings>
    <cpi:offlineImage cpi:source=”wim:c:/users/administrator/desktop/install.wim#Windows Longhorn SERVERENTERPRISE” xmlns:cpi=”urn:schemas-microsoft-com:cpi” />
</unattend>

Note that the most important call if the FirstLogonCommand that calls a batch file (that more or less corresponds with that from the following article http://paulhorsfall.co.uk/archive/2007/05/21/SharePoint-Sysprep-and-SQL.aspx. Note that the password used is the only hardcoded string – this must be whatever the password of your admin account is (bold red text above).

Running Sysprep

I then copied the following files to a newly created folder named C:\sysprep, on my newly created vm: the mossconfig.bat, unattend.xml and a batch file containing the command to run sysprep, so you can simple double click. These are in the zip at the end of this article.

Following this, I made a copy of the VM, as I obviously wanted to keep my original master prior to unsealing (renaming accordingly). I loaded this up, and then ran C:\sysprep\runsysprep.bat, which sealed my vm. On next loading my VM, I was then prompted for various settings (e.g. computername, timezone etc). Ideally, when someone logs in for the first time, I wanted mossconfig.bat to run and set up moss. However I ran into an issue, where the search service would not start until i rebooted again (I never had this issue on similar scenarios on Server 2003). I think this was because my computer was part of a workgroup and not a domain. I hence had to run the mossconfig batch file manually after a reboot (see postinstall.bat and mossconfigmanual,bat in the zip file at the end of this article). Note that I have left placeholder batch files in the attached zip, to indicate where the moss configuration code should be called.

Side Note – notes why automated moss install was not successful:

When running  C:\Users\Administrator>stsadm -o osearch -action start -role indexquery -farmcontactemail <email> -farmserviceaccount <domain\username> -farmservicepassword <password> -defaultindexlocation “C:\Program Files\Microsoft Office Servers\12.0\Data\Applications” on first logon from sysprep, I got the error:

‘start’ action failed. Additional information: Cannot start service OSearch on computer ‘.’.

The event log contained two errors:

The Office SharePoint Server Search service depends on the Netlogon service which failed to start because of the following error: The operation completed successfully.

This computer is configured as a member of a workgroup, not as a member of a domain. The Netlogon service does not need to run in this configuration.

I have not yet figured these out, but after I reboot and run exactly the same command, everything runs fine. I will update this article if and when I get this resolved.

Sample files / Notes

  • Note that there is some dialog after sysprep prompts you to change your password (irrelevant of whether the Administrator password was set to never expire). This must match what is used in the answerfile for calling the moss batch file (ideally I would supress this to ensure passwords are consistent, but have not determined how at the time of writing).
  • Once my new VM was created, I installed Virtual PC additions. If you install this before sysprep, it doesn’t seem to persist when unsealing.
  • Also note that you may want to alter the unattend.xml call to mossconfig.bat to use service accounts instead of the administrator account.

If anyone has an ideas on starting osearch from sysprep onfirstlogon, please give me a shout!!!

SharePoint: Report contains no data

This error can occur when viewing one of the usage reports / workflow reports in SharePoint simple if the report has no data (sounds obvious)! If you do need reports, you should ensure that relevant audit events are recorded (from the site settings page at the root of the site collection), although be aware that this will have implications on performance.

Note that with SPD workflows, audit logs are written out, but if you write a custom workflow through Visual Studio, you have to programmatically write out audit events. 

Related Links:

http://support.microsoft.com/kb/953133/en-us
http://social.msdn.microsoft.com/
http://office.microsoft.com/en-us/sharepointserver

SharePoint: Feature Containing InfoPath Form With Code Behind

I recently was handed a project that consisted of an InfoPath form with code behind, as well as a workflow with custom InfoPath forms. The code was in visual studio 2005 projects, and was packaged into SharePoint wsps using wspbuilder. This blog article only concentrates on deploying the InfoPath form with code behind as a SharePoint wsp, using wspbuilder (http://www.codeplex.com/wspbuilder).

A rough outline of the structure is as follows:

  1. Infopath originals xsn’s existing outside of the visual studio 2005 solution.
  2. The infopath forms were then published into a features folder of a project that used wspbuilder to construct a wsp. Note that infopath threw “unknown errors” in the preexisting published xsn file was not checked out. Also note that the feature uses the XsnFeatureReceiver.
  3. The code behind for the infopath form existed in a vsta project, which resided in the solution. Note that when editing this code, I always initiated this from Infopath, and not from Visual Studio directly.  The output assembly was then automatically bound into the xsn by vsta and published to the project containing the feature folder.
  4. The project containing the feature was then built – a wsp was subsequently generated and deployed.

After doing the above, I got the following error:

System.IO.FileNotFoundException: Could not load file or assembly file:///C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\Template\Features\<MyFeatureFolder>\<InfopathCodeBehind>.dll or one of its dependencies. The system cannot find the file specified.

It turns out that when the xsn is deployed through upload form template on the applications tab of central admin, a feature is created on the fly on the file system. When this feature is created, SharePoint extracts the dll from the xsn so that the dll sits beside the xsn in the features folder. See the screenshots below.

pubishedinfopathform2

pubishedinfopathform

This was a little surprising that it is extracted, as the dll exists in the xsn. Anyway, from that, I altered feature so that it contained the dll extracted from the xsn. Note that this was a manual step – to do this i did the following:

  1. Copy xsn file and rename .cab.
  2. Extract dll from .cab and put in relevant location in your features folder
  3. Ensure that feature.xml and elements.xml contain a reference to the dll.

SharePoint: Infopath error when accessing external data

I had an issue yesterday where an infopath form published in SharePoint was accessing webservices on another server (on a different domain). Whereas this was working fine when I was testing the infopath form directly on the SharePoint server, when i accessed the form off-box, I got the following error:

An error occurred accessing a data source.
An entry has been added to the Windows event log of the server.
Log ID: 5566

It turns out that this is because of the ntlm double hop issue – in that credentials from the users browser are passed to the SharePoint server, but are not passed to the webservice. This is a well known issue and to resolve this, you typically need to implement kerberos authorisation instead of ntlm.

The workaround to this (although less than ideal) is to embed the credentials to access the webservice in the data connection file (stored in the data connections library in sharepoint central admin). Fortunately this library does not permit people to download and view credentials in plain text. To implement this workaround, simply alter your data connection files to contain the following:

<udc:Authentication>
    <udc:UseExplicit CredentialType=”NTLM”>
        <udc:UserId>DOMAIN\USERNAME</udc:UserId>
        <udc:Password>PASSWORD</udc:Password>
    </udc:UseExplicit>
</udc:Authentication>

SharePoint: Content Deployment Errors

Just a quicknote – I have recently been doing a lot with stsadm import and export, and have experienced intermittent errors, such as “FatalError: The element ‘FieldTemplate’ in namespace ‘urn:deployment-manifest-schema’ has invalid child element ‘Field’ in namespace http://schemas.microsoft.com/sharepoint/’. “. It turns out that this was a sharepoint bug – fortunately a hotfix is available at http://support.microsoft.com/kb/955594.

Also another quicknote: when using stsadm import and export, or the content deployment api, you will get errors if the user you are running as does not have rights on the appropriate content database.