Workflows Inventory Report for SharePoint

Requirement: Get me a SharePoint Workflows Report with the Total No. of workflows wherever it’s running, for our intranet SharePoint site with Site Name, List Name, Workflow Name, and No. of Instances, etc.

Solution: As usual, dive into the object model code (This can be achieved with PowerShell as well). Here it is.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Workflow;
using System.IO;

namespace GetWorkflowReport
{
    class GetWorkflowsReport
    {
        static void Main(string[] args)
        {
            string site;

            try
            {
                if (args.Length == 0)
                {
                    Console.WriteLine("Enter the Web Application URL:");
                    site = Console.ReadLine();
                }
                else
                {
                    site = args[0];
                }

                SPSite tmpRoot = new SPSite(site);
                SPSiteCollection tmpRootColl = tmpRoot.WebApplication.Sites;

                //objects for the CSV file generation
                StreamWriter SW;
                SW = File.AppendText("c:\\WorkflowReport.csv");

                //Write the CSV Header
                SW.WriteLine("Site Collection Name, Site Name, Site URL, List Name, List URL, Workflow Name, Running Instances");

                //Enumerate through each site collection
                foreach (SPSite tmpSite in tmpRootColl)
                {
                    //Enumerate through each sub-site
                    foreach (SPWeb tmpWeb in tmpSite.AllWebs)
                    {
                         //Enumerate through each List
                        foreach (SPList tmpList in tmpWeb.Lists)
                        {
                             
                            //Enumerate through associated workflows
                            foreach(SPWorkflowAssociation tmpSPWorkflowAssociation in tmpList.WorkflowAssociations)
                            {
                               // If you want to Limit to SPD workflows: check tmpSPWorkflowAssociation.BaseTemplate == null
                           //Skip the Previous versons of workflows
                                if(!tmpSPWorkflowAssociation.Name.Contains("Previous Version"))
                                {
                                    
                                //Remove the , in Site Name, document names and write them into the CSV file
                                    SW.WriteLine(tmpSite.RootWeb.Title.Replace(",", " ") + "," + tmpWeb.Title.Replace(",", " ") + "," + tmpWeb.Url + "," + tmpList.Title.Replace(",", " ") + "," + tmpWeb.Url + "/" + tmpList.RootFolder.Url + "," + tmpSPWorkflowAssociation.Name.Replace(",", " ") + "," + tmpSPWorkflowAssociation.RunningInstances);
                                }

                            }
                        }
                    }
                     
                                                      
                }

                //Close the CSV file object 
                SW.Close();
                //Dispose of the Root Site Object
                tmpRoot.Dispose();
                Console.WriteLine(@"Report Generated Successfull at c:\WorkflowReport.csv. Press ""Enter"" key to Exit");

                //Just to Pause
                Console.ReadLine();
            }

            catch (Exception ex)
            {
                //Log the exception to event log
                System.Diagnostics.EventLog.WriteEntry("Get Workflow Report", ex.Message);
            }
        }
    }
}

and the output goes like this:

Workflow Report for Completed, In Progress, Terminated, and Cancelled:

This time the requirement is: Get me the workflows for all the lists and Libraries with No. of workflows completed, In Progress, Terminated, Cancelled.

Alright, I changed the code slightly:

class GetWorkflowsReport
    {
        static void Main(string[] args)
        {
            string site;

            try
            {
                if (args.Length == 0)
                {
                    Console.WriteLine("Enter the Web Application URL:");
                    site = Console.ReadLine();
                }
                else
                {
                    site = args[0];
                }

                SPSite tmpRoot = new SPSite(site);
                SPSiteCollection tmpRootColl = tmpRoot.WebApplication.Sites;

                //objects for the CSV file generation
                StreamWriter SW;
                SW = File.AppendText("c:\\WorkflowReportEx.csv");

                //Write the CSV Header
                SW.WriteLine("Site Collection Name, Site Name, Site URL, List Name, List URL,  Cancelled,Completed, Faulting,Running,Terminated");

                //Enumerate through each site collection
                foreach (SPSite tmpSite in tmpRootColl)
                {
                    //Enumerate through each sub-site
                    foreach (SPWeb tmpWeb in tmpSite.AllWebs)
                    {
                         //Enumerate through each List
                        foreach (SPList tmpList in tmpWeb.Lists)
                        {
                            //Initialise the variables
                            int Cancelled=0;
                            int Completed=0;
                            int Faulting=0;
                            int Running=0;
                            int Terminated=0;

                            if (tmpList.WorkflowAssociations.Count > 0)  //IF the List has any workflows associated
                            {
                                foreach (SPListItem oSPListItem in tmpList.Items)
                                {
                                    foreach (SPWorkflow oSPWorkflow in oSPListItem.Workflows)
                                    {
                                        //Get the state of the workflow, Whether completed, Terminated, etc
                                        switch (oSPWorkflow.InternalState)
                                        {
                                            case SPWorkflowState.Cancelled:
                                                Cancelled++; ;
                                                break;

                                            case SPWorkflowState.Completed:
                                                Completed++;
                                                break;

                                            case SPWorkflowState.Faulting:
                                                Faulting++;
                                                break;

                                            case SPWorkflowState.Running:
                                                Running++;
                                                break;

                                            case SPWorkflowState.Terminated:
                                                Terminated++;
                                                break;
                                        }
                                   }
                            }
                                //Remove the , in Site Name, etc and write them into the CSV file
                                SW.WriteLine(tmpSite.RootWeb.Title.Replace(",", " ") + "," + tmpWeb.Title.Replace(",", " ") + "," + tmpWeb.Url + "," + tmpList.Title.Replace(",", " ") + "," + tmpWeb.Url + "/" + tmpList.RootFolder.Url + "," +Cancelled + ","  +Completed+ "," + Faulting + ","  + Running+ "," +Terminated);
                            }
                        }
                      }
                    }

                //Close the CSV file object 
                SW.Close();
                //Dispose of the Root Site Object
                tmpRoot.Dispose();
                Console.WriteLine(@"Report Generated Successfully at c:\WorkflowReportEx.csv. Press ""Enter"" key to Exit");

                //Just to Pause
                Console.ReadLine();
            }

            catch (Exception ex)
            {
                //Log the exception to event log
                System.Diagnostics.EventLog.WriteEntry("Get Workflow Report Extended", ex.Message);
            }
        }

and the output :

Salaudeen Rajack

Salaudeen Rajack - Information Technology Expert with Two-decades of hands-on experience, specializing in SharePoint, PowerShell, Microsoft 365, and related products. He has held various positions including SharePoint Architect, Administrator, Developer and consultant, has helped many organizations to implement and optimize SharePoint solutions. Known for his deep technical expertise, He's passionate about sharing the knowledge and insights to help others, through the real-world articles!

5 thoughts on “Workflows Inventory Report for SharePoint

  • Excellent piece of work !!

    Reply
  • nice one….its very helpfull to me

    Reply
  • nice one rajack….its very help full to me.

    Reply
  • Nice work, just one query about the second report

    it is gathering information for the last time each workflow was run against each item, is it possible to get information about everytime a workflow is run against each item? not just the last instance of the workflow an item?

    Reply
    • If you looking for the Workflow’s track on a particular item, you can Get it from Workflow History lists. This lists keeps the track of all the workflow instances with its details.

      Even the Workflow clean up timer job, just dis-associates the History item from the list and not actually deletes it.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *