Wednesday, April 22, 2015

Timer Job to Start the workflow in a list

Recently, I had an interesting requirement. No of list contains items and they expire on certain dates and require to send reminders for each items.  Initially I thought to write a custom workflow and kick the workflow by the OOB expiration policy/information policy. However information policy check dates are above the specified date. Example: anything more than 7 years.  So if you set the workflow to kick, it’s going to kick again and again for any items which are more than 7 years. Especially you won’t prefer to send email more than once. So I come up with a timer job for that.
The timer job will read a central list, which has details of list that need to run the expire workflow, and then kick the workflow.
Here is the sample of that list.


Then I create a timer job.
Here is the code for that.

namespace SP.Sample.OnlineForms
{
    using System;
    using System.Collections.Generic;
    using System.Web;
    using Microsoft.SharePoint.Administration;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Workflow;
    using Microsoft.SharePoint.WorkflowUtil;
    using Microsoft.SharePoint.Utilities;
    using System.Security.Permissions;
    using System.Text;
    using System.Collections.Specialized;

    public class SampleExpireAlertsTimerJob : SPJobDefinition
    {
        //SPWeb mySiteWeb;

        public SampleExpireAlertsTimerJob(SPWebApplication webApp)
            : base("Sample Expire Alerts", webApp, null, SPJobLockType.Job)
        {
            this.Title = "Sample Expire Alerts";
        }
        public SampleExpireAlertsTimerJob()
            : base()
        {
        }
        public override void Execute(Guid targetInstanceId)
        {
            string key = "TeamsRootSiteUrl";
            string TeamsRootSiteUrl = "";
            if (this.Properties.Contains(key))
            {
                TeamsRootSiteUrl = this.Properties[key].ToString();
               
            }

            if (!string.IsNullOrEmpty(TeamsRootSiteUrl))
            {

               

                using (SPSite site = new SPSite(TeamsRootSiteUrl))
                {
                    using (SPWeb web = site.RootWeb)
                    {
                        SPList list = web.Lists.TryGetList("SampleExpireAlerts");
                        SPQuery oQuery = new SPQuery();

                        oQuery.Query = string.Format(@"
                                                <OrderBy><FieldRef Name='ID' /></OrderBy>"
                                              );
                        SPListItemCollection collListItems = list.GetItems(oQuery);

                        foreach (SPListItem item in collListItems)
                        {
                            string weburl = item["WebURL"] as string;
                            string listName = item["ListName"] as string;
                            string dateFieldtoFilter = item["DateFieldtoFilter"] as string;
                            int daysToFilter = int.Parse(item["DaysToFilter"] as string);
                            string workflowName = item["WorkflowName"] as string;

                            StartAlertWorkFlow(weburl, listName, dateFieldtoFilter, daysToFilter, workflowName);

                        }
                    }
                }
            }
        }

        /// <summary>
        /// Send remainder and warning emails to the employees
        /// </summary>
        /// <param name="employeeName">Name of the employee ex: Sutha Thavaratnarajah</param>
        /// <param name="moduleName">Name of the module ex: conduct</param>
        /// <param name="TeamsRootSiteUrl"> Url retrived from the timer job property.</param>
        /// <param name="eid">email template ID.</param>
        public void StartAlertWorkFlow(string weburl, string listName, string dateFieldtoFilter, int daysToFilter, string workflowName)
        {
            using (SPSite SampleSite = new SPSite(weburl))
            {
                using (SPWeb SampleWeb = SampleSite.OpenWeb())
                {

                    SPList list = SampleWeb.Lists.TryGetList(listName);
                    SPQuery oQuery = new SPQuery();
                    //string userName = "Sutha Thavaratnarajah";
                    string datetofilter = System.DateTime.Today.AddDays(daysToFilter).ToString("yyyy-MM-dd");

                    oQuery.Query = string.Format(@"
                                                    <Where>
                                                      <Eq>
                                                         <FieldRef Name='{0}' />
                                                         <Value IncludeTimeValue='False' Type='DateTime'>{1}</Value>
                                                      </Eq>
                                                   </Where>", dateFieldtoFilter, datetofilter);
                    SPListItemCollection collListItems = list.GetItems(oQuery);
                    foreach (SPListItem item in collListItems)
                    {

                        item.Web.AllowUnsafeUpdates = true;
                        SPWorkflowManager workflowManager = item.Web.Site.WorkflowManager;
                        SPWorkflowAssociationCollection workflowAssociation = item.ContentType.WorkflowAssociations;
                        foreach (SPWorkflowAssociation Association in workflowAssociation)
                        {
                            if (Association.Name == workflowName)
                            {
                                workflowManager.StartWorkflow(item, Association, Association.AssociationData, true);
                                break;
                            }
                        }

                   

                    }
                  
                }
            }
        }
    }
}

So, this timer job will kick the specified workflow in specified List with the given criteria.


Note: you need to create the workflow in the target lists.

Thursday, January 8, 2015

Save site as template -SharePoint 2013

A small script to save as template for SharePoint 2013 sites. This script also handle publishing feature enabled sites. I wrote this script to save some time. Instead of click few places , just run the script. :)


param(
    [string] $url = $(throw "No URL! Usage: Save-SP13Template.ps1 [webURL] [FileName]"),
[string] $templateName = $(throw "No Template Name! Usage: Save-SP13Template.ps1 [webURL] [TemplateName]")
)

#-------------------------------------------------------------


Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
function Save-SiteTemplate {

$Web=Get-SPWeb $url
$Web.SaveSiteAsTemplateEnabled = $true
$Web.Update()
$fileName =$templateName +".wsp"
$Web.SaveAsTemplate($fileName,$templateName,"Template Description",1)
}

Save-SiteTemplate

Office Integration with SharePoint 2010 in a virtualized environment




1 Office Integration required settings.

Office integration with SharePoint in a virtualized environment required few settings in the client computer. The settings natively configured by the office product such as MS word and excel. However, in a virtualized environment it may not exactly configured as in a normal client computer. Following settings can be verified if any issue with your office integration.

1.1 MS Office Trusted location

In office products such as word and excel, add the trusted locations.

http://*.yourcompany.com
https://*.yourcompany.com

1.2 AuthForwardServerList.

Set the SharePoint URLs to AuthForwardServerList.

1. Using RegEdit, navigate to the following key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WebClient\Parameters
2. Add a New Multi-String Vlaue (Edit > New).
3. Name it AuthForwardServerList and press Enter.
4. Set the value (Edit > Modify) to your FQDN. Or you can do something more comprehensive like http://*.yourcompany.com
https://*.yourcompany.com

1.3 Portal URL
This may change depend on the office version/Windows Client you are using. Pls translate to equivalent for the client windows OS and office suite.
HKEY_CURRENT_USER\Software\AppDataLow\Microsoft\Office\14.0\Common\Portal


1.4 SharePoint Shortcuts
SharePoint Shortcuts store in following location.
C:\Users\%user% \SharePoint Sites
Ex: C:\Users\sutha.thavaratnaraja\SharePoint Sites
If you use a virtualized (ex citirx) the profile location similar to this except “C:\users”
1.5 Outlook .pst File locaiton
Sharepoint .pst files store in following location.
C:\Users\%user% \AppData\Local\Microsoft\Outlook
Example:
C:\Users\myFirstName.LastName \AppData\Local\Microsoft\Outlook


We may need to configure the virtual environment to giving similar mechanism to store this file, so that outlook can connect SharePoint.