Script to import, export and compare crawled and managed properties between SharePoint farms

I got really excited when using the export-import-mp.ps1 script by Riccardo Celesti that can export and import managed properties between search service applications in SharePoint. However, I would like to compare all exported properties of one environment to a fresh “vanilla” installation so that a documentation can be created.

Export the modified managed properties

The export-import-mp script is just great, it will export and import managed properties to and from a CSV file. If you export all settings then it takes a fair amount of time, but it works perfectly.

First, I download the script export-import-mp.ps1 and export all properties (without filter) of the source farm as:

 .\export-import-mp.ps1 –serviceapp “Search Service Application” -export

 Note that the script can commonly cause rights issues if the account running the script does not have enough privileges in the database. In this case, you get the following error:

Get-SPEnterpriseSearchMetadataManagedProperty : There was an internal problem connecting to or querying the database.

Simply increase your rights temporarily on the target database server or run with a system account.

Generate a list of unique customizations

I then run my modified script diff-mp.ps1 on a vanilla farm using the output export-managed-properties.csv from the source farm as:

.\diff-mp.ps1 –serviceapp “Search Service Application”

The script creates a new file called export-managed-properties-diff.csv. This CSV can now be used to create an Excel report over my farm managed properties and form a documentation.

Export and import crawled properties

I also found a need to generate my crawled properties, as there was a bit of difference between my environments, even after several full crawls. This specifically helped me with user profile properties.

You can use the script exactly as before using the new script name export-import-cp.ps1. There is also a diff script for the crawled properties, named diff-cp.ps1.

Script Sources

Here are the script sources for the new files.

export-import-cp.ps1

#----------------------------------------------------------------------------- 
#
Name: export-import-cp.ps1
#
Description: This script has three switch to:
#
- export a list of crawled properties (optionally filtered)
#
- import a list of crawled properties with crawled property mapping
#
- delete a list of crawled properties
#

#
Usage: Run the script passing paramters ServiceApp, Import|Export|Delete and Filter
#
By: Tobias Lekman ([email protected]), modified original version by Riccardo Celesti blog.riccardocelesti.it
#
-----------------------------------------------------------------------------

[CmdletBinding(DefaultParameterSetName = "Export")]
Param([Parameter(Mandatory=$true)]
[String]
$serviceapp,
[Parameter(Mandatory
=$false,ParameterSetName='Export')]
[Parameter(Mandatory
=$true,ParameterSetName ="Delete")]
[String]
$filter,
[Parameter(ParameterSetName
='Import')]
[
switch]$import,
[Parameter(ParameterSetName
='Export')]
[
switch]$export,
[Parameter(ParameterSetName
='Delete')]
[
switch]$delete
)
if ((gsnp MIcrosoft.SharePoint.Powershell -ea SilentlyContinue) -eq $null){
asnp Microsoft.SharePoint.Powershell
-ea Stop
}
$logfile = ".\export-crawled-properties.csv"
$importlog = ".\import-crawled-properties.log"
$importlogerr = ".\import-crawled-properties-errors.log"
if ((Get-SPEnterpriseSearchServiceApplication $serviceapp -ea SilentlyContinue) -eq $null){
Write
-Host "Enterprise Search Service Application $serviceapp has not been found" -ForegroundColor Red
exit
}
else {
$ssa = Get-SPEnterpriseSearchServiceApplication $serviceapp
Write
-Host "Enterprise Search Service Application $serviceapp has been found" -ForegroundColor Green
}
if ($export){
if ((Get-ChildItem -Name $logfile -ea SilentlyContinue) -ne $null){
Clear
-Content $logfile
ac
$logfile "Name,CategoryName,Propset,IsMappedToContents,IsNameEnum,SchemaId,VariantType";
}
else {
ac
$logfile "Name,CategoryName,Propset,IsMappedToContents,IsNameEnum,SchemaId,VariantType";
}
if ($filter -ne $null){
Get
-SPEnterpriseSearchMetadataCrawledProperty -SearchApplication $ssa -Limit All | ?{$_.Name -like "$($filter)*"} | %{

$cp = $_;
ac
$logfile "$($cp.Name),$($cp.CategoryName),$($cp.Propset),$($cp.IsMappedToContents),$($cp.IsNameEnum),$($cp.SchemaId),$($cp.VariantType)"
}
}
else {
Get
-SPEnterpriseSearchMetadataCrawledProperty -SearchApplication $ssa -Limit All | %{

$cp = $_;

ac
$logfile "$($cp.Name),$($cp.CategoryName),$($cp.Propset),$($cp.IsMappedToContents),$($cp.IsNameEnum),$($cp.SchemaId),$($cp.VariantType)"
}
}
}
if ($import){
if ((Get-ChildItem $logfile -ea SilentlyContinue) -eq $null){
Write
-Host "The export file has not been found" -ForegroundColor Red
exit
}
else {
Import
-Csv $logfile -Delimiter "," | %{
$cp = $_;
if ((Get-SPEnterpriseSearchMetadataCrawledProperty -SearchApplication $ssa -Limit All | ?{$_.Name -eq $cp.Name} -ea SilentlyContinue) -eq $null){
try {
$newcp = New-SPEnterpriseSearchMetadataCrawledProperty -SearchApplication $ssa -Name $cp.Name -PropSet $cp.PropSet -Category $cp.CategoryName -IsNameEnum:([bool]::Parse($cp.IsNameEnum)) -VariantType:([int]::Parse($cp.VariantType)) -IsMappedToContents:([bool]::Parse($cp.IsMappedToContents)) -EA Stop
ac
$importlog "$(Get-Date),$($cp.Name),[INF],Crawled Property,"

} catch {
Write
-Host "Something went wrong :) $($Error[0].Exception.Message)" -ForegroundColor Red
ac
$importlog "$(Get-Date),$($cp.Name),[ERR],"
ac
$importlogerr "$(Get-Date),$($cp.Name),[ERR],Crawled Property,$($Error[0].Exception.Message)"
}
}
else {
Write
-Host "Crawled property $($cp.Name) already exists" -ForegroundColor Red
ac
$importlog "$(Get-Date),$($cp.Name),[WRN],Crawled Property,Crawled property already exists"
}
}
}
}
if ($delete){
Get
-SPEnterpriseSearchMetadataCrawledProperty -SearchApplication $ssa -Limit All | ?{$_.Name -like "$($filter)*"} | %{
$cp = $_;
$cp.Delete();
}
}

diff-mp.ps1


#----------------------------------------------------------------------------- 
#
Name: diff-mp.ps1
#
Description: Creates a diff of exported managed properties (use export-import-mp.ps1 first)
#

#
Usage: Run the script passing paramters ServiceApp
#
By: Tobias Lekman ([email protected]), modified from original by Riccardo Celesti blog.riccardocelesti.it
#
-----------------------------------------------------------------------------

Param([Parameter(Mandatory=$true)]
[String]
$serviceapp
)
if ((gsnp MIcrosoft.SharePoint.Powershell -ea SilentlyContinue) -eq $null){
asnp MIcrosoft.SharePoint.Powershell
-ea Stop
}
$logfile = ".\export-managed-properties.csv"
$difffile = ".\export-managed-properties-diff.csv"
if ((Get-SPEnterpriseSearchServiceApplication $serviceapp -ea SilentlyContinue) -eq $null){
Write
-Host "Enterprise Search Service Application $serviceapp has not been found" -ForegroundColor Red
exit
}
else {
$ssa = Get-SPEnterpriseSearchServiceApplication $serviceapp
Write
-Host "Enterprise Search Service Application $serviceapp has been found" -ForegroundColor Green
}
if ((Get-ChildItem -Name $difffile -ea SilentlyContinue) -ne $null){
Clear
-Content $difffile
ac
$difffile "Name,Description,ManagedType,Searchable,FullTextQueriable,Queryable,Retrievable,Refinable,Sortable,HasMultipleValues,SafeForAnonymous,Mapping";
}
else {
ac
$difffile "Name,Description,ManagedType,Searchable,FullTextQueriable,Queryable,Retrievable,Refinable,Sortable,HasMultipleValues,SafeForAnonymous,Mapping";
}
if ((Get-ChildItem $logfile -ea SilentlyContinue) -eq $null){
Write
-Host "The export file has not been found" -ForegroundColor Red
exit
}
else {
$count = 0;
Import
-Csv $logfile -Delimiter "," | %{
$mp = $_;
if ((Get-SPEnterpriseSearchMetadataManagedProperty -SearchApplication $ssa -Identity $mp.Name -ea SilentlyContinue) -eq $null){
ac
$difffile "$($mp.Name),$($mp.Description),$($mp.ManagedType),$($mp.Searchable),$($mp.FullTextQueriable),$($mp.Queryable),$($mp.Retrievable),$($mp.Refinable),$($mp.Sortable),$($mp.HasMultipleValues),$($mp.SafeForAnonymous),$($mp.Mapping)"
Write
-Host $mp.Name"exported"
}
}
Write
-Host "Exported"$count" properties." -ForegroundColor Green
}

diff-cp.ps1


#----------------------------------------------------------------------------- 
#
Name: diff-cp.ps1
#
Description: Creates a diff of exported crawled properties (use export-import-cp.ps1 first)
#

#
Usage: Run the script passing paramters ServiceApp
#
By: Tobias Lekman ([email protected]), modified from original by Riccardo Celesti blog.riccardocelesti.it
#
-----------------------------------------------------------------------------

Param([Parameter(Mandatory=$true)]
[String]
$serviceapp
)
if ((gsnp MIcrosoft.SharePoint.Powershell -ea SilentlyContinue) -eq $null){
asnp MIcrosoft.SharePoint.Powershell
-ea Stop
}
$logfile = ".\export-crawled-properties.csv"
$difffile = ".\export-crawled-properties-diff.csv"
if ((Get-SPEnterpriseSearchServiceApplication $serviceapp -ea SilentlyContinue) -eq $null){
Write
-Host "Enterprise Search Service Application $serviceapp has not been found" -ForegroundColor Red
exit
}
else {
$ssa = Get-SPEnterpriseSearchServiceApplication $serviceapp
Write
-Host "Enterprise Search Service Application $serviceapp has been found" -ForegroundColor Green
}
if ((Get-ChildItem -Name $difffile -ea SilentlyContinue) -ne $null){
Clear
-Content $difffile
ac
$difffile "Name,CategoryName,Propset,IsMappedToContents,IsNameEnum,SchemaId,VariantType";
}
else {
ac
$difffile "Name,CategoryName,Propset,IsMappedToContents,IsNameEnum,SchemaId,VariantType";
}
if ((Get-ChildItem $logfile -ea SilentlyContinue) -eq $null){
Write
-Host "The export file has not been found" -ForegroundColor Red
exit
}
else {
$count = 0;
Import
-Csv $logfile -Delimiter "," | %{
$cp = $_;
if ((Get-SPEnterpriseSearchMetadataCrawledProperty -SearchApplication $ssa -Limit All | ?{$_.Name -eq $cp.Name} -ea SilentlyContinue ) -eq $null){
ac
$difffile "$($cp.Name),$($cp.CategoryName),$($cp.Propset),$($cp.IsMappedToContents),$($cp.IsNameEnum),$($cp.SchemaId),$($cp.VariantType)"
Write
-Host $cp.Name"exported"
}
}
Write
-Host "Exported"$count" properties." -ForegroundColor Green
}