Workflow to Update Hyperlink Display Text

Problem:

I wanted to use Quick Edit to update the URL column for a bunch of items in a list. The problem is that when you edit a hyperlink column, you have to click the little hyperlink editor icon next to the cell to also edit the display text. Otherwise, it just shows up as the URL.

Solution:

Use a workflow to change the display text to something else.

1. First, create a new text column or use an existing text column
2. Open SharePoint Designer
3. Create a new List Workflow
4. Add Update List Item action
5. Click “Add…”

6. Scroll through and find your new column. In this example I used the existing Description column.

7. Click “…” to open the String Builder

8. Click “Add or Change Lookup”
9. Select the hyperlink column
10. Change “Return field as:” to URL

11. Click “OK”
12. IMPORTANT: Add a comma and a space.
13. Click “Add or Change Lookup” again to select a column, or type out what you want your display text to be. I am setting mine to be the Title of the item.
14. Click “OK” > “OK” > “OK”
15. Add another Update List Item action
16. Click “Add…”
17. Set the hyperlink column to the value of the column we updated in the previous step

18. Click “OK” > “OK”
19. Change the Start Options to “Start workflow automatically when an item is changed”
20. Publish

Now you can Quick Edit a bunch of URLs without having to manually change the display text.

Search Crawl Log Error – Access is denied

Scenario:

Crawl History shows 0 successes and a bunch of security errors.

The following error is logged in the Error Breakdown:

“Access is denied. Verify that either the Default Content Access Account has access to this repository, or add a crawl rule to crawl this repository.”

Possible Solution:

Check your hosts file. In my case, host headers had been commented out for testing and never changed back.

 

Workflow Stuck On Starting After Password Change

I generally use my own account to create and publish workflows. One day, none of my workflows were completing and they were all stuck on “starting”. I thought maybe there was something wrong with the workflows themselves so I tweaked one of them a bit and re-published and voila! It worked! But the thing I tweaked really shouldn’t have “fixed” anything. So I changed it back and again, it worked!

After banging my head against my desk for a little while I remembered updating my password that morning. Maybe all I needed to do was republish my workflows.

Which is what I did and it fixed everything.

There may have been an easier solution, but this worked for me.

Summary:

If you’re going to use your own account to create and publish workflows, you might have to re-publish every time you change your password.

You should probably use an admin account without a password policy to publish workflows.

 

Keep Results Empty Until User Searches

Scenario:

When you navigate to a custom search page, the Search Results web part is already populated even though you haven’t searched for anything yet.

You want the Search Results web part to remain empty until a user searches for something.

Solution:

Wrap the query template. {?{searchboxquery}}

1. Edit the page
2. Edit the Search Results web part
3. Click “Change query”

4. In the Query text box, wrap the filters {?{searchboxquery}}

5. When you click Test query, the preview should say “This query returned no results.”
6. Click OK to save the query
7. Click OK to save and close the web part properties
8. Save the page

Copy Missing Objects From One Content Database to Another

I recently applied a cumulative update to a SharePoint environment that hadn’t been patched in years. When I tried to upgrade the main production content database, the process failed and rendered the site inaccessible. The errors logs mentioned invalid objects such as “Webs” and “Sites”, and upon further troubleshooting we learned that because of permission issues, the content database was missing critical views and procedures due to one of the updates rolled up into the cumulative update.

NOTE: I’d like to take a moment to stress the importance of backups. CONFIRM THAT YOU HAVE A HEALTHY BACKUP BEFORE PERFORMING MAINTENANCE. EVERY. SINGLE. TIME! Thank you.

Even though we corrected the permission issues, no matter what we tried we could not re-run the upgrade to fix the problem. Instead, we had to copy those missing objects and views from the sandbox content database to prod, and cross our fingers it would work. (spoiler: it did)

  1. Right click your healthy database > Tasks > Generate Scripts…
  2. In the Choose Objects prompt, select the objects you would like to copy. In our case we copied Views and Stored Procedures.
  3. Click Next
  4. Select “Save to new query window”
  5. Next > Next > Finish
  6. Change the database in the query to the database that’s missing objects
  7. Execute
  8. Browse the site to confirm content
  9. Drink

Start Workflow on Inbound Email

By default, workflows will not auto start for attachments sent to a library via email.

To enable this functionality, run the following PowerShell script on your SharePoint server.


Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

$spWebService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$spWebService.DeclarativeWorkflowAutoStartOnEmailEnabled = $true
$spWebService.Update()

Next, make sure your workflow is configured to start automatically when an item is created.

Custom XSL Web Part Error – Access Denied

Scenario:

I created a custom XSL style sheet for a library web part that would intermittently throw an error for everyone except the admin account (me).

Every morning users were complaining about an error on the web part. I would sign in and try to replicate, but it always worked for me. Then when I’d ask the user to refresh their page and miraculously the error would go away.

Error

ULS logs contained the following information:

SPSecurityContext: Could not retrieve a valid windows identity for username ‘domain\user’ with UPN ‘user@domain.local’. UPN is required when Kerberos constrained delegation is used. Exception: System.ComponentModel.Win32Exception (0x80004005): Access is denied Server stack trace:
 at System.ServiceModel.Channels.AppContainerInfo.GetCurrentProcessToken()
 at System.ServiceModel.Channels.AppContainerInfo.RunningInAppContainer()
 at System.ServiceModel.Channels.AppContainerInfo.get_IsRunningInAppContainer()
 at System.ServiceModel.Channels.PipeSharedMemory.BuildPipeName(String pipeGuid)
 at System.ServiceModel.Channels.PipeSharedMemory.get_PipeName()
 at System.ServiceModel.Channels.PipeConnectionInitiator.GetPipeName(Uri uri, IPipeTransportFactorySettings transportFactorySettings)
 at System.ServiceModel.Channels.NamedPipeConnectionPoolRegistry.NamedPipeConnectionPool.GetPoolKey(EndpointAddress address, Uri via)
 at System.ServiceModel.Channels.CommunicationPool`2.TakeConnection(EndpointAddress address, Uri via, TimeSpan timeout, TKey& key)
 at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
 at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
 at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
 at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
 at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
 at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
 at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
 at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
 at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
 at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
 at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) Exception rethrown
 at [0]:
 at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
 at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
 at Microsoft.IdentityModel.WindowsTokenService.S4UClient.IS4UService_dup.UpnLogon(String upn, Int32 pid)
 at Microsoft.IdentityModel.WindowsTokenService.S4UClient.CallService(Func`2 contractOperation)
 at Microsoft.SharePoint.SPSecurityContext.GetWindowsIdentity().
No windows identity for “domain\user”.

Root cause:

The SharePoint site’s application pool was configured to recycle every morning at 3:00 AM. This would clear cached authentication, and due to permissions, the XSL style sheet could not be accessed until the administrator logged in.

In addition, according to Hemendra’s response in this post, this can also be caused by an anonymous cache bug.

Solution:

Option 1: Remove auto-recycle settings on the application pool. (The error will re-appear if the site is manually recycled or the server reboots.)

Option 2 (recommended): Create two separate XSL files. The first file will be attached to the web part and, using the xsl:import element, will reference a second XSL file that contains your view styles.

XSL File #1 – Reference.xsl (linked in the Web Part Properties):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:import href="/SiteAssets/Style.xsl"/>

<xsl:template match="/">
<xsl:apply-imports/>
</xsl:template>

</xsl:stylesheet>

xsllink

XSL File #2 – Style.xsl (contains view styles):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<tr>
<td><xsl:value-of select="catalog/cd/title"/></td>
<td><xsl:value-of select="catalog/cd/artist"/></td>
</tr>
</table>
</body>
</html>
</xsl:template>

</xsl:stylesheet>

NOTE: Save your XSL files in a library where Everyone has at least Read permissions.