Skip to content

Changing SharePoint farm passwords

Another recent case from the customer.

What they had is a farm which was deployed with autospinstaller. https://autospinstaller.codeplex.com/ So they have quite a number of accounts for various SharePoint services , windows services and application pools.

 

So how should we change the accounts?

The easiest way (that was implemented at the customer) is to have account to be registered as managed accounts.

This way you or SharePoint can automatically change passwords for the accounts, and update all relevant records.

The managed account can change the passwords in AD or just update the SharePoint records. In our case there were some errors we have not resolved, so we have let the AD admins change the password and then we have changed the things in SharePoint.

 

So what happens after you change the AD account password?

If you do nothing, there will be problems. Most likely though you will only notice the problems after you restart the server.

 

The reason is that there are

Windows Service registrations on farm computers containing copies of the passwords

IIS Pools registrations containing copies of the passwords

In some cases (like search or workflow) other entities contain the reference to the password.

Managed accounts

The benefit of managed account is that SharePoint can automate some of these actions across the farm. Namely – changing the windows service registrations and iis pools registrations.

If you choose to change the passwords (and not let them be changed automatically), there are basically 2 ways to do it.

Option one – Central Admin

two

 

Press the edit button

Enter new password and press ok below

two

 

Note that option one – Set account password to a new value will try to change the password in AD first. Option two will just update the relevant services and IIS pools.

In some cases you would prefer to use PowerShell. If the account you are changing is also used to run the Central Administration application pool, then your command will kinda fail in the middle cause it will run under the pool that is going to be reset!

In this case you can use the Set-SPManagedAccount command

https://technet.microsoft.com/en-us/library/ff607617(v=office.16).aspx

If you want this command to change the AD password use this format

Set-SPManagedAccount -Identity $username -NewPassword $newpassword -ConfirmPassword $newpassword

If you want to use an existing password – use this one.


Set-SPManagedAccount -Identity $username -ExistingPassword $newpassword  -UseExistingPassword:$true

I have made a script that reads accounts and new passwords from the csv files and updates them in a bulk.


<#
.SYNOPSIS
Changes managed account passwords at the farm.
.DESCRIPTION
Changes accounts using the provided CSV file.
.EXAMPLE
.\changepasswords.ps1    -inputFile "yourfile.csv" -newPasswords:$false
.NOTES
Author: Marat Bakirov
Date: 05 July 2016
#>
[cmdletbinding()]
param(
[string] $InputFile = "accountsandpasswords.csv",
[switch] $newPasswords = $true
)

####################################################
# Configurables
####################################################

Add-PSSnapin Microsoft.Sharepoint.Powershell

####################################################
# Main
####################################################

function Main
{

$passwords = Import-Csv $InputFile
$passwords | foreach {
$username = $_.Username
$newpwd1 = $_.NewPassword
$newpassword =  ConvertTo-SecureString -String $newpwd1 -AsPlainText -Force
$newpwd1
if ($newpasswords)
{
Write-Host "changing password for  {$username} to a new one"
Set-SPManagedAccount -Identity $username -NewPassword $newpassword -ConfirmPassword $newpassword -Confirm:$false
}
else
{
Write-Host "changing password for  {$username} to an existing one"
Set-SPManagedAccount -Identity $username -ExistingPassword $newpassword -Confirm:$false -UseExistingPassword:$true
}
}
}
Main

How to change other passwords

If the account participates in the user profile sync, search or workflow farm, you  might need to run additional scripts.

User profile sync

These accounts are managed and are changed within SharePoint but are also used for the User Profile Sync. So an additional configuration might be required.

Good reference can be found here

https://blog.zubairalexander.com/managing-passwords-for-service-accounts-in-sharepoint-sql-server/ – section 5 5. User Profile Synchronization Connection Account

or https://blogs.msdn.microsoft.com/charliechirapuntu/2013/01/16/sharepoint-2010-service-accounts-passwords-change-guide/

 

Search crawler account

This has an additional impact – the search content account has to be updated in the active directory first and then updated in the search center.

https://technet.microsoft.com/en-au/library/dn178512.aspx

 

Workflow and service bus farm accounts

 

 

On each server in the farm that has workflow installed run the Service Bus PowerShell in the elevated mode. (Note: if the service buspower shell is missing, then skip the procedure for this server).

Run the changewfpassword.ps1 script.

The script will prompt for the new Password for the svcInsiteWfProd/ svcInsiteWfTest  account.

 


Write-Host "Please enter a new password"
$passwordText = Read-Host
$AccountPassword = ConvertTo-SecureString -String $passwordText -AsPlainText -Force

Stop-WFHost -Verbose
Update-WFHost -RunAsPassword $AccountPassword –Verbose
Start-WFHost -Verbose

Stop-SBHost -Verbose
Update-SBHost -RunAsPassword $AccountPassword –Verbose
Start-SBHost -Verbose

 

Source code

The scripts could be found here

 

https://1drv.ms/f/s!AguWtH15ywzQhI5kUYLXI1Jcmv4Y6Q

 

Case – broken export-spweb. (Understanding the solution package version and DeploymentServerType)

Another case from the recent customer support work. The customer had a 3rd party solution with a list template, list and a web part which seemed to be created for SharePoint 14 (2010) originally and simply recompiled. (And I cannot change or recompile the sources).

 

The customer has SharePoint 2013 farm, made of 2 App servers (let us call them APP1 and APP2) and 2 web front ends (WEB1 and WEB2).

APP1 also runs central admin.

 

Another 3rd party backup solutions the customer is using is doing a granular SharePoint backup (up to document) and internally uses the Export-SPWEB command.

 

The Export command breaks.

Errors are similar to the ones described here:

https://social.technet.microsoft.com/Forums/en-US/6b50d0f2-b323-4156-a11a-d3f6ea1492c7/sharepoint-2010-site-collection-export?forum=sharepointgeneralprevious

 

Error: Feature ‘d57f4817-f1f9-42aa-863c-139804c731b0’ for list template ‘100’ is not installed in this farm.  The operation could not be completed.

 

During investigation I have found out the few reasons.

 

First – the 3rd party solution was installing in the 14 Hive.

What?

 

The solution files and features were added to the “C:\Program Files\Common Files\microsoft shared\Web Server Extensions\14\TEMPLATE\FEATURES\”  but NOT added to the “C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\TEMPLATE\FEATURES\”

 

Apparently the solution was compiled with the 14 compatibility option.

2016-07-19_14-42-55

 

 

Probably it is not a good idea to go through all servers and copy the files, so to achieve the result we need to tell SharePoint to deploy the solution to both 14 and 15 hives.

Would be simpler if the solution would recompiled with 15 compatibility option, but I could not do it, so I had to run the following command to deploy the solution

 

2016-07-19_15-07-18


Install-SPSolution -Identity <yoursolution.wsp> -AllWebApplications -GacDeployment -CompatibilityLevel {14,15}

 

This made the files to appear at the 15 hive.

However, the files were only deployed to the WEB1 and WEB2, and the export command were still not working at the APP1 and APP2, despite the fact that it started to work fine at the WEB1 and WEB2.

 

The customer was really reluctant to run the Export jobs at the Web frontend and thus increasing the load.

 

To understand why the files did not appear at the APP1 and APP2, let us look at another setting:

2016-07-19_15-11-07

 

So this setting is telling us if the solution will be deployed to web front end or an application server.

But how does SharePoint define which server is the application server?

 

Well you might assume that it is server role.

https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spserverrole.aspx

2016-07-19_15-18-44

 

For SP2013 it seems that this does not matter.

It seems that the  Sharepoint defines the web front end as a server that runs a “Microsoft Sharepoint Foundation Web Application” service.

 

2016-07-19_15-22-50

If the solution package deployment type is “WebFrontEnd”  – it’s assets are deployed  to the servers that have the “Microsoft Sharepoint Foundation Web Application” on.

So the solution was simple – start the Microsoft Sharepoint Foundation Web Application service on the server? Simple?

 

One more tricky thing. Starting the service on the server that has a Central Admin – causes the IIS to restart, and thus central admin to restart. So we may encounter the problem. In this case run the command

 

 


Get-SPServiceInstance | where {$_.TypeName.Contains('Web Application')} | ft -Property Id,TypeName,Server,Status -Autosize

 

Find the service instance on the server you want it to run on, and then run the


Start-SPServiceInstance -Identity <guid> command

 

2016-07-19_15-48-44

 

That is all! the case is solved. So we have fixed the version by installing the solution with the correct compatibility levels and also added a Web Role to the application servers.

 

Woah woah woah wait a second.

What?

Added a Web Role to the application servers???

Yes, however we did not break the farm topology. These servers APP1 and APP2 HAD the “Microsoft Sharepoint Foundation Web Application” service but were NOT used as Web  Front ends. Simply the load balancer had no idea they do have the IIS and so the requests were not redirected here.

We just solved the problem.

 

 

 

 

How to display correct document links in the search results.

At the recent client project there were an interesting situation. They had a web part that was looking pretty much like a list with the only difference – it was a Content Search webpart and it was supposed to show certain the documents from all subsites. Pretty usual request.

However, the client pointed out, that the links are not the same as if they would use the “normal” documents view. The client was not happy that the links suggest to download the file instead of opening in Word/Excel/etc.

I have started to look.

There were a number of reasons why the links were different.
First reason is that they use  Path  managed property.
Path managed property gives what it gives. The path.
Like this

http://sp131:82/Documents/excel1.xlsx

But it does not respect existence of the Excel services or the OWA.
So I found this blog post

http://www.eliostruyf.com/three-useful-managed-properties-for-working-with-office-web-apps/

That was probably the only one explaining other important managed properties

  • ServerRedirectedURL
  • ServerRedirectedPreviewURL
  • ServerRedirectedEmbedURL

 

So I have used the ServerRedirectedURL. At the customer environment it returns a link to OWA, like this:


http://server/_layouts/WopiFrame.aspx?sourcedoc={E526E4B1-6759-448F-B6C6-0C67E942173B}&file=Documents/excel1.xlsx&action=default&DefaultItemOpen=1

 

At my local SharePoint dev single server machine it looked like this


http://sp131:82/_layouts/15/xlviewer.aspx?id=/Documents/excel1.xlsx&DefaultItemOpen=1

 

Another difference was the way the links work. In the library itself the links tried to open the corresponding app – word or excel or the OWA. In the search results there were no prompt for opening the App.

 

There is a setting that affects this behaviour It is well described in this article

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

2016-07-18_16-27-06

 

You can find it under “advanced” settings in the document library, and there are some other system wide settings that affect it.

 

I have looked at the links in the list and found out that the links look like this

 

When the library setting is like “open in the client application”.


<a class="ms-listlink ms-draggable" href="/Documents/doc1.docx" onmousedown="return VerifyHref(this,event,'0','SharePoint.OpenDocuments','')" onclick="return DispEx(this,event,'TRUE','FALSE','FALSE','SharePoint.OpenDocuments.3','0','SharePoint.OpenDocuments','','','','1','1','0','0x7fffffffffffffff')" dragid="1" draggable="true">doc1</a>

When the library setting is like “open in the browser”.


<a class="ms-listlink ms-draggable" href="/Documents/doc1.docx" onmousedown="return VerifyHref(this,event,'1','SharePoint.OpenDocuments','')" onclick="return DispEx(this,event,'TRUE','FALSE','FALSE','SharePoint.OpenDocuments.3','1','SharePoint.OpenDocuments','','','','1','1','0','0x7fffffffffffffff')" dragid="1" draggable="true">doc1</a>

In my case the customer was ok with hardcoding the option one. So the final resulting code was like this



<!--#_
var linkURL = $getItemValue(ctx, "Path");
linkURL.overrideValueRenderer($urlHtmlEncode);
var ServerRedirectedURLValue = '';
var ServerRedirectedURL = $getItemValue(ctx, "ServerRedirectedURL");
ServerRedirectedURL.overrideValueRenderer($urlHtmlEncode);
ServerRedirectedURLValue = ServerRedirectedURL.defaultValueRenderer(ServerRedirectedURL);
if ( (ServerRedirectedURLValue == null) || (ServerRedirectedURLValue == undefined) || (ServerRedirectedURLValue == ''))
ServerRedirectedURLValue = linkURL.defaultValueRenderer(linkURL);
var onmousedown = "return VerifyHref(this,event,'0','SharePoint.OpenDocuments','1" +ServerRedirectedURLValue +"')";
var onclick = "return DispEx(this,event,'TRUE','FALSE','FALSE','SharePoint.OpenDocuments.3','0','SharePoint.OpenDocuments','','1"+ServerRedirectedURLValue+"','','2','0','0','0x7fffffffffffffff')";
_#-->
<a class="cbs-Line1Link ms-noWrap ms-displayBlock"
onmousedown="_#= onmousedown =#_"
onclick="_#= onclick =#_"
href="_#= linkURL =#_" title="_#= $htmlEncode(line1.defaultValueRenderer(line1)) =#_" id="_#= line1LinkId =#_">_#= line1 =#_</a>

 

How to add “View Library” link to the SharePoint Search results from file share

Recently a customer asked me to improve one little thing.
You know the “view library” link that appears once you search for the files in SharePoint?

These guys had setup a search over a file share, but the library link did not appear there.
Apparently the solution appeared to be rather simple. However, I did not find anything in the internet and the customer did not as well.
I assume you are familiar with the display templates concept in the SharePoint 2013. There templates are used to display search results and actually they are JavaScript files (or, in the case of SharePoint Standard, HTML files that generate the JS files).

So the links are rendered by the Item_CommonHoverPanel_Actions.html
This part renders the “View Library” link.


if(!Srch.U.e(ctx.CurrentItem.ParentLink) && ctx.CurrentItem.csr_ShowViewLibrary) {
_#-->

<!–#_
}

While debugging I have found out that the CurrentItem.ParentLink is not filled.
I could not find out why it happens that way for the file shares, however, once I found this, the fix became very simple. I have added this simple piece of code before the block.

//ignia custom code
var url = ctx.CurrentItem.csr_Path;
if (url.indexOf('file://') >=0)
{
var lastIndexOfSlash = url.lastIndexOf('/');
if (lastIndexOfSlash > 0)
{
ctx.CurrentItem.ParentLink = url.substring(0,lastIndexOfSlash);
}
}

Simple!

How to deal with “Missing server side dependencies” error

In this post I am going to show my methodology for dealing with the “Missing server side dependencies” error. I do not have a good way to deal with it online but one good way to deal with it on-premises.

 
 

For this example I am using the SharePoint 2010, but the problem is the same in the newest versions (though honestly I did not check it on the SharePoint 2016).

 
 

This error appears in the SharePoint Health Analyzer

 
 

 
 

 
 

and looks like this:

 
 

 
 

 
 

 
 

 
 

Let us think for a second – why does this error happen and what is the inner reason for it?

 
 

Let us say your server side solution has some artefact. In this case it is the web part. Once upon a time the web part was a part of the solution and was deployed somewhere. Then you have decided you do not need the web part or simply has renamed it. However the content database already contains an information like “page xxx has a web part yyy in this zone with this settings”.

And if the webpart does not exist the database is inconsistent.

 
 

It is not necessary a web part. You can add a ghosted module file and then decided to rename it. So the SharePoint will keep the information about the file in the database but the file will not be there.

 
 

Could be also that the web part gallery (_catalogs/wp contains information about your webpart and the webpart is also part of farm solution and do not exist anymore)

 
 

So the first step is to find where the web part is.

 
 

The way I was always doing it is via SQL. With the SQL you can search through the content database and find that specific string.

 
 

I have been making and losing the script the number of times, most recent time I have found a script in here

http://stackoverflow.com/questions/591853/search-for-a-string-in-all-tables-rows-and-columns-of-a-db

And I have slightly modified it so it not only shows the table where the string is stored, but also specific lines.

 
 

use WSS_Content — could be your database name here

 
 

DECLARE

@search_string VARCHAR(100),

@table_name SYSNAME,

@table_schema SYSNAME,

@column_name SYSNAME,

@sql_string VARCHAR(2000)

 
 

SET @search_string = ‘yourwebpart.webpart’

 
 

DECLARE tables_cur CURSOR FOR SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = ‘BASE TABLE’

 
 

OPEN tables_cur

 
 

FETCH NEXT FROM tables_cur INTO @table_schema, @table_name

 
 

WHILE (@@FETCH_STATUS = 0)

BEGIN

DECLARE columns_cur CURSOR FOR SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = @table_schema AND TABLE_NAME = @table_name AND COLLATION_NAME IS NOT NULL — Only strings have this and they always have it

 
 

OPEN columns_cur

 
 

FETCH NEXT FROM columns_cur INTO @column_name

WHILE (@@FETCH_STATUS = 0)

BEGIN

— SET @sql_string = ‘IF EXISTS (SELECT * FROM ‘ + QUOTENAME(@table_schema) + ‘.’ + QUOTENAME(@table_name) + ‘ WHERE ‘ + QUOTENAME(@column_name) + ‘ LIKE ”%’ + @search_string + ‘%”) PRINT ”’ + QUOTENAME(@table_schema) + ‘.’ + QUOTENAME(@table_name) + ‘, ‘ + QUOTENAME(@column_name) + ””

SET @sql_string = ‘IF EXISTS (SELECT * FROM ‘ + QUOTENAME(@table_schema) + ‘.’ + QUOTENAME(@table_name) + ‘ WHERE ‘ + QUOTENAME(@column_name) + ‘ LIKE ”%’ + @search_string + ‘%”) SELECT * FROM ‘ + QUOTENAME(@table_schema) + ‘.’ + QUOTENAME(@table_name) + ‘ WHERE ‘ + QUOTENAME(@column_name) + ‘ LIKE ”%’ + @search_string + ‘%”’

 
 

EXECUTE(@sql_string)

 
 

FETCH NEXT FROM columns_cur INTO @column_name

END

 
 

CLOSE columns_cur

 
 

DEALLOCATE columns_cur

 
 

FETCH NEXT FROM tables_cur INTO @table_schema, @table_name

END

 
 

CLOSE tables_cur

 
 

DEALLOCATE tables_cur

 
 

 
 

 
 

 
 

Once I have run the script I have seen this:

 
 

 
 

So now I know that the site with ID 089D94D0-7BF4-4A51-9E29-2BACABC30DF4 contains a missing web part in the gallery, I guess I could just delete it? A simple get-spsite PowerShell command could find me the site and the gallery.

 
 

Here is another example of another webpart. This time we can see it happens on 2 different web sites – a default site and a personal site of the administrator.

 
 

 
 

 
 

 
 

However, running this script is not enough. This is another good script that will find your webpart on all pages.

 
 

SELECT Webs.FullUrl, Webs.Title, AllDocs.DirName, AllDocs.LeafName, AllWebParts.tp_DisplayName, AllWebParts.tp_ID

FROM AllDocs, Sites, AllWebParts, Webs

WHERE Webs.Id = Sites.RootWebId AND AllDocs.Id = AllWebParts.tp_PageUrlID

AND Sites.Id = AllDocs.SiteId AND tp_WebPartTypeId IN (

SELECT DISTINCT tp_WebPartTypeId FROM AllWebParts (NOLOCK)

WHERE tp_WebPartTypeId IS NOT NULL AND tp_Assembly IS NULL AND tp_Class IS NULL)

— if you add this line, the script will find your specific web part instead of giving you all web parts on all pages

–AND (AllWebParts.tp_DisplayName = ‘yourwebpartname’)

 
 

Results of the script when run with my webpart:

 
 

Pic4.

 
 

 
 

Now depending on the number of pages and problems you could either clean the pages manually or make a script that will go through the pages and delete the webpart from it.

 
 

One more hint to finish this. Recently I met a problem I could not solve easily. Some users had added the obsolete Web Part to the Personal View of the page. So the script that would clean the web part could not delete this or even find the users! The content database did not help in this case.

 
 

So the simplest way to remove all personalized settings and the faulty/missing webpart from the page is to add the ?contents=1 to the page URL. This will bring the page into maintenance mode.

 
 

Here is how you remove all personal users settings

 
 

 
 

 
 

And here is how you delete the problematic web part from the page

 
 

 
 

 
 

 
 

Sharepoint dev machine – keep your SQL databases sizes neat

Ok, time to go back to the blog posting.

 

I do often create single-server SharePoint based environments purely for development purposes. In this environment we often face an issue of overgrowing databases logs.

To make things worse, now I use SSDs in Azure, which are rather limited in size.

So for DEVELOPER machine it would be fine to switch the recovery model to simple and thus the log should be truncated.

Prior to SQL 2012, there was a special option “truncate log on checkpoint”, but as of SQL 2012 I cannot find this option anymore. See https://technet.microsoft.com/en-us/library/ms187310(v=sql.105).aspx

 

The blog here http://microtechpoint.com/index.php?route=blog/article&article_id=10 contains a good set of commands to keep your database in place (I really like the title “Shrinking Ginormous SharePoint Database Transaction Log Files” :)), but it only deals with one database.

 

So I have found an undocumented procedure sp_MSForEachDB (you could read more here http://www.c-sharpcorner.com/UploadFile/63f5c2/sp_msforeachtable-stored-procedure-in-sql-server-2012/ or here http://weblogs.sqlteam.com/joew/archive/2008/08/27/60700.aspx ) that can run a particular command on every database.

 

The final syntax I use comes like this (but, of course, you could use your commands and avoid shrinking or set autoshrink if it suits your environment).

EXEC sp_MSforeachdb ‘USE [?]; print ”?”;  ALTER DATABASE [?] SET RECOVERY SIMPLE; CHECKPOINT; DBCC SHRINKDATABASE ([?],10); ‘

 

Disclaimer: I am not in any case saying that simple recovery model is ok for production.

Hope this post would be useful.

 

SharePoint : Clicking the icon in Type column is highlighting the item instead of launching the document

Our customer has complained that in the old SharePoint they used to have, they could click on the document Icon, and this would open the document. In a new SharePoint, click makes a selection click in the list.

So the customer really wanted us to make this icons clickable.

I have found a number of solutions, and they all were not satisfactory for me.

Official Microsoft answer:

https://support.microsoft.com/en-us/kb/2457975

suggests to change the default xsl file on the server. WE have Office 365.

One of the most interesting solutions was here

https://spdociconlink.codeplex.com

(

you do not have to install the whole solution, as the core you can find in this file

https://spdociconlink.codeplex.com/SourceControl/latest#SPDocIconLink/SPDocIconLink/ControlTemplates/SPDocIconLink/SPDocIconLink.ascx

which just does a CSR override for the DocIcon field.

)

The disadvantages of this solution:

  1. Checkin/Checkout status is not shown. Usually there is a little override icon.
  2. When you have an OWA, the clicks on the documents does not open the editor, instead, the file is getting downloaded.

So I came with the solution that reuses the built-in functions, and so has all advantages of the proper icon and the opening of the OWA files.

function CustomIcon(ctx, field, listItem, listSchema) {
if (ctx.CurrentItem.FSObjType == ‘1’) { /* a folder*/
var ret = [];
ret.push(ComputedFieldWorker.DocIcon(ctx, field, listItem, listSchema));
}
else {
var ret = [];
ret.push(“<a href=\”” + ctx.CurrentItem.FileRef);
ret.push(“\” onmousedown=\”return VerifyHref(this,event,'”);
ret.push(listSchema.DefaultItemOpen);
ret.push(“‘,'”);
ret.push(listItem[“HTML_x0020_File_x0020_Type.File_x0020_Type.mapcon”]);
ret.push(“‘,'”);
ret.push(listItem[“serverurl.progid”]);
ret.push(“‘)\” “);
ret.push(“>”);
ret.push(ComputedFieldWorker.DocIcon(ctx, field, listItem, listSchema));
ret.push(“</a>”);
}
return ret.join(”);
}

(function () {
var overrideCtx = {};

overrideCtx.Templates = {};
overrideCtx.Templates.Fields = { ‘DocIcon’: { ‘View’: CustomIcon } };
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
})();

 

Follow

Get every new post delivered to your Inbox.