Sunday, May 28, 2017

Sort Custom Site Templates Alphabetically in SharePoint 2013

Custom Site Templates are really useful in SharePoint when you have to create sites using same settings, objects, content and look & feel. However there are couple of functionalities that should be already implemented in SharePoint but somehow they are not. We have to code for them mostly.

We generally create custom site templates in SharePoint and they show up in the Custom tab. However, working on a recent project we got a request from customer that the custom site templates are not in sort order in SharePoint 2013 which gives an ugly looks to end users for creating sites. There is no Out Of the Box solution provided by Microsoft for this so we had to write some custom code.

We have created a custom Site Collection level feature which just sort the custom site templates in SharePoint 2013 create new web page.

Here is how it looked Before and After the feature implementation.



Before:


After:


Unfortunately i can't share the complete code of the feature but this is what we are doing on Feature Activation.


Hope this will help someone to implement this functionality.

Happy SharePointing...!

Friday, May 19, 2017

DateTime Picker not working with site names which contains apostrophe ' in SharePoint 2013

I have noticed that some of the sites in my SharePoint 2013 farm which contains an Apostrophe ( ' ) in their name works fine except their DateTime Picker for any of the custom list. (The OOTB Calendar type list just works fine.)

If you create a custom list and add a DateTime type column in that list, in the NewForm.aspx the DateTime picker won't dropdown to select dates if the site has an Apostrophe ( ' ) in its name.

I have a site below in SharePoint 2013 (i have a little branding so don't get confused) where i created a simple custom list. I clicked the Calendar icon but no dropdown appeared.



Change the name of the site from Site Settings and removed the Apostrophe ' character.

Before


After



Tried to browse the site again and the clicked on Calendar icon again in the same form.


It worked... :)

Its Microsoft kind'a thing and till now i haven't heard that Microsoft noticed this issue and released any patch.

The issue is, the DateTime picker do not convert the ' character into %27 which is its HTML code. So in a result, the DateTime picker unable to get the dropdown.

This question really helped me to get around this. Thanks Victoria Xia for pointing out the root cause.

Happy SharePointing... :)

Monday, May 15, 2017

PowerShell Script : Mount Multiple Content Databases at once with SharePoint

Below is the code that you can use to mount multiple content databases with SharePoint (2010 or 2013 or 2016). Put all of the content databases names in DB.txt file and run the script.

1. Create text file with name “DB.txt” in the same directory where script file is present.
Write database names in “DB” file. 
Make it sure each name should be in new line and write End Point at the end as shown below.


2. Open SharePoint 2013 Management Shell


3. Change directory path to path where script file is saved.


Then type ./MountSPContentDB.ps1 and press enter key. (Copy the script in a file and name it MountSPContentDB.ps1) 
Provide web application url and press enter key.


Provide SqlServer name and instance. 

4. Result 
You can track the complete log file (named MountSPContentDB -current date and time) which you can find in the same directory where your script file is located. 

Script:
[code]$currentTime = Get-Date -Format o | foreach {$_ -replace ":", "."} New-Item $PSScriptRoot\UpgradeSPContentDB-$currentTime.txt -type file $webAppUrl = Read-Host "Please provide Web Application URL" $databaseServer = Read-Host "Please provide database server name" $DbArray = Get-Content -Path $PSScriptRoot\DB.txt function UpgradeSPContentDB() { Start-Transcript -Path "$PSScriptRoot\UpgradeSPContentDB-$currentTime.txt" foreach ($dbName in $DbArray) { if($dbName -ne "End Point") { try{ Mount-SPContentDatabase $dbName -DatabaseServer $databaseServer -WebApplication $webAppUrl -ErrorAction Stop Write-Output "$dbName is upgraded" } catch [System.Exception] { Write-Host $_.Exception.Message } } } Stop-Transcript } UpgradeSPContentDB[/code]

Components that could break after SharePoint upgrade

Although you can predict most of the stuff that could go wrong after a SharePoint upgrade or migration but still there are chances that you miss something. I have compiled a list of components that could break or stop working after you move to new SharePoint environment. I'll be updating this post whenever i found anything else breaking after SharePoint upgrade. I apologize for my rough formatting. :)


InfoPath:
Connections with external services and libraries.
Connection with User Profile Service Application.
When upgrading to 2013 from 2010, you need to update where fetching User Information like User Name User Friendly Name. SharePoint 2013 works on Claims Based Authentication so InfoPath 2010 Form Views may crash if you are showing view on user based.

OneNote:
OneNote Sync URL change
OneNote not syncing

Static URLs:
Static URL's used in Web Pages, Always use relative URLS

Connected Excel Files:
Data exported in Excel files could break if URL change after migration

Workflows:
SharePoint URLs in Workflow emails
Bindings of Users like Created By, Modified By could break with blank or a GUID showing in text box

Shared Calendars:
Shared Calendars are bind with a URL, If the URL changes after migration or upgradation, that might break the Calendars.

Custom JS/CSS:
If you have some custom pages which contains some custom JS or CSS and has to deal with something on the page, there is a strong possibility that it might break after the migration. As the master pages and layouts are different in MOSS 2007, SharePoint 2010 and SharePoint 2013, there could be a chance that your JS or CSS dealing with SharePoint's tags no longer work after upgrade.


Tuesday, April 11, 2017

Modifying SharePoint 2013 Search Service Topology All At Once

Its a routine work that we have to create/configure SharePoint Service Applications and Search Service Application is one of the major service that takes time after creation for configuration. Mostly there are three tier architecture where we customize SharePoint Search Service Topology in order to make it more stable, available and quick for content processing. In SharePoint 2010 it was simple through UI but in SharePoint 2013 you can do all of this stuff using PowerShell.

In my case, i have 2 APP servers, 2 WFE servers and 1 DB server. Below is the PowerShell script where you can replace your servers names only and get your Search Topology configured like my farm. Putting end result screenshot of my Search Topology. My APP01 server is the Central Administration server.


Note: Make sure your Search Service Application has been started on all target servers. You can use below command for each server to start the service.




[code] $ssa = Get-SPEnterpriseSearchServiceApplication $active = Get-SPEnterpriseSearchTopology -SearchApplication $ssa -Active $clone = New-SPEnterpriseSearchTopology -SearchApplication $ssa -Clone –SearchTopology $active $wfe1 = Get-SPEnterpriseSearchServiceInstance -Identity "MY-WFE01" $wfe2 = Get-SPEnterpriseSearchServiceInstance -Identity "MY-WFE02" $App2 = Get-SPEnterpriseSearchServiceInstance -Identity "MY-APP02" #Add MY-APP02 Server as Admin, Crawl, Content Processing and Analytic Processing Component New-SPEnterpriseSearchAdminComponent -SearchTopology $clone -SearchServiceInstance $App2 New-SPEnterpriseSearchCrawlComponent -SearchTopology $clone -SearchServiceInstance $App2 New-SPEnterpriseSearchContentProcessingComponent -SearchTopology $clone -SearchServiceInstance $App2 New-SPEnterpriseSearchAnalyticsProcessingComponent -SearchTopology $clone -SearchServiceInstance $App2 #Add MY-WFE01 as QueryProcessing And IndexComponent New-SPEnterpriseSearchQueryProcessingComponent -SearchTopology $clone -SearchServiceInstance $wfe1 New-SPEnterpriseSearchIndexComponent –SearchTopology $clone -SearchServiceInstance $wfe1 -IndexPartition 0 #Add MY-WFE02 as QueryProcessing And IndexComponent New-SPEnterpriseSearchQueryProcessingComponent -SearchTopology $clone -SearchServiceInstance $wfe2 New-SPEnterpriseSearchIndexComponent –SearchTopology $clone -SearchServiceInstance $wfe2 -IndexPartition 0 #Remove MY-APP01 from Index Component $indexComponent = (Get-SPEnterpriseSearchComponent -SearchTopology $clone -Identity IndexComponent1) #To verify that you have correct server, type $indexComponent on PowerShell now and verify server name Remove-SPEnterpriseSearchComponent -Identity $indexComponent.componentID.GUID -SearchTopology $clone -confirm:$false #Remove MY-APP01 from QueryProcessing Component $queryComponent = (Get-SPEnterpriseSearchComponent -SearchTopology $clone -Identity QueryProcessingComponent1) #To verify that you have correct server, type $queryComponent on PowerShell now and verify server name Remove-SPEnterpriseSearchComponent -Identity $queryComponent.componentID.GUID -SearchTopology $clone -confirm:$false Set-SPEnterpriseSearchTopology -Identity $clone [/code]

Tuesday, February 28, 2017

Find attached Workflows to a list in SharePoint 2013 using PowerShell

This Script will iterate through all the provided Site Collections and export the attached Workflows with a list in a CSV file. It will also generate a log file that contains the script execution logs.

It will export the following items.

1. Site URL
2. Web URL
3. List Name
4. Attached Workflows Count




1.Text file containing database names

Create text file with name “DB.txt” in the same directory where script file is present.
Write database names in “DB” file. 
Make it sure each name should be in new line and write End Point at the end as shown below.


2.Open SharePoint 2013 Management Shell


3.Change directory path


Then type ./ WorkflowFinder.ps1 and press enter key.

3. Results
2.       Result will be saved in “WorkflowFinder.csv” file which you can find in the same directory where your script file is located.
You can also track the complete log file (named WorkflowFinder -current date and time) which you can find in the same directory where your script file is located. 

Output CSV will look like this.


PowerShell Scipt

[code] $currentTime = Get-Date -Format o | foreach {$_ -replace ":", "."} New-Item $PSScriptRoot\WorkFlowFinder-$currentTime.txt -type file New-Item $PSScriptRoot\WorkFlowFinder.csv -type file -Force $SiteCollectionArray = Get-Content -Path $PSScriptRoot\SiteCollections.txt Start-Transcript -Path "$PSScriptRoot\WorkFlowFinder-$currentTime.txt" $UtilStartTime = "Utility Start Time: " $startTime = Get-Date -Format F $UtilStartTime + $startTime $outputFile = "$PSScriptRoot\WorkFlowFinder.csv" #Initialize Workflow Count variable $workflowcount = 0 $outputHeader = "Site URL" + "`t" + "Web Url" + "`t" +" List Name" + "`t" + " Total Items " > $outputFile #Write-Host $DbArray.Length foreach($siteCol in $SiteCollectionArray) { if($siteCol -ne "End Point") { $SPSite =Get-SPSite -Identity $siteCol foreach($SPWeb in $SPSite.AllWebs) { foreach($SPList in $SPWeb.Lists) { foreach($wf in $SPList.WorkflowAssociations) { if ($wf.Name -notlike "*Previous Version*") { $workflowcount += 1 } } #Write-Host $workflowcount if($workflowcount -gt 0) { $output = $SPSite.Url + "`t" + $SPWeb.Url + "`t" + $SPList.Title + "`t" + $workflowcount >> $outputFile Write-Output $output } $workflowcount = 0 } } } } $UtilEndTime = "Utility End Time: " $endTime = Get-Date -Format F $UtilEndTime + $endTime Stop-Transcript [/code]


Thursday, February 23, 2017

Get All Web Templates Using PowerShell SharePoint 2013

This script will traverse all the site collections and extract its template name.

1.Site Collections File

Create text file with name “SiteCollections.txt” in the same directory where script file is present.
Write site collections urls in “SiteCollections” file. 
Make it sure each url should be in new line and write “End Point” at the end as shown below.


2. Save Code and Run
Save below code and Open SharePoint Management Shell. Change the directory to where the code and SiteCollections.txt file is saved and run the code script file.

The output would be like below.


PS Script:

[code] $currentTime = Get-Date -Format o | foreach {$_ -replace ":", "."} New-Item $PSScriptRoot\GetAllWebTemplates-$currentTime.txt -type file $SiteCollectionArray = Get-Content -Path $PSScriptRoot\SiteCollections.txt Start-Transcript -Path "$PSScriptRoot\GetAllWebTemplates-$currentTime.txt" $UtilStartTime = "Utility Start Time: " $startTime = Get-Date -Format F $UtilStartTime + $startTime foreach ($url in $SiteCollectionArray) { if($url -ne "End Point") { try{ $site=Get-SPSite -Identity $url } catch {} foreach($web in $site.AllWebs) { if($web) { $output = $site.URL + "`t" + $web.URL + "`t" + $web.WebTemplate + "`t" + $web.WebTemplateId Write-Output $output $web.Dispose() } else { Write-Output "Site Doesn't exist" } } } } $UtilEndTime = "Utility End Time: " $endTime = Get-Date -Format F $UtilEndTime + $endTime Stop-Transcript [/code]