Automatic Creation of Managed and Crawl Properties


SharePoint 2013/2016 automatically generates managed and crawl properties for site columns. This makes the life of site collection administrator lot easier. In this post I will put a real example of how to test it.

Step 1

Create Site columns and content type and add it to a list. I used the PowerShell below to do that

Add-PSSnapIn “Microsoft.SharePoint.Powershell”

#Get the site collection and web object

$siteColl = Get-SPSite -Identity “https://portal16.contoso.com/”

function Create-SiteColumnText ($siteColl, $CustomColumn)

{

$rootWeb = $siteColl.RootWeb

#Assign fieldXMLString variable with field XML for site column

$fieldXMLString = “<Field Type=’Text’ Name=’$CustomColumn’

Description=’Indicate date of last and next meeting and names of current members.’

DisplayName=’$CustomColumn’

StaticName=’$CustomColumn’

Group=’Custom Columns’

Hidden=’FALSE’

Required=’FALSE’

Sealed=’FALSE’

ShowInDisplayForm=’TRUE’

ShowInEditForm=’TRUE’

ShowInListSettings=’TRUE’

ShowInNewForm=’TRUE’></Field>”

#See field XML on console

#write-host $fieldXMLString

#Create site column from XML string

$rootWeb.Fields.AddFieldAsXml($fieldXMLString)

Write-Host “Column Added”

}

function Create-SiteColumnChoice ($siteColl, $CustomColumn)

{

$rootWeb = $siteColl.RootWeb

#Assign fieldXMLString variable with field XML for site column

$fieldXMLString = “<Field Type=’Choice’

Name=’$CustomColumn’

Description=’Choice.’

Format=’Dropdown’

DisplayName=’$CustomColumn’

StaticName=’$CustomColumn’

Group=’Custom Columns’

Hidden=’FALSE’

Required=’FALSE’

Sealed=’FALSE’

ShowInDisplayForm=’TRUE’

ShowInEditForm=’TRUE’

ShowInListSettings=’TRUE’

ShowInNewForm=’TRUE’>

<Default>Specification</Default>

<CHOICES>

<CHOICE>Specification</CHOICE>

<CHOICE>Development</CHOICE>

<CHOICE>Test</CHOICE>

<CHOICE>Documentation</CHOICE>

</CHOICES>

</Field>”

#See field XML on console

#write-host $fieldXMLString

#Create site column from XML string

$rootWeb.Fields.AddFieldAsXml($fieldXMLString)

Write-Host “Column Added”

}

Create-SiteColumnText -siteColl $siteColl -CustomColumn “MyCustomColumn1”

Create-SiteColumnText -siteColl $siteColl -CustomColumn “MyCustomColumn2”

Create-SiteColumnText -siteColl $siteColl -CustomColumn “MyCustomColumn3”

Create-SiteColumnChoice -siteColl $siteColl -CustomColumn “MyCustomColumn4”

$web = $siteColl.RootWeb

$ctypeName = “MyCustomContentType”

$ctypeParent = $web.availablecontenttypes[“Item”]

$ctype = new-object Microsoft.SharePoint.SPContentType($ctypeParent, $web.contenttypes, $ctypeName)

$web.contenttypes.add($ctype)

$field = $web.fields.getfield(“MyCustomColumn1”)

$fieldLink = new-object Microsoft.SharePoint.SPFieldLink($field)

$ctype.fieldlinks.add($fieldLink)

$field = $web.fields.getfield(“MyCustomColumn2”)

$fieldLink = new-object Microsoft.SharePoint.SPFieldLink($field)

$ctype.fieldlinks.add($fieldLink)

$field = $web.fields.getfield(“MyCustomColumn3”)

$fieldLink = new-object Microsoft.SharePoint.SPFieldLink($field)

$ctype.fieldlinks.add($fieldLink)

$field = $web.fields.getfield(“MyCustomColumn4”)

$fieldLink = new-object Microsoft.SharePoint.SPFieldLink($field)

$ctype.fieldlinks.add($fieldLink)

$ctype.Update()

$ListTitle = “CustomList1”

$Web.Lists.Add($ListTitle, $ListTitle, 100)

$Library =$Web.Lists[$ListTitle]

$Library.ContentTypesEnabled = $true

$Library.ContentTypes.Add($ctype);

$Library.ContentTypes.Delete($Library.ContentTypes[0].Id)

$Library.ContentTypes.Count

$Library.Update()

$Array = @(“Specification”, “Development”, “Test”, “Documentation”)

for ($i = 1; $i -lt 5; $i++)

{

$Item = $Library.AddItem()

$Item[“Title”] = “Item $i”

$Item[“MyCustomColumn1”] = “Item $i Column $i”

$Item[“MyCustomColumn2”] = “Item $i Column $i”

$Item[“MyCustomColumn3”] = “Item $i Column $i”

$j = $i

$Item[“MyCustomColumn4”] = $Array[$j-1]

$Item.Update()

Write-Host “Done…” -ForegroundColor Green

}

clip_image002

Next Step would be to run a full crawl.

Open Central Administration – Application management – Manage service application – Search Service Application – Content Sources – Choose Full crawl from All Sites Content Source. You can run increment crawl in case your farm is large but my farm only has few items.

clip_image004

Click on Crawl Log – URL View – Type the URL of the custom list and click Search

clip_image006

You see that your items are indexed. Now wait for crawl status to idle.

clip_image008

Now go back to portal site – Open Site Settings – Under Site Collection Administrator click Search Schema

clip_image010

Type MyCustom in filter textbox and Click green arrow.

clip_image012

You would see that these columns are greyed out with clear message when you edit them.

clip_image014

“Automatically created managed property.MyCustomColumnX2OWSTEXT is an automatically created managed property. You can’t see any of its existing settings or which crawled properties are mapped to it, but you can map more crawled properties to it. If you save the managed property without making any changes, all settings will be deleted.”

Once you make a change in the property, the link become’s active.

clip_image016

These properties can now be used in Content Search Web part, reminders and display templates

You can make Search Rest to read the values as well

https://portal16.contoso.com/_api/search/query?querytext=’Item 1 Column 1’&selectproperties=’Path,Url,Title,Author,MyCustomColumn1OWSTEXT’

image

Advertisements

SharePoint 2013 Crawl Download File Size


If you are crawling large files in SharePoint 2013, you will see the following warning in your Search Logs.

“The file reached the maximum download limit. Check that the full text of the document can be meaningfully crawled”.  If you want to avoid this and crawl the large files you must increase this limit.

The default Download limit for crawler is 64MB.  You have to increase it to allow the crawling of videos.  Its a bit tricky decision.  I hope your videos are not Blueray DVDs converted to Mp4.  The max is 1024MB which you can set using PowerShell.  Review the video files and decide what size you must specify

$searchapp = Get-SPEnterpriseSearchServiceApplication
$searchapp.GetProperty(“MaxDownloadSize”)
#this command is just to check the current value; default is 64
$searchapp.SetProperty(“MaxDownloadSize”, <value>)
#where you replace <value> with the download limit; for example, 256

$searchapp.Update()

Now Run a Full Crawl.  Crawl might take extra time but will reduce the number of errors.

Update User Profile Feed Identifer after User Profile Re-Creation


The script can be used to re-create the user profile feed identifier property.  If this property is not set the user will not be able to use Social features like newsfeed on my site host.

Add-PSSnapin Microsoft.SharePoint.Powershell -ErrorAction SilentlyContinue
$MySiteHost = new-object Microsoft.SharePoint.SPSite("https://mysites.contoso.com/");  
$ServiceContext = [Microsoft.SharePoint.SPServiceContext]::GetContext($MySiteHost);  

$ProfileManager = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($ServiceContext);  
$profile = $ProfileManager.GetUserProfile("contoso\adamb"); 
$Site = $profile.PersonalSite
$Site | Select *
$Site.RootWeb.Created
#If Personal Site needs to be created.  The feed Identifier will be added automatically in that case.
#$profile.CreatePersonalSite()
$profile.FeedIdentifier
#If My Site Already Exist.
$microFeedId = ($Site.Url + ";1." + $Site.ID.ToString().Replace("-", "") + "." + $Site.RootWeb.ID.ToString().Replace("-", "") + "." + $Site.RootWeb.Lists["Microfeed"].ID.ToString().Replace("-", "") + ".0c37852b34d0418e91c62ac25af4be5b")
$profile["SPS-FeedIdentifier"].Value = $microFeedId
$profile.Commit()
$Site.Dispose()
$MySiteHost.Dispose()

Unable to Add the App – The App domain for this site has already been assigned


Recently I was working on configuring SharePoint hosted apps for our customer and while testing I saw this issue.  After completing the configuration of Apps I uploaded an app to app catalog and added the app to a site. The app worked without any issue but there was one gotcha.  I missed to replace an S in App Prefix which was set to Apps so my app url was https://apps-1234.apps.contoso.com but the orignal plan was to use “app” as prefix. 

So I removed the app from the site and app catalog.  Then went to CA and changed the app prefix to app from “apps”.  Uploaded the test app to catalog and then tried to add to the site and it failed with error. “Unable to add the app to the site please retry”

I started ULS Viewer and started live log stream and clicked retry and saw an amazing message.  SharePoint app was still using “apps” while I have updated it app.  I knew something was goofy and traditionally UI is that good with me when it comes to SharePoint. 

SPException thrown: Message: The App domain for this site has already been assigned.. Stack:    at Microsoft.SharePoint.Utilities.SPUtility.ThrowSPExceptionWithTraceTag(UInt32 tagId, ULSCat traceCategory, String resourceId, Object[] resourceArgs) 

Here is what I did.
Open SharePoint Management Shell as administrator (Farm Account).

Set-SPAppDomain -AppDomain apps.contoso.com
Set-SPAppSiteSubscriptionName -Name "app" -Confirm:$false

#Open Command Prompt as Administrator. Run the commands below.
net stop sptimerv4
iisreset
net start sptimerv4
#Repeat the above 3 on all servers in the farm.

I closed all the browsers and opened the site and click Retry from Site content page.  Bingo the app was added without any problem.

Add and Remove Web Site Binding using PowerShell


Windows Server 2008 R2 does not allow us to add a binding to same port twice.  Additionally you can not select a different SSL certificate for web app that is configured with https.  To do so you have to add binding by adding another IP address on the server and then add the binding on the IP and use a different SSL cert.  I saw people using a comand line utility like appcmd but frankly the syntax was pretty rough to use it.  So I tried wth PowerShell.  I was able to make a script that allows you to add a remove a binding as required.  The below script is used when I configured SharePoint Hosted apps on Windows server 2008 R2 environment where apps are configured to use different app domain.  Customer was getting certificate error so they wanted to use different SSL cert on App Web (No Host Header Web Application).  Just like I said before you just need an addition IP address on the WFES and then add a binding with * on that IP.  You can then remove the default binding using the same PowerShell script.

Import-Module WebAdministration
Get-Website
#Note the Web application Name
$ADFSApp = Get-Website -Name "NoHostHeader"
New-WebBinding -Name "NoHostHeader" -Protocol https -Port 443 -HostHeader "*" -IPAddress 35.0.0.11
#List the binding of the web appGet-WebBinding -Name "NoHostHeader" | Select *
#Remove the default Binding
Remove-WebBinding -Name "NoHostHeader" -BindingInformation "*:443:"

You can change the commands the way you want.  Do not try to modify the values of  https binding from UI as the changes apply to all web applications.  Be careful.  The script only targets one web app it is safe to execute.

Update Hidden View with PowerShell


Here is quick fix for an issue where AllItems view was set to blank and was set to hidden.  Here is how I fixed it.  Nothing fancy just some old Server OM calls in PowerShell.

First you have to list all the views to find it out what’s going wrong and put it in a list.

$SiteUrl = https://portal.contoso.com     
$ListUrl = "Discussions List"            

$Databases = @();
       
$Web = Get-SPWeb -Identity $SiteUrl            
if ($Web -ne $null)            
{
    $List = $Web.Lists[$ListUrl]
    foreach($view in $List.Views)
    {
        $ViewFile = $targetUrl.GetFile($view.Url)
        $Viewobj = New-Object PSObject
        Add-Member -input $Viewobj noteproperty 'ID'  $view.ID
        Add-Member -input $Viewobj noteproperty 'Title'  $view.Title
        Add-Member -input $Viewobj noteproperty 'CreatedBy'  $ViewFile.Author
        Add-Member -input $Viewobj noteproperty 'Modified' $ViewFile.TimeLastModified 
        Add-Member -input $Viewobj noteproperty 'ModifiedBy' $ViewFile.ModifiedBy 
        Add-Member -input $Viewobj noteproperty 'CreatedOn' $ViewFile.TimeCreated  
        Add-Member -input $Viewobj noteproperty 'Private' $view.PersonalView  
        Add-Member -input $Viewobj noteproperty 'Url' $view.Url  
        Add-Member -input $Viewobj noteproperty 'Hidden' $view.Hidden  
        $Databases += $Viewobj
          
    }
    #Export If Needed.        
    #$Databases  | Out-File C:\View.txt

}
#Select the View and Click OK in GridView
$aBadView= $Databases | Out-GridView -PassThru
$aBadView.ID

Now You have the View ID you have do it like below

$ID = [guid]("0b57d149-dbcc-4652-b72f-2fa024238301")    #$ID = [guid]($aBadView.ID)
$BadView = $List.Views[$ID]
$BadView.Title = "Subject"
$BadView.Hidden = $false
$BadView.Update()

Run the first part of script again to verify.

Remove and Add Index Partition – SharePoint 2013


Some times you will see that One of the index partition replica may showed as degraded with Yellow icon.  According to Microsoft this happens when the server has not completed the index replication or “Propogation” to its replica.  If this optiosn stays for long you can easily fix it.  You can use the script below.  In my example the server also had query component running on the same server.

 

Removing the Index Partition Replica

Add-PSSnapin Microsoft.SharePoint.PowerShell -ea 0 
#set Search Service Application
$ssa = Get-SPEnterpriseSearchServiceApplication
$active = Get-SPEnterpriseSearchTopology -SearchApplication $ssa -Active

 

Get-SPEnterpriseSearchComponent -SearchTopology $active | Out-File E:\TOPOLOGY4.TXT
NOTEPAD E:\TOPOLOGY4.TXT

#Note Down the IDs for the components and replace in below lines.

#copy the existing topology
$clone = New-SPEnterpriseSearchTopology -SearchApplication $ssa -Clone -SearchTopology $active

#remove the bad component, placing the name where [BAD COMPONENT NAME] is... remove the []
$ComponentID = (Get-SPEnterpriseSearchComponent -SearchTopology $clone -Identity "33e8886b-2bb6-4e18-8412-668d0e93906b").componentID
Remove-SPEnterpriseSearchComponent -Identity $ComponentID.GUID -SearchTopology $clone -confirm:$false

$ComponentID = (Get-SPEnterpriseSearchComponent -SearchTopology $clone -Identity "5bf9c520-3632-46e6-976b-f97a975fad1f").componentID
Remove-SPEnterpriseSearchComponent -Identity $ComponentID.GUID -SearchTopology $clone -confirm:$false

$ssa.PauseForIndexRepartitioning()
Set-SPEnterpriseSearchTopology -identity $clone
$ssa.ResumeAfterIndexRepartitioning()
 

Adding Index Partition Replica Back to the Topology

It would be better from now to go to bad index server, and re-create the index folder drive and probably reboot it.  Use the below script to add it back to the search configuration.

Add-PSSnapin Microsoft.SharePoint.PowerShell -ea 0 
#set Search Service Application
$ssa = Get-SPEnterpriseSearchServiceApplication
$active = Get-SPEnterpriseSearchTopology -SearchApplication $ssa -Active

#copy the existing topology
$clone = New-SPEnterpriseSearchTopology -SearchApplication $ssa -Clone -SearchTopology $active

#New-SPEnterpriseSearchQueryProcessingComponent -SearchTopology $clone -SearchServiceInstance "Server1"
#New-SPEnterpriseSearchIndexComponent -SearchTopology $clone -SearchServiceInstance "Server1" -IndexPartition 0 -RootDirectory "I:\SearchIndex"

$ssa.PauseForIndexRepartitioning()
Set-SPEnterpriseSearchTopology -identity $clone
$ssa.ResumeAfterIndexRepartitioning()