SharePoint Experts, Information Architects, Expert Witness

We provide consulting in a broad array of business and technology from architecture to design to deployment of global systems with a focus on surfacing data in the enterprise. Specialists in Microsoft, we are a premier provider of SharePoint Expertise (including 2016 and Office 365). We also provide Expert Witness/Legal Expert in eDiscovery, source discovery, patent infrigement, piracy and more! We also have established SICG DLDS s.a. - our counterpart in Costa Rica that specializes in water systems (http://www.crwatersolutions.com) - Contact me direct: david_sterling@sterling-consulting.com or call 704-873-8846 x704.

Search This Blog

Loading...

Tuesday, March 22, 2016

SharePoint, BlobCache and HTTP 304's

As we all know, the "BlobCache" for SharePoint is disabled by default. There are three specific lines that define this in the web.config of the site. The first is the blob cache (and location):

<BlobCache location="C:\BlobCache\" path="\.(gif|jpg|jpeg|jpe|jfif|bmp|dib|tif|tiff|themedbmp|themedcss|themedgif|themedjpg|themedpng|ico|png|wdp|hdp|css|js|asf|avi|flv|m4v|mov|mp3|mp4|mpeg|mpg|rm|rmvb|wma|wmv|ogg|ogv|oga|webm|xap)$" maxSize="10" enabled="false" />

The output cache profiles:

<OutputCacheProfiles useCacheProfileOverrides="false" varyByHeader="" varyByParam="*" varyByCustom="" varyByRights="true" cacheForEditRights="false" />

And the output cache size in MB:


<ObjectCache maxSize="100" />

All of these must be updated for a production site. First off, the Blob Cache - it must be on a drive OTHER than C: and must be enabled. In addition, it is necessary to add the 'max-age" for the blob's otherwise requests to the site will generate lots of HTTP 304's (304 is a successful pull from cache but without the max-age set to a day, it will require two hits and is a drag on performace). 

As we SHOULD all know, you never make hand changes to the web.config in SharePoint. SharePoint stores the web.config in the database and will periodically overwrite the web.config file on disk (particularly true in a multi-server environment). Changes must ALWAYS use the SPWebConfigModification object either using the Object Model or using PowerShell. You would be surprised at the supposed 'experts' that don't know this.

The following PowerShell scripts will update all three of the lines above using SPWebConfigModification. Each of these changes can be identified by the "owner" specified in the script (example: BlobCacheChg) - this allows them to be removed if necessary.

First to change the Blob Cache settings (note the settings in blue):

# SCRIPT FOR UPDATING THE BLOB CACHE:
#
# Get a reference to the object:
$configModEnable = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
# First enable the cache - set the path of the entry to change
$configModEnable.Path = "configuration/SharePoint/BlobCache"
# Get the enabled attribute:
$configModEnable.Name = "enabled"
# Set the value to true:
$configModEnable.Value = "true"
# Set the sequence (a single modification so 0):
$configModEnable.Sequence = 0
# Set the owner value:
$configModEnable.Owner = "BlobCacheChg"
# Now set the modification type (EnsureAttribute):
$configModEnable.Type = 1
#
# Get a reference to the object:
$configModSetLocation = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
# First enable the cache - set the path of the entry to change
$configModSetLocation.Path = "configuration/SharePoint/BlobCache"
# Get the location attribute:
$configModSetLocation.Name = "location"
# Set the value to true:
$configModSetLocation.Value = "e:\BlobCache\"
# Set the sequence (a single modification so 0):
$configModSetLocation.Sequence = 0
# Set the owner value:
$configModSetLocation.Owner = "BlobCacheChg"
# Now set the modification type (EnsureAttribute):
$configModSetLocation.Type = 1
#
# Get a reference to the object:
$configModSetMaxAge = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
# First enable the cache - set the path of the entry to change
$configModSetMaxAge.Path = "configuration/SharePoint/BlobCache"
# Get the max-age attribute:
$configModSetMaxAge.Name = "max-age"
# Set the value to 86400 (seconds = 24 hours):
$configModSetMaxAge.Value = "86400"
# Set the sequence (a single modification so 0):
$configModSetMaxAge.Sequence = 0
# Set the owner value:
$configModSetMaxAge.Owner = "BlobCacheChg"
# Now set the modification type (EnsureAttribute):
$configModSetMaxAge.Type = 1
#
# Apply the changes to the web application:
#
$webApp = Get-SPWebApplication –Identity http://somesite
#
$webApp.WebConfigModifications.Add($configModEnable)
#
$webApp.WebConfigModifications.Add($configModSetLocation)
#
$webApp.WebConfigModifications.Add($configModSetMaxAge)
#
# Apply the changes:
#
$webApp.Update()
#
# Update the farm:
#
$webApp.Parent.ApplyWebConfigModifications()

Updating the Output Cache setting:

# SCRIPT FOR UPDATING THE OBJECT CACHE PROFILES:
# Get a reference to the object:
$configModOCProf = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
# First enable the cache - set the path of the entry to change
$configModOCProf.Path = "configuration/SharePoint/OutputCacheProfiles"
# Get the useCacheProfileOverrides attribute:
$configModOCProf.Name = "useCacheProfileOverrides"
# Set the value to true:
$configModOCProf.Value = "true"
# Set the sequence (a single modification so 0):
$configModOCProf.Sequence = 0
# Set the owner value:
$configModOCProf.Owner = "ObjCProfileChg"
# Now set the modification type (EnsureAttribute):
$configModOCProf.Type = 1
#
# Apply the changes to the web application:
#
$webApp = Get-SPWebApplication -Identity http://somesite
#
$webApp.WebConfigModifications.Add($configModOCProf)
#
# Apply the changes:
#
$webApp.Update()
#
# Update the farm:
#
$webApp.Parent.ApplyWebConfigModifications()


Updating the Output Cache size:

# SCRIPT FOR UPDATING THE OBJECT CACHE VALUE:
# Get a reference to the object:
$configModObjCache = New-Object Microsoft.SharePoint.Administration.SPWebConfigModification
# First enable the cache - set the path of the entry to change
$configModObjCache.Path = "configuration/SharePoint/OutputCache"
# Get the maxSize attribute:
$configModObjCache.Name = "maxSize"
# Set the value to true:
$configModObjCache.Value = "256"
# Set the sequence (a single modification so 0):
$configModObjCache.Sequence = 0
# Set the owner value:
$configModObjCache.Owner = "ObjCacheChg"
# Now set the modification type (EnsureAttribute):
$configModObjCache.Type = 1
#
#
# Apply the changes to the web application:
#
$webApp = Get-SPWebApplication -Identity http://somesite
#
$webApp.WebConfigModifications.Add($configModObjCache)
#
# Apply the changes:
#
$webApp.Update()
#
# Update the farm:
#
$webApp.Parent.ApplyWebConfigModifications()

Once these changes are made, the web.config should reflect the updates:

<BlobCache location="e:\BlobCache\" path="\.(gif|jpg|jpeg|jpe|jfif|bmp|dib|tif|tiff|themedbmp|themedcss|themedgif|themedjpg|themedpng|ico|png|wdp|hdp|css|js|asf|avi|flv|m4v|mov|mp3|mp4|mpeg|mpg|rm|rmvb|wma|wmv|ogg|ogv|oga|webm|xap)$" maxSize="10" enabled="true" max-age=86400/>

<OutputCacheProfiles useCacheProfileOverrides="true" varyByHeader="" varyByParam="*" varyByCustom="" varyByRights="true" cacheForEditRights="false" />

<ObjectCache maxSize="256" />

Now of course, you may want to remove these changes at some point - for this, you use the "Owner" specified in the scripts above.

Removing the Blob Cache changes:

# SCRIPT FOR REMOVING BLOB CACHE CHANGES:
# Get the web application:
#
$webApp = Get-SPWebApplication http://somesite
# Mod storage:
$mods = @()
# Get all modifications based on the author:
foreach ( $mod in $WebApp.WebConfigModifications ) {
       if ( $mod.Owner -eq "BlobCacheChg" ) {
              $mods += $mod
       }
}
foreach ( $mod in $mods ) {
       [void] $WebApp.WebConfigModifications.Remove($mod)
}
$webApp.Update()
$webApp.Parent.ApplyWebConfigModifications()


Removing the Output Cache changes:

# SCRIPT FOR REMOVING OBJECT CACHE PROFILE CHANGES:
# Get the web application:
#
$webApp = Get-SPWebApplication -Identity http://somesite
$webApp =
# Mod storage:
$mods = @()
# Get all modifications based on the owner:
foreach ( $mod in $WebApp.WebConfigModifications ) {
       if ( $mod.Owner -eq "ObjCProfileChg" ) {
              $mods += $mod
       }
}
foreach ( $mod in $mods ) {
       [void] $WebApp.WebConfigModifications.Remove($mod)
}
$webApp.Update()
$webApp.Parent.ApplyWebConfigModifications()

Removing the Output Cache size changes:

# SCRIPT FOR REMOVING OBJECT CACHE VALUE CHANGES:
# Get the web application:
#
$webApp = Get-SPWebApplication -Identity http://somesite
# Mod storage:
$mods = @()
# Get all modifications based on the owner:
foreach ( $mod in $WebApp.WebConfigModifications ) {
       if ( $mod.Owner -eq "ObjCacheChg" ) {
              $mods += $mod
       }
}
foreach ( $mod in $mods ) {
       [void] $WebApp.WebConfigModifications.Remove($mod)
}
$webApp.Update()
$webApp.Parent.ApplyWebConfigModifications()




Monday, March 7, 2016

Infopath cannot save the following form. this document library was either renamed or deleted or network problems are preventing the file from being saved

So working with an InfoPath form, you try to publish to SharePoint and get this:

Infopath cannot save the following form. this document library was either renamed or deleted or network problems are preventing the file from being saved

You retry - problem persists! Assuming you don't actually have network issues, the problem is likely that either (a) you didn't install the Desktop Experience (I know, I know) and/or (b) the Windows Themes service isn't running. Turns out, InfoPath needs the D.E. features and that service to work.

In most cases, it will be (a). You can use the system manager to install quickly but you can easily do it from PowerShell:


The command (in case you can't read it) is:

Install-WindowsFeature Desktop-Experience

As noted, once complete, you will have to reboot the server. IF this doesn't work, check the Windows Themes service (it should be set to Automatic and should be started).

Kudos to David Lean on this.

Thursday, March 3, 2016

Using the Upload Document Button outside of the Document Center (SP 2013)

Like me, you've probably wanted to use the Upload Document button from the Document Center in another site type:
While I've done this in 2010, there are some minor changes in 2013 to the script to get it to work. Using the 2010 solutions, you will find that once a page it published, the script will not work!

Here's the actual solution for 2013 - first, create a text file and add the following code (note the URL you have to set - also, I used 'Documents' - specify the proper library name):

<script type="text/javascript">// <![CDATA[
var navBarHelpOverrideKey = "wssmain";
function OpenNewFormUrl(url)
{
var options = {};
SP.SOD.executeFunc('sp.ui.dialog.js', 'SP.UI.ModalDialog.showModalDialog', function() {
SP.UI.ModalDialog.commonModalDialogOpen(url, options, null, null);
});
}
// ]]>
</script>
<div>
   <button onclick="javascript:OpenNewFormUrl(&#39;[URL TO YOUR SITE]/Documents/Forms/upload.aspx&#39;);return false;">
      <nobr>
         <img alt="Upload a Document" src="/_layouts/15/images/uploaddoc.png?rev=23" style="vertical-align: middle;"/>&#160;<span>Upload a Document</span></nobr> </button></div>


Upload the file to a library in SharePoint and copy the link (shortcut). Navigate to a page and add a Content Editor Web Part or Script Web Part - edit the web part settings and paste in the link to the text file. Save the part settings and you are ready to go.

NOTE: Don't edit the CEWP source - SharePoint will 'rewrite' the code and while it might work, more often it doesn't!


Tuesday, February 16, 2016

Event 6398 - SharePoint User Profile Service

Event 6398 - SharePoint User Profile Service

Every now and again, it seems that even in 2013/2016, the User Profile Service can go south for no particular reason. One error I see most often in the System Application Event Log is Event ID 6398:



If you can't see the image the text is:

The Execute method of job definition Microsoft.Office.Server.UserProfiles.UserProfileImportJob (ID <some guid>) threw an exception.

There was not endpoint listening at http://<server>/ResourceManagementService/MEX that could accept the message....etc.

This error (marked as Critical) fires about every minute.

Turns out that the culprit is usually the Forefront Identity Management service isn't running. To correct, login to the server that is hosting the UPS service then select Administrative Tools > Services (or Start > Run > Services.msc).

Locate the Forefront services and typically, it will be stopped:


Right click on the service and start it - this should clear up the errors and UPS should starting working again.

Make SURE the account running the service is correct - in the above example, the FARM account was used - typically, you would be using an account specific for the synchronization service, right?

The service can be checked in PowerShell and started there as well. To get the status, enter:

Get-Service FIMService

To start it:

Start-Service FIMService

For example:


Friday, January 1, 2016

Checking BitLocker status (Windows 8/Windows 10)

If you've started using BitLocker to encrypt your hard drives (and you should be), you may notice when first started that the system is very sluggish for awhile.

When I turned it on (be aware - not ALL versions of Windows have it - for example Windows 8.1 Pro and Enterprise - I am assuming the same for Windows 10), all went as planned but the system was really slow for a 16GB machine. While I was just setting it up (installing Office, etc.), the system was really bogged down. I let it sit for a day then installed some other things - same issue.

This was really beginning to concern me about the long term performance until I noticed that in the System Tray, the BitLocker icon was there. Right clicking on it is showed "Encrypting". Being a new system with a 1TB drive, I assumed it would take a while so I let it sit for a full day. Checked the status, same deal so wasn't sure if it was stuck or some other major issue.

Looking around for some answers (I obviously didn't want to reboot), I finally found the command line method for managing BitLocker (manage-bde). While this command has a lot of options (locking/unlocking a drive, etc.) it has the option to simply check the status. Open a Command Window (running As Administrator!), enter the command:

manage-bde -status

Viola! It shows the complete information you'd want to know:

Disk volumes that can be protected with
BitLocker Drive Encryption:
Volume C: [drive name]
[OS Volume]

Size: 930.79 GB
BitLocker Version: 2.0
Conversion Status: Encryption in Progress
Percentage Encrypted: 73.8%
Encryption Method: AES 128
Protection Status: Protection Off
Lock Status: Unlocked
<some more info about type of key, etc. here>

<other drives will be listed here>

In short, enabling BitLocker means being very patient. In the case of my drive (930.79 GB), it took over two and a half days to complete!

Tuesday, October 27, 2015

The Trust Relationship Between This Workstation And The Primary Domain Failed

So every now and then, I've come across the error when trying to login to a server:

The Trust Relationship Between This Workstation And The Primary Domain Failed

There are a number of reasons this can happen - basically it means that the Domain Controller and the Server are not communicating. For example, if a domain controller goes down and the server brought up, it cannot communicate to authenticate the server in the domain. This can also happen when system recoveries are necessary or when restoring a Virtual Machine.

One method (though not the best) is to simple login to the server as an Administrator, go to the System Properties, leave the domain by specifying a temporary workgroup name (you'll need the AD Administrator account & password), reboot then join the domain again.

However, there are two better ways to do this by simply resetting the Server Password in Active Directory from the Server you are having issues with. Login as the Server Administrator then via a Command Line (using Run as Administrator), enter the following:

netdom.exe resetpwd /s:<AD server name> /ud:<user name> /pd:*

Where 'AD server name' is the name of the Active Directory server and 'user name' is an account (in format of domain\name) that has permssions in AD.

Note that when you enter this command, it will prompt for a password to the account you specified.

Alternately, you can use PowerShell:

Reset-ComputerMachinePassword [-Credential <PSCredential>] [-Server <String>]

Where 'PSCredential' is the login name and 'String' is the name of the domain controller. For more info on the PowerShell command, see here:

https://technet.microsoft.com/en-us/library/hh849751.aspx

Once either of these methods are used, I suggest rebooting the server - when it comes back up, login with a domain account.


Tuesday, October 6, 2015

Some interesting changes for SharePoint 2016

Overall, SharePoint 2016 is simply an upgrade to 2013. One significant change is that Server Roles must be assigned when installing (i.e. web front end, etc.) and the Distributed Cache role is also new (as a setting that is – 2013’s streamlined model accounted for this role though most folks didn't use it). It is clear that it will require a few more servers in your average farm.

There are some cosmetic changes to the site templates (they changed the header a little bit – site settings now in a new black bar at the top of the page):


Overall, the installation process and adding servers is pretty much the same. All of the service applications are the same – and surprisingly, PerformancePoint is still available (Microsoft hinted at dropping that two years ago). They did add a new service for Project Server (see below). Site deployment remains the same and templates are the same as 2013.

As for features, annoyingly, the Access App feature is automatically enabled meaning you have to turn it off it you don't want your users using that (the security issues around Access still remain). This time though, they did expand on the explanation of what it’s for (in 2013, it just said Access web app).

They have added some new ones (not sure if this represents a merge of Project Server but sure looks like it; since this is preview, they might not include these in the final):

  • Announcement Tiles - Enables Announcement Tiles feature and adds the webpart to the site.
  • Project Proposal Workflow - Provides a review workflow for managing project proposals.
  • Project Web App Connectivity - Provides the lists required within a Project Site for integration with Project Web App including issues, risks, and deliverables.
  • Project Server Approval Content Type - This content type is used by the Project Server Approval workflow
  • Project Web App Permission for Excel Web App Refresh - When this feature is active, users can refresh reports containing Project Web App data within Excel Web App.
  • Project Web App Ribbon - Contains the ribbon controls for Project Web App pages.
  • Project Web App Settings - Project Web App PMO Settings
  • Sample Proposal - Sample workflow for Project Server

The Services on Server has changed a bit too, in addition to the Roles, they’ve added a new Restart option and an indicator if the Service is in Compliance (not 100% on the last one, but would appear to be based on the Role of the server):



Probably the biggest changes is the new 2016 Hybrid Feature – this allows connection to Office 365 and OneDrive:
“With hybrid features, you can take a best-of-both-worlds approach by providing access to Office 365 productivity services and offerings directly within SharePoint Server 2016. To learn more about SharePoint hybrid solutions, visit the 'SharePoint Hybrid Solutions Center' (http://go.microsoft.com/fwlink/?LinkId=533372).”

So – there you have it! As the preview, Microsoft is usually around 3 months to customer release – I expect we’ll see the final in December!