Delete an Orphaned Workflow in Sharepoint 2010

In this article we explore a real-world scenario where a workflow is sending a reminder email to users and the interesting thing is that the task list & data no longer exist.

I have encountered such scenarios many times in my consulting experience and I would recommend running the latest cumulative updates to resolve the issue. In cases where the update patching is not feasible you can use the following solution approach.

Understanding the Problem

To ensure the problem is being conveyed correctly I am using the following points:

  1. Task List named Approval List was created
  2. A new item was added to the Task List
  3. An Approver is being notified on the task
  4. The Task List was deleted, removed from Recycle Bin too
  5. The notification mail is being sent every week
  6. The user cannot modify the task or approve it to stop the emails

This case can occur due to an incomplete migration where the relational columns are mismatched. Our focus is to fix the problem so that our user is not being disturbed by obsolete or invalid emails.

Examining the Problem

As the first step you can try to impersonate the user in the SharePoint web application. If you cannot access the user credentials you can try examining the SharePoint content database. The content database contains the list, list records, user, work flow information for a SharePoint web application.

You can get the content database name of the web application from Central Administration.

WrkShr1.jpg

You will see the content database name from the page that appears. Ensure that you are referring to the right web application.

WrkShr2.jpg

You can click on the Database Name link to see more information about like Server Name.

WrkShr3.jpg

Now you can try logging in to the database using SQL Server Management. The following are our tables of interest. (Here we are examining List Workflows)

Table

Description

AllLists

This table contains the list metadata like Title, Description etc.

AllUserData

This table contains the user data like list item.

Workflow

This table contains the workflow instances.

Please note that there are no referential constraints but GUID values are used to interconnect between tables. The following are the table structures:

WrkShr4.jpg

Note: Modification to the table using SQL / Direct Editing is restricted by Microsoft. You should use the Server Object Model for any modifications.

Proposed Solution

The advisable solution is to terminate the workflow using the SharePoint user interface.

To do this open Lists > Site Workflows link.

WrkShr5.jpg

Click on the highlighted link as shown above. You should get the following Workflow Information page.

WrkShr6.jpg

Click on the Terminate this workflow now link as shown above.

If the workflow gets terminated then you are good. Your customer should be happy as he will be free from the erroneous email alert.

You can verify the database record to ensure the InternalStatus column is set to 8.

WrkShr7.jpg

The enumeration of the Internal State column mapping to SPWorkflowState is given below:

WrkShr8.jpg

Extended Proposed Solution

This solution involves much more effort and is advisable if the User or Administrator is not able to perform the preceding. You can write a piece of code to fetch the workflows in a running state and cancel it using the Server Object Model.

Step 1

Create a new windows application

Create a new Windows application and make the .Net version to 3.5, Platform Target to Any CPU. Add 1 TextBox, 2 Button and 1 ListBox as shown below:

WrkShr9.jpg

Step 2

List the Workflow Instances

On the Find Running Workflow button click event invoke the following method which lists all the Workflow Instances.

private void RefreshList()

{

    using (SPSite site = new SPSite(UrlText.Text))

    {

        using (SPWeb web = site.OpenWeb())

        {

            List.Items.Clear();

            _internalList = new List<SPWorkflow>();

 

            foreach (SPWorkflow workflow in web.Workflows)

            {

                List.Items.Add(workflow.AuthorUser.LoginName + " " + workflow.InternalState.ToString() + " " + workflow.Created.ToShortDateString() + " " + workflow.StatusUrl);

                _internalList.Add(workflow);

            }

        }

    }

}

 

private IList<SPWorkflow> _internalList;

Note: Please note that periodically the Workflow table is cleared of the completed workflows by a Timer Job.

Step 3

Terminate the Workflow

For terminating the Workflow use the following code.:
 

private void TerminateButton_Click(object sender, EventArgs e)

{

    if (List.SelectedIndex >= 0)

    {

        if (MessageBox.Show("Are you sure to Terminate this Workflow?", "Confirm", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)

        {

            SPWorkflow workflow = _internalList[List.SelectedIndex];

 

            SPWorkflowManager.CancelWorkflow(workflow);

 

            RefreshList();

 

            MessageBox.Show("Terminated.. The list will be refreshed after Timer Job removes the workflow entry!");

        }

    }

}


Note: Here we are using the SPWorkflowManager class to terminate the workflow. The CancelWorkflow() is the method used to perform it. After cancelling, the item will be removed by a timer job. 

Step 4

Execute the Application

On executing the application you will see all the workflows listed. Selecting the appropriate workflow and clicking the Terminate button should set the Workflow Internal State to Cancelled. From this point onwards the obsolete email problem will be gone.

WrkShr10.jpg

Note: Currently the workflow author, date and URL information are added in the list. You are free to add additional information about the workflow in the list.

References

http://tinyurl.com/sp2010-wf-terminate

Summary

In this article we have explored a possible problem associated with obsolete task emails workflow and the solutions for it.

I would like to emphasize that the Microsoft recommended solution is to use the Server Object Model or Client Object Model to make the database changes rather than using SQL statements directly on the content database.

The source code for the article is attached.