Dec 30, 2009

Basic steps for a Sharepoint workflow

I always have problems configuring the basic setup for a Sharepoint workflow, especially creating tasks.

Things to remember:
1. Each task must have its own correlation token.
2. In the event for onWorkflowActivated you should set the workflowID = workflowProperties.workflowID.
3. In the event for createTask, you must set the taskId = Guid.NewGuid()
4. Create a fault handler to log exceptions to the HistoryList and add Microsoft.Office.Server.Diagnostics.PortalLog.LogString("error details")

Dec 10, 2009

How to cut and paste Active Directory group members

The Active Directory Users and Groups MMC plugin (dsa.msc) is quick for finding groups and members, but hard to copy and paste from. Or at least I haven't figured out how yet.

So we go to the command line:
dsquery group -name ServiceDesk|dsget group -members > ServiceDeskMembers.txt


This command will output all the members of the group ServiceDesk to the text file ServiceDeskMembers.txt

Dec 4, 2009

How to find SQL queries with high CPU usage

Using this query in SQL Server 2005, you can see the top 5 queries ranked by CPU usage (http://msdn.microsoft.com/en-us/library/ms189741(SQL.90).aspx):


select DB_NAME(QP.dbid) as "Context_Database",top_5.*

from (SELECT TOP 5 query_stats.plan_handle AS "Query_Hash",



SUM(query_stats.total_worker_time)/SUM(query_stats.execution_count)AS "Avg CPU Time",
MIN(query_stats.statement_text)AS "Statement Text"


FROM(



SELECT QS.*,

SUBSTRING(ST.text, (QS.statement_start_offset/2)+ 1,



((CASE statement_end_offset



WHEN-1 THEN DATALENGTH(st.text)



ELSE QS.statement_end_offset



END - QS.statement_start_offset)/2) + 1)AS statement_text



FROM sys.dm_exec_query_stats AS QS



cross apply sys.dm_exec_sql_text(QS.sql_handle)as ST

) as query_stats




GROUP BY query_stats.plan_handle


ORDER BY 2 DESC) as top_5
cross apply sys.dm_exec_query_plan(top_5.Query_Hash) as QP
;

Nov 30, 2009

How to use SPSWC controls in Sharepoint DataFormWebpart

If you try to add a control such as to a Sharepoint Data View Webpart inside the XSLT, Sharepoint Designer will crash and your page won't render correctly.

You need to add two things to fully register the SPSWC namespace for use in XSLT.

1. Add at the top of your page:

<%@ Register Tagprefix="SPSWC" Namespace="Microsoft.SharePoint.Portal.WebControls" Assembly="Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>


2. In the <xsl:stylesheet> tag at the beginning of your Data View Webpart, add an entry for:
xmlns:SPSWC="Microsoft.SharePoint.Portal.WebControls"


That should do it.

Nov 20, 2009

Sharepoint and Reporting Services: User cannot be found

As you can deduce from the error, the problem is that the author of a Sharepoint web site cannot be found.

When Reporting Services tries to render a page, it seems to read the Author field of every web site of all site collections in all web applications. If the author cannot be resolved in just one web site(the user had been deleted), this fails.

You can see the same error with Sharepoint Manager 2007 tool (http://spm.codeplex.com/) by browsing to a web site and viewing the Author field.

I copied code from this blog post (http://blog.krichie.com/2008/09/12/resetting-the-author-on-a-sharepoint-site-or-wherefore-art-thou-author-redux/) to reset the Author field for sites that have this error in a site collection.

Here's the modified code:

// BEGIN SPResetAuthor

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

namespace SPResetAuthor
{
class Program
{
static void Main(string[] args)
{
if (args.Length < 2)
{
string sFormat = "{0,5}{1,-20}{2}\n";
StringBuilder sb = new StringBuilder();
sb.Append("\nSYNTAX: SPResetAuthor.exe webURL DOMAIN\\USER \r\n");
sb.Append("\nwhere:\n\n");
sb.AppendFormat(sFormat, " ", "", "The Web URL where"
+ " the author needs to be reset");
sb.AppendFormat(sFormat, " ", "", "The Login Account"
+ " for the new author, i.e. DOMAIN\\USER");
Console.WriteLine(sb.ToString());
return;
}

// Open the site collection
Console.WriteLine("Opening site collection for: {0}",args[0]);
SPSite site = new SPSite(args[0]);
String userName = args[1];

fixEmptyAuthors(site.AllWebs, userName);

}

private static void fixEmptyAuthors(SPWebCollection webs,String userName) {
foreach (SPWeb web in webs)
{
bool authorEmpty = true;

try
{
web.EnsureUser(web.Author.LoginName);
authorEmpty = false;
}
catch (Exception e)
{
authorEmpty = true;
}

Console.WriteLine("Site (web) title: " + web.Title);

if (authorEmpty)
{
Console.WriteLine("Resetting Author to: {0}", userName);
SPUser user = web.EnsureUser(userName);
web.Author = user;
web.Update();
}

fixEmptyAuthors(web.Webs,userName);

}
}
}
}

// END SPResetAuthor




Create a Console application with this code (don't forget the reference to Microsoft.Sharepoint.dll) and run the app with: spresetauthor.exe http://server:port domain\user

You'll need to run the application for all site collections you have (My Sites, SSP, etc) and I recommend the "sharepoint\system" as the new author.

Good luck!

Oct 27, 2009

Sharepoint navigation audience problem

I fought for a few hours today trying to add a Sharepoint group to an audience on a global navigation link.

My coworker had come across the same issue and it seems that if a group used as an audience doesn't have any permissions on the site collection, the audience won't work for this group, even if every member has site rights through other groups.

The lesson: All groups should have at least Read permissions on the root site collection.

Aug 13, 2009

Restaurar Sharepoint

Here are several ways to backup and restore (or move) a Sharepoint installation, from the least to most difficult:

  1. stsadm -o export will export a site or subsite (-includeusersecurity will preserve all security roles and permissions).
  2. stsadm -o backup will backup an entire site collection
  3. stsadm -o backup -backupmethod complete will backup an entire farm
Notes:
When importing a site, the user must be a site collection administrator.
When restoring (and especially moving) an entire farm with new users or to a new domain, Sharepoint will usually not assign correctly the permissions in SQL Server databases to the new service accounts. The user must revise all the Security User assignments in every database related to Sharepoint and add any service accounts that should be db_owner.

Jul 16, 2009

Inheriting permissions in Sharepoint

After having spent several hours reapplying permissions and roles, I have learned the following about Sharepoint permissions in WSS 3.0:
  1. Inheriting permissions and inheriting roles are not the same.
  2. The Sharepoint GUI by default only breaks the permissions inheritance when you select "Edit Permissions" for an object or list.
  3. Removing permissions from a parent site or object with "Remove user permissions" will delete that user's permissions from all child objects, even those that have broken the permission inheritance.
Seems quite unintuitive to me. So be careful removing user permissions from sites or really any object with children.

Here's more detail on the subject:

http://kjellsj.blogspot.com/2008/10/sharepoint-acls-roledefinitions.html

Apr 20, 2009

Error 403 Forbidden and Event ID 1314

We had a Smartpart in Sharepoint that contains a usercontrol which uses the AjaxControlToolkit.dll located in the bin folder. After an IISRESET, normal users couldn't access any page which used this DLL unless an administrator connected to the page first. The Windows Event Viewer would record "An unhandled access exception has occurred" with Event ID 1314 for every failed page view.

I got the solution from this post: http://objectmix.com/sharepoint/298556-users-receive-intermittent-forbidden-errors-event-id-1314-a-3.html

Using "Process Monitor" from Microsoft which logs all file and registry accesses I could see an "Access Denied" event for AjaxControlToolkit.dll.

The two solutions which occured to me were:
1. Give "Authenticated Users" read and execute permissions on the AjaxControlToolkit.dll.
2. Move the AjaxControlToolkit.dll to the GAC.

Hope this helps someone.

Apr 15, 2009

Problem with workflow association

I was getting the following error when trying to associate a custom workflow to a list:

Unable to validate data. at System.Web.Configuration.MachineKeySection.GetDecodedData(Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Int32& dataLength)
at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString)

After many hours of searching and reading, I came across this post: http://stevepietrek.com/2008/02/18/oops-mistake-in-custom-applicationmaster/

So it turns out any changes to the application.master can break certain _layout pages like the association pages for workflows. Microsoft recommends not touching the application.master for good reason, but our client requires complete visual consistency so we have to give it to them. Now I have a simple.master that I apply to problematic _layout pages that can't handle the changes to application.master.

Jan 16, 2009

Como crear una maquina virtual para Sharepoint

La mejor manera de desarrollar para Sharepoint es dentro de una maquina virtual donde puedes jugar y explorar sin causar daño.

Pasos:
  1. Asegurate de tener al menos 60 gigabytes libres en tu disco duro.
  2. Crea una nueva maquina virtual en Virtual PC 2007.
  3. Crea un disco duro virtual de al menos 30 gigabytes. Una instalación básica de Windows Server 2003, Visual Studio 2008, SQLServer 2005 y MOSS 2007 ocupa 20 gigabytes. También haría falta dejar espacio para la importación de una copia de seguridad de tu sitio de producción y luego contar lo que ocupará esto en disco.
  4. Instalar Windows Server 2003, Visual Studio 2008 (sin SQLServer Express) y finalmente SQLServer 2005.
  5. Instala cualquier otro programa de interés como Sharepoint Designer, Infopath y otros.
  6. Instalar los service packs y actualizaciones para todo.
  7. Instalar MOSS en modo Full, pero sin lanzar el asistente de configuración al final.
  8. Instala los service pack, infrastructure updates y hotfix packs para MOSS (siempre sin lanzar el asistente de configuración al final).
  9. Copia la copia de seguridad a una carpeta local y comparta la carpeta en red. (Esto es para luego poder restaurarlo desde el panel de Administración Central de Sharepoint)
  10. Crea los usuarios locales que utilizará para MOSS como MOSS-DB o MOSS-FARM y agregarlos al grupo de Administradores.
  11. En SQLServer Management Studio, dentro de Security -> Logins, añadir MOSS-DB como administrador con todos los permisos de creación.
  12. Añadir "c:\program files\microsoft shared\common files\web extensions\12\bin" al PATH para todos los usuarios en la pestaña avanzada de configuración de Windows.
  13. Crea una acceso rapido en el escritorio de todos los usuarios al "c:\program files\microsoft shared\common files\web extensions\12" en "C:\Documents y Settings\All Users\Escritorio".
  14. Descarga las herramientas de Sysprep que permite sellar la maquina y crear copias limpias sin conflictos en la red.
  15. Editar el commandline.sys para los comandos a ejecutar tras la instalación. Principalmente configurar el MOSS.
  16. Cuando tienes todo listo, apaga la maquina.
  17. Crea una copia entera de este disco duro (Solo se puede sellar un disco 4 veces y asi evitamos afectar la imagen maestra).
  18. Cambia el disco duro de la maquina virtual para apuntar a la copia recien hecho.
  19. Arranca con la copia y lanza la herramienta de Sysprep para limpiar y sellar el disco. Se apagará automaticamente.
  20. Distribuye las copias del disco sellado y cuando el usuario lo arranca, se instalará automaticamente.
Me queda mucho por refinar de esta entrada, pero bueno.

Suerte con este mundo de Sharepoint.