SharePoint Dragons

Nikander & Margriet on SharePoint

How to create an OfficeDev PnP Provisioning engine extensibility provider

The OfficeDev PNP provisioning engine (https://github.com/officedev/pnp-sites-core) is able to create an XML template based on a given SharePoint site and then use that XML template to create new sites. Ootb, the provisioning engine contains a considerable amount of stuff it can do as detailed in the PNP provisioning schema (https://github.com/OfficeDev/PnP-Provisioning-Schema/blob/master/ProvisioningSchema-2015-12.md). The provisioning engine allows you to define extension points that allow you to add custom steps to the provisioning process, and in this article we’ll explain how to do it. 

First of all, it’s quite possible to get the OfficeDevPNPCore15 (for SharePoint 2013 on prem) or OfficeDevPNPCore16 (for SharePoint Online) NuGet packages and use the provisioning engine like that. We’ve found that there’s tremendous value in being able to step through and debug source code, so unless you’ve got a tool that allows you to debug 3rd party assemblies on the fly within Visual Studio we far more prefer to add the OfficeDevPnP.Core project itself to our own provisioning tool and add a project reference to it so we have access to all source code. You can either obtain the source code by creating a project based on OfficeDevPnP.Core.dll (for example, via Telerik JustDecompile at http://www.telerik.com/products/decompiler.aspx) or get it directly by cloning it from the GitHub repository. This allows you to get much needed insights into the inner workings of the provisioning engine.

When building an extensibility provider, we’ve used 2 sources:

– The succinct article at http://www.erwinmcm.com/using-an-extensibility-provider-with-the-pnp-provisioning-engine/

– The PNP provisioning schema at https://github.com/OfficeDev/PnP-Provisioning-Schema/blob/master/ProvisioningSchema-2015-12.md

The process of building an extensibility process goes like this:

1. Create a custom provider class that implements the IProvisioningExtensibilityProvider.

2. Add a custom provider section to the XML template.

3. Implement the logic of the custom provider.

The C# code of a custom provider class looks like this:

using OfficeDevPnP.Core.Framework.Provisioning.Extensibility;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using Microsoft.SharePoint.Client;

using OfficeDevPnP.Core.Framework.Provisioning.Model;

using System.Xml.Linq;

namespace MyTest.Providers

{        

    public class CustomProvider : IProvisioningExtensibilityProvider

    {

        public void ProcessRequest(ClientContext ctx, ProvisioningTemplate template, string configurationData)

        {

        }

    }

}

Then, you need to adjust the XML generated by the provisioning engine and, if it’s not already there, add a custom <pnp:Providers> section. The <pnp:Providers> section needs to be placed within the <pnp:ProvisioningTemplate> section, and although the exact position doesn’t really seem to matter we place it pretty close to the end of the <pnp:ProvisioningTemplate> section. The <pnp:Providers> needs two attributes:

– Enabled, this is true or false and allows you to temporarily disable a custom provider.

– HandlerType, which expects the FQDN of the code that will be executed once the provisioning engine comes across this XML. It expects the following info: {Namespace + class name of extensibility provider}, {Assembly name}, {Version}, {Public key token, if the assembly is strong named}.

Within the <pnp:Providers> section, you can place anything you like as long as it’s valid XML. The following XML fragment is a minimal provisioning template that just creates a web property bag entry and executes a custom extensibility provider: 

<?xml version=”1.0″?>

<pnp:Provisioning xmlns:pnp=”http://schemas.dev.office.com/PnP/2015/12/ProvisioningSchema“>

  <pnp:Preferences Generator=”OfficeDevPnP.Core, Version=2.2.1603.0, Culture=neutral, PublicKeyToken=3751622786b357c2″ />

  <pnp:Templates ID=”CONTAINER-TEMPLATE-[GUID]”>

    <pnp:ProvisioningTemplate ID=”TEMPLATE-[GUID]” Version=”1″>            

      <pnp:Providers>

        <pnp:Provider Enabled=”true” HandlerType=”MyTest.Providers.CustomProvider, MyTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”>

          <pnp:Configuration>

            <MyProviderConfiguration id=”SampleConfig” xmlns=”http://schemas.loisandclark.eu/MyProviderConfiguration“>

              <ChildNode Attribute=”value”>TextContent</ChildNode>

            </MyProviderConfiguration>

          </pnp:Configuration>

        </pnp:Provider>

      </pnp:Providers>

      <pnp:PropertyBagEntries>

<pnp:PropertyBagEntry Key=”lois” Value=”clark” Overwrite=”true” />

      </pnp:PropertyBagEntries>  

    </pnp:ProvisioningTemplate>

  </pnp:Templates>    

</pnp:Provisioning>

You can’t exert fine grained control over the exact execution point in the provisioning pipeline, but all extensibility providers are executed sequentially and almost at the end of the provisioning pipeline. Currently, only WebSettings (containing settings for the current web site such as a SiteLogo and Master page URL, see https://github.com/OfficeDev/PnP-Provisioning-Schema/blob/master/ProvisioningSchema-2015-12.md#websettings) and PersistTemplateInfo (info about the provisioning template that gets persisted in a web property bag entry) are executed after your extensibility providers.

So what’s left to do is provide an implementation that of the ProcessRequest() method of the extensibility provider. It gets passed the SharePoint context and gets access to the XML in the custom <pnp:Provider> section. Your code will have to process that config info and use the current web to do something useful. The following code is a valid implementation:

using OfficeDevPnP.Core.Framework.Provisioning.Extensibility;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using Microsoft.SharePoint.Client;

using OfficeDevPnP.Core.Framework.Provisioning.Model;

using System.Xml.Linq;

namespace MyTest.Providers

{        

    public class CustomProvider : IProvisioningExtensibilityProvider

    {

        public void ProcessRequest(ClientContext ctx, ProvisioningTemplate template, string configurationData)

        {

            ClientContext clientContext = ctx;

            Web web = ctx.Web;

            string configurationXml = configurationData;

            XNamespace ns = “http://schemas.somecompany.com/MyProviderConfiguration“;

            XDocument doc = XDocument.Parse(configurationXml);

            string id = doc.Root.Attribute(“id”).Value;

            var childNode = doc.Root.Descendants(ns + “ChildNode”).FirstOrDefault();

            if (childNode != null)

            {

                string innerValue = childNode.Value;

                string attr = childNode.Attribute(“Attribute”).Value;

            }

        }

    }

}

Concluding, this means the extension points in the provisioning process aren’t exactly great, but it’s easy to do and at least you get the correct SharePoint context for free and have the opportunity to store all config info in a single place.

Bug in January 2016 CU for SharePoint 2013: adjusting external links in site pages

There’s a bug in the January 2016 CU where the CU erroneously updates external links. On a site page, we have a link to an external JavaScript library placed on a CDN like this:

· //cdn.ourcompany.com/js/jquery/jquery.js

After the CU is done “fixing” it, this link has become an internal one:

· /js/jquery/jquery.js

Because of that, the page no longer is able to find the javascript file and the page fails. Links explicitly including the protocol are not molested in this way, so http//cdn.ourcompany.com/js/jquery/jquery.js remains http//cdn.ourcompany.com/js/jquery/jquery.js after CU installation. Let’s hope this bug is fixed in future updates, since we really want to leave out explicit protocols (like so: //cdn.ourcompany.com/js/jquery/jquery.js). We also would like the CU not to try to be too smart and stay away of the contents of our site pages. Btw, it also seems that the CU doesn’t touch similar references in page layouts.

SharePoint Debugging: Not without a trace

We’re always quite interested to see how other peoply try to solve SharePoint issues and thought it would be interesting to share a recent experience with MS support. In a case were list items got corrupted after a migration, MS support was interested in the following:

– An HTTP trace retrieved via Fiddler taken while the issue is reproduced via the browser.

– Relevant ULS log files.

– A memory dump of the SharePoint process retrieved via tttracer taken while the issue is reproduced.

To us, the latter choice is the most interesting one. Tttracer.exe refers to the Microsoft Time Tracel Tracing Tool (see http://www.thewindowsclub.com/microsoft-time-travel-tracing-diagnostic) and is a diagnostic tool that captures trace info and extends the WinDbg tool to load such trace files for further analysis. Tttracer allows you to select a specific process (or more) on your computer and collects info about it. At a later time, MS support is able to use such trace files and go back and forth in time to diagnose SharePoint processes before, during, and after issues.

Unfortunately, tttracer is not available outside Microsoft so of no immediate use to us. However, there were some steps in the trace capturing process that are good practices to follow anyway, such as:

1. If you’re interested in doing a memory dump, isolate a WFE that will be used for testing the issue.

2. If you’re interested in doing a memory dump, edit the host file on that WFE to ensure all SharePoint URL calls are directed to the WFE, and not to a load balancer.

3. Set ULS logging to verbose and put that info in a separate log file (via Set-SPLogLevel -TraceSeverity VerboseEx -EventSeverty Verbose and New-SPLogFile).

4. Reset IIS.

5. Reproduce the issue.

6. If you’re interested in doing a memory dump, find the process id of the application pool that hosts the SharePoint site where the issue occurs (by executing “%windir%\system32\inetsrv\appcmd list wps” on a command prompt).

8. Reproduce the issue.

9. Analyze all the info you retrieved.

We suspect your own troubleshooting may not be that different, and most likely will be more extensive than this, but for sure it won’t hurt to compare notes!

Profiling SharePoint databases

Of course messing with SharePoint databases is not supported but we’ve found there are times when we do want to take a closer look at SharePoint databases and see where certain information is stored or how long an operation takes at the database level. As we don’t do this that often, we thought it would be convenient to document the procedure for profiling SharePoint databases and also thought the write-up could be helpful for others.

Follow this procedure to start profiling databases:

1. Start SQL Server Profiler directly or via SQL Server Management Studio and then choose Tools > SQL Server Profiler.

2. Click File > New Trace. This opens the Connect to Server dialog window.

3. Enter the server name of the SharePoint database server or instance that you want to profile.

4. Click Connect.

5. This opens the Trace Properties dialog window.

6. Enter a valid Trace name.

7. In the Use the template drop down list, choose TSQL_Duration. This template is especially good for finding how long it takes to run SQL queries and stored procedures.

8. Click the Events Selection tab.

9. Select the Show all columns checkbox.

10. Check the DatabaseName column for both Stored Procedures and TSQL.

11. If you don’t know the exact name of the database(s) you want to profile, click Run.

Perform the UI actions that you want to investigate further, and click the Pause Selected Trace button. This gives you the chance to identify the names of the databases you’re interested in. Now that you’ve established that, you’re ready add a filter to profile only the databases you’re interested in and no more. This is a necessary step as the number of queries that are executed on a SharePoint database server are quite overwhelming. Typically, but not always, you’ll be most interested in the SP_Content_* databases.

Now follow the next procedure to add some filters:

1. Click the Clear Trace Window button.

2. Click File > Properties.

3. Click the Events Selection tab.

4. Click Column Filters. This opens the Edit Filter dialog window.

5. Select DatabaseName.

6. Click Like.

7. Enter the desired database name, e.g. %Content%.

8. Click Run.

Now you have a better chance to find out what’s taking so long and where specific information is stored.

Coding for kids

Margriet wrote an interesting blog post about getting kids in contact with programming. You can read more about it over here. In the Netherlands, there’s the option to join codeuur, in English, the article discusses a lot more options.

Browser chart site

Everybody needs a browser charting site to look up if a certain CSS, JavaScript or HTML 5 feature is supported or not, because it will save tons of time. We kinda like this one: http://caniuse.com/ It allows you to check if a feature is supported in a heartbeat, it allows you to compare multiple browsers and versions with each other, and it shows insights into usage info for your country!

A case of "easy": Virto SharePoint Bulk Operations Toolkit

Recently, we took a look at Virto’s SharePoint 2013 workflow activities kit and we were happy with what we saw. As a result, we also decided to take a lok at another Virto product, the Virto Bulk Operations Toolkit. This is a bundle of 8 components that all do something useful with bulk operations and is shipped with a nice bulk bundle price saving you over 40%. This is a feature-packed bundle that is definitely capable to handle some of the questions we or our customers have been struggling with. And, oh yeah, it comes with comprehensive and extensive documentation.

Let’s take a look at the 8 components.

1. Bulk Check In and Approve
As the name implies, this component is for SharePoint multiple files checkin and SharePoint multiple files approval. It allows end users to check in bulk groups of documents and has features such as adding comments to the bulk whilst doing a check-in, publishing or drafting versions if

approval is enabled, or doing bulk discards of multiple checked-out files. The user interface for doing this is a lot easier then what SharePoint is offering ootb. The next Figure shows an example (all pictures are taken with permission of Virto):

clip_image002

Bulk Check In and Approve has a comprehensive set of features such as:

  • Search support for check in and approve actions.
  • CAML query support for check in and approve actions.
  • Menus that are aware of current user permissions.
  • Default view type setting.
  • Ability to check-in documents in folders and subfolders.
  • Bulk discard of files.
  • Bulk check-in and approve capabilities.

2. Bulk Data Edit Web Part
This is a component for SharePoint multiple files editing. This is a request we’ve heard time and time again (although you have to be careful with this!): the possibility to do SharePoint bulk edit. In other words, to edit the same metadata field for a bulk of list items. This enables end users to specify metadata for a bulk of items in 1 go (supported in all types of lists and libraries)! The ootb datasheet view alleviates the problem somewhat, but it is nowhere near as easy to use as this component. See the following screenshot to get an impression.

clip_image004

The Bulk Data Edit Web Part has a comprehensive set of features such as:

  • Ability to create new terms.
  • Search support for edit scenarios.
  • CAML query support for edit scenarios.
  • Taxonomy options.
  • Bulk edit for list or site scopes.
  • Editing data of the same field for a group of list items.

3. Bulk File Copy and Move
This is a component for SharePoint multiple file copy and move. The copying (or more often: moving) of large amounts of list items and/or documents is usually something that end users request of administrators, who usually use a high-end migration tool to do the heavy lifting. This component is great in that it places the power of moving larger amounts of misplaced documents/list items in the hands of end users in the form of a separate web part or an additional action in the Action menu. Also check out the Figure below.

clip_image006

Bulk File Copy and Move has features such as:

  • Support for search for copy & move operations.
  • Support for CAML queries for copy & move operations.
  • Filtering possibilities for copy & move operations.
  • Support for using the same SharePoint views as in source libraries.

4. Bulk File Delete Web Part
This is a component fo SharePoint multiple file deletion. This is also a special one. As you would expect, it can delete multiple list items/documents from any type of list. But this component goes a significant step further in that it allows you to specify which

groups of items to delete via an advanced filtering mechanism (that allows you to delete by view, CAML queries, searches, etc). The Figure below shows an example of search support in deletion scenarios:

clip_image008

The Bulk File Delete Web Part has features such as:

  • Search support when deleting files.
  • CAML support when deleting files.
  • Flexible max amount of files that are displayed.
  • Filtering possibilities during file deletion.

5. Bulk File Download Web Part
This is a component for SharePoint multiple files download. This component allows end users to download files from a library and store it locally in a single .zip file. Again, it’s easy to select which files must be downloaded. This component has been around since 2007 and was probably more important then than it is now with all the offline capabilities of SharePoint, although we have seen a customer that periodically bundled documentation that was shipped to external partners, in which case this component would have been quite useful. It also works nice in combination with component nr. 6, the Bulk File Unzip Utility. Currently, we’re exploring these components to quickly fill some sites with relevant test data which seems to work out quite nicely. The next Figure nicely demonstrates what this web part looks like:

clip_image010

The Bulk File Download Web Part has a comprehensive set of features such as:

  • Extensive logging during download.
  • Automatic JavaScript minification.
  • Support for large files.
  • Support for async operations.
  • Choosing specific files for downloading.
  • Download a bulk of files in a single archive.

6. Bulk File Unzip Utility

This is a component for SharePoint multiple files unzipping. This component unpacks zip archives to document libraries, retaining the original structure. For end users migrating to SharePoint from another system, this can be extremely useful. This allows end users to pack their documents, stuff them in SharePoint, and then use the Bulk File Copy and Move and Bulk Data Edit Web Parts to get the documents organized! This is a nice example how the separate components within the bundle seem to enhance each other. The next Figure shows how easy it is: select an archive and click the Unpack button!

clip_image012

The Bulk File Unzip Utility has features such as:

  • Unpacking archives to SharePoint document libraries.
  • Preserving folder structures after unpacking.
  • Ability to retain original file creation/modification datetime! This is a really cool feature which can be very important in certain legal situations.
  • Auto-deletion of archives aftyer unpacking.
  • Unzip settings are scoped at either the library or site level.

7. Bulk File Upload Web Part
This is a component for SharePoint multiple files upload. In the past, we’ve written stuff about uploading bulk files to SharePoint and even have written our own little tool to do it. The bottom line always consists of the following points:

  • The standard SharePoint tools for uploading files in bulks to SharePoint are not advanced and reliable enough.
  • There are community tools that are better, but offer very limited support which is commonly not acceptable in enterprise scenarios.
  • There are high-end migration tools that do a great job at a great cost.

The Bulk File Upload Web Part has a comprehensive set of features such as:

  • Possibility to add field descriptions.
  • Show overwrite option.
  • The possibility to redirect all requests to the standard upload page to the Virto Bulk Upload (via an HTTP module).
  • Support for Content Organizer rules.
  • Possibility to resize jpeg images during upload.
  • Current user defaults for property values.
  • Maximum file size settings.
  • Allowed file type settings.
  • Upload of large files.
  • Partial uploading of operation is cancelled.

It seems that Virto fills a very nice niche here by offering a professional and supported solution at a very reasonable price (at least, that’s what we think). The next Figure shows an impression.

clip_image014

8. HTML 5 Bulk File Upload
Last but not least, this is a component for SharePoint multiple files upload. This component is a nice enhancement to the Bulk File Upload Web Part and is completely written in HTML 5. It is very similar to the Bulk File Upload Web Part except that it’s even better! This component is probably our favorite in the bundle. The next Figure shows what it looks like.

clip_image016

HTML 5 Bulk File Upload has features such as:

  • Uploading of bulk files.
  • Support for custom metadata.
  • Support for uploading files via drag-n-drop leveraging just HTML 5.
  • Ability to overwrite files during upload.
  • Display of file upload progress bar.
  • Restriction of file types that can be selected.
  • Limiting the max file upload size.
  • Support for unlimited amounts of content types and fields.
  • And, as all of Virto’s components, cross browser support for MSIE, FireFox, Chrome and Opera.

So if any of the features of the Virto Bulk Operations toolkit appeal to you, we won’t try to stop you checking it out at http://www.virtosoftware.com/bundles/virto-bulk-operations-toolkit.

jQuery Caret Plugin

Let’s give a positive endorsement for the jQuery Caret Plugin which can be found at https://github.com/acdvorak/jquery.caret This library allowed us to find the current cursor position in a text area with code like this:

targetElement = $(“#myID”);
var currentCursorPosition = targetElement.caret();

Contrary to the other solutions we’ve tried, this one also worked flawlessly in MSIE 8!

Quick link title strangeness in SharePoint 2013: wrong Title value

There is some strangeness surrounding the retrieval of quick launch links in SharePoint 2013 which may very well be a bug in SharePoint. Although we’re the first ones to admit we haven’t been let in on the exact reasoning behind SharePoint’s implementation of the quick launch title, and there may be very good reasoning behind it, we’re inclined to believe that this is another area where multi-language scenarios have been implemented sloppily in SharePoint 2013. In this article we discuss what the problem is and, better yet, how to solve it.

In principle, retrieving the link title of a quick link is easy. The next C# code uses the server-side OM to retrieve the title of every first link of every web site in a site collection.

string siteUrl = “[site collection URL]”;
using (var site = new SPSite(siteUrl))
{
    foreach (SPWeb web in site.AllWebs)
    {
        string title = web.Navigation.QuickLaunch[0].Title;
    }
}

There are situations when the Title does not contain the value you’d expect. There are 2 preconditions that need to be met to experience this strangeness (there may be more scenarios causing it, but we’re describing the one we’ve encountered):

  • We’re editing the default first link of a new team site.
  • The locale of the thread running the code is different from the default language of the SharePoint web site.

To clarify, let’s present an example that runs as expected, then followed by the example that does not behave as we expect.

Example 1: Expected Title

  1. Create a new team site and choose language “English”.
  2. Go to the Navigation link (so the Publishing features need to be enabled in order to do this) and edit the first link and change it’s title to “Test”. Do not change the URL!
  3. Run the code and verify that web.Navigation.QuickLaunch[0].Title indeed returns the value of “Test”, the same value as seen via the UI in the quick launch bar.

Example 2: Unexpected Title

  1. Create a new team site and choose language “Dutch” (or some other language as long as its not English).
  2. Go to the Navigation link (so the Publishing features need to be enabled in order to do this) and edit the first link and change it’s title to “Test”. Do not change the URL as this will ensure the Title functionality to function correctly!
  3. Run the code and verify that web.Navigation.QuickLaunch[0].Title does not return the value of “Test”, but instead returns “Home”, even when the quick launch bar itself displays the link title “Test” correctly.

Inspecting the implementation of the Title property in the Microsoft.SharePoint.Navigation.SPNavigationNode class sheds some light on this issue:

public string Title
{
    get
    {
        if (System.Globalization.CultureInfo.CurrentUICulture.LCID == this.Navigation.Web.UICulture.LCID)
        {
            return this.m_strTitle;
        }
        return this.TitleResource.Value;
    }
}

In our case our code was running under a thread with the LCID of 1033 (English – United States). As long as the default language of the SharePoint web site is set to English, this works fine and the member variable m_strTitle is returned containing the correct quick link title value of “Title”.

But, when the LCID of our thread is 1033 and the default language of the SharePoint web site is set to Dutch, we get this.TitleResource.Value which is “Home” and that is incorrect.

As a remedy, we can use reflection to retrieve the value of private member m_strTitle. In C#, this goes like this:

SPNavigationNode firstLink = web.Navigation.QuickLaunch[0];
FieldInfo fieldInfo = firstLink.GetType().GetField(“m_strTitle”, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
string realLinkTitle = fieldInfo.GetValue(firstLink).ToString();

In PowerShell, the same feat goes like this:

$site = Get-SPSite $siteUrl
foreach ($web in $site.AllWebs)
{
    $firstLink = $web.Navigation.QuickLaunch[0]
    $fieldInfo = $firstLink.GetType().GetField(“m_strTitle”,
        [Reflection.BindingFlags]::NonPublic
        -bor [Reflection.BindingFlags]::Instance)
    $actualLinkTitle = [string]$fieldInfo.GetValue($firstLink)

    $web.Dispose()
}
$site.Dispose()

Now, regardless of the thread your code is running in, you get the actual link title instead of the resource value.

Having fun with Virto software’s SharePoint 2013 workflow activities kit

It is quite common that companies leveraging SharePoint 2013 workflows find there is some functionality lacking. Extending the existing workflow possibilities by creating custom SharePoint workflow activities that can be leveraged by the company’s power users is certainly possible, but can be quite expensive. Typically, the best option is to buy a commercial solution that extends ootb workflow capabilities. 

There are multiple vendors out there delivering such solutions, but recently our interest was peeked by a company called Virtosoftware. Virtosoftware has created over 50 solutions for SharePoint 2007, 2010, 2013 and Office 365, is a Microsoft Gold certified partner and Virto offers a set of valuable workflow activity extensions. You can find more about that over here: SharePoint Workflows 

One of the areas addressed by Virto are SharePoint workflow activities concerned with interacting with Active Directory. Those activities allow you to interact with almost all AD information. This includes retrieving all kinds of AD properties, but also stuff like user and group management. The next Figure shows an example (taken from the Virto web site with permission):

clip_image002

Most often, we find a need to interact with permissions via workflows at either the site or list level. Luckily, such activities are included in the kit. Virto’s workflow activities kit also contains, of course, the ability to work with e-mails and e-mail attachments in an advanced way.  

The kit offers an ideal extension for power users in the form of Manage site activities that allow SharePoint workflows to perform typical management tasks in a controlled and regulated way, such as creating lists, libraries, sites, and even site collections.

Unsurprising, Virto’s workflow kit has extensions for working with lists, but the extension that did surprise us in this area was an activity that allows you to generate reports about a list. Now that is something we can get on board with! 

All in all the SharePoint workflow kit has over 230 workflow activities, so we won’t cover all of them. Let it be noted the activities contain useful additions involving sending Twitter messages, interacting with several instant messaging platforms, sending SMS messages, interacting with HTTP at a low level, and more.

As a final safety net, there are activities that allow you to execute custom VB.NET or C# code, so if what you’re looking for is not there, there is an easy escape route. If that’s not enough, on page SharePoint Workflow Activities Extensions section “Request the missing activity” we found that Virto promises that if you find a specific SharePoint activity that is not there in the Virto SharePoint Workflow Activities Extensions set, you can send a request that will be fulfilled within 3 Business Days (sic!).

Concluding, thumbs up for Virto SharePoint 2013 workflow activities extensions!

Follow

Get every new post delivered to your Inbox.

Join 754 other followers