Home - SPCrew- Another great SharePoint blog site
Search
Home

SEARCH


Search All content on this site

  ​​Recent Blogs


May 02
HTML in SharePoint Calculated Fields (display a link)

SCENARIO:

Field1 is a text field that is populated with a URL (e.g http://www.google.com)

Field2 is a text field that has a title for that url (e.g Google)

The idea is to create a calculated field that will take the values from field1 and field2 and create this: Google

 

STEPS:

  1. Create a calculated field
  2. IMPORTANT: choose number as the type for this field, not a single line of text

     

    The reason being is when you choose number it forces the formula to be "Calculated" versus simply displayed.

     

  3. Enter in the formula

    =CONCATENATE("<DIV><a href='",[Field1],"'>",Field2,"</a></DIV>")

     

  4. Click "OK".

And that's it.

 

NOTE: This approach works great for all fields except the ID field. You will have to come up with a work around for that in order for you to use the ID field. One approach I used was to create a dummy field to store the ID field and then I used an event receiver to update that field upon item creation.  The other is to use jquery.

April 05
PowerShell Script to Migrate Search MetaData Properties for SharePoint 2010

A little Background:

On one of the projects I was involved with, Search Metadata properties were heavily being leveraged. When creating staging or production environments, the task of creating nearly 150 Metadata columns was becoming tedious. We first wrote a script that would manually enter in the names of the metadata properties, and then if new properties were added would mean that we would have to update the script. This left lots of room for error, as well as lots of lines of code. 

We modified the script to dynamically get all the properties and create xml files to represent different portions of the metadata properties and then use the xml file to create the new properties in the destination environment.

To get a successful MetaData Property for search, you need:

  1. Ensure crawled property exists (run a crawl)
  2. Create a new managed property.
  3. Create a property mapping to map the crawled property to the managed property.

Let us take a look at an example of a metadata property in the source environment at (/_admin/search/listmanagedproperties.aspx) in central admin.

 

"IsProBono" is the name of the Managed Data Property.

Clicking on the property will give you this

 

         

Notice that the name of the Crawled Property is "ows_Pro_x00200_Bono_x0020_Event". Highlighted in yellow are the attributes of the Search  Metadata property and we'll have to consider them when creating the property in the destination server.

 Here are the steps we're going to take in order to move the mappings from one environment to another.

  1. Create a custom Export xml file that will have the following as a template.

<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">

<Obj>

<CrawledPropertyName></CrawledPropertyName>

<ManagedPropertyName></ManagedPropertyName>

<PropertyType></PropertyType>

<IncludeInMd5></IncludeInMd5>

<RespectPriority></RespectPriority>

<FullTextQueriable></FullTextQueriable>

<EnableScoping></EnableScoping>

<HasMultipleValues></HasMultipleValues>

</Obj>

</Objs>

  1. Create an export script on the source server to populate this xml file with nodes.
  2. Make sure you have done a full crawl of the destination content source. This will make sure that all the necessary crawled properties are created.
  3. Move the xml file to the destination server and run the import script to create the Managed Properties and Mapped Properties

ONTO the CODE

         

EXPORTS

  • First create a script that will export the metadata properties on the source server and put that content inside three separate xml files.

    #Export Crawled Properties

$DATE = get-date

$LogPath = "c:\Logs"

$LogFileName = "SearchService.txt"

$FilePath = $LogPath + "\" + $LogFileName

$logFileCreated = $False

#Method to take care of writing log files to a file on the server.

function write-log([string]$label, [string]$logMsg)

{

    if($logFileCreated -eq $False)

    {

        write-host "Creating log file..."

        if((Test-Path -path $LogPath) -ne $True)

        {

            write-host "Provide proper values to LogPath folder" -ForegroundColor Red

        }

        else

        {

            Add-Content -Path $FilePath -Value $logHeader

            $script:logFileCreated = $True

            write-host "Log file created..."

        }

    }

    else

    {

        [string]$info = [System.String]::Format("[$Date] {0}: {1}",$label, $logMsg)

        Add-Content -Path $FilePath -Value $info

    }

}

       

       

 #Load the Sharepoint Powershell snapin

$snapin = Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.SharePoint.Powershell'}

       

if ($snapin -eq $null)

{

    Write-Host "Loading SharePoint Powershell Snapin"

    Add-PSSnapin "Microsoft.SharePoint.Powershell"

}

       

$CrawledPropertyName = "ows*"

#Name of the Search Service Application

$SearchService = "Search Service Application"

#Path to the location of the config xml files

$PathXmlFiles = "C:\deploy\xml"

$path = "C:\deploy\xml\exportedfile.xml"

$xmlfile = New-Object XML

#Load the template xml config file

$xmlfile.Load($path)  

     

#These three lines get the managed properties, crawl properties, and mapped properties of the service and also create

#xml file copies of those.

$prop = Get-SPEnterpriseSearchMetadataCrawledProperty -SearchApplication $SearchService | Where-Object {$_.name -like $CrawledPropertyName} | Export-Clixml $PathXmlFiles\getCrawledMetaDataProperty.xml

$mp = Get-SPEnterpriseSearchMetadataManagedProperty -SearchApplication $SearchService | Export-Clixml $PathXmlFiles\getMetaDataProperty.xml

$map = Get-SPEnterpriseSearchMetadataMapping -SearchApplication $SearchService -ManagedProperty $mp | Export-Clixml $PathXmlFiles\getCrawledMetaDataMapProperty.xml

     

$xmlmetadata3 = Import-Clixml $PathXmlFiles\getCrawledMetaDataMapProperty.xml  

try

{

    $oldObject = (@($xmlfile.Objs.obj)[0])

    foreach ($mapdata in $xmlmetadata3)

    {

        $created2 = Get-SPEnterpriseSearchMetadataManagedProperty -SearchApplication $SearchService | Where-Object {$_.PID -eq $mapdata.ManagedPid }  

        #get a reference to the managed property

        $managedpropertyRef = Get-SPEnterpriseSearchMetadataManagedProperty -SearchApplication $SearchService | Where-Object {$_.PID -eq $mapdata.ManagedPid }

        #get a reference to the crawl property

        $crawledpropertyRef = Get-SPEnterpriseSearchMetadataCrawledProperty -SearchApplication $SearchService | Where-Object {$_.Name -eq $mapdata.CrawledPropertyName }

        $message = "Crawled Property Name: " +$mapdata.CrawledPropertyName +" Mapped to ManagedPropertyName: " +$managedpropertyRef.Name

        Write-Host $message

        write-log ("!!INFO!!" , $message)

        #add new xml node

        $newObject = $oldObject.Clone()

        $newObject.CrawledPropertyName = $mapdata.CrawledPropertyName

        $newObject.ManagedPropertyName = $managedpropertyRef.Name  

        $propertyType = [int]$managedpropertyRef.ManagedType

        $includeInMd5 =[int]$managedpropertyRef.IncludeInMd5

        $respectPriority =[int]$managedpropertyRef.RespectPriority

        $fullTextQueriable =[int]$managedpropertyRef.FullTextQueriable

        $enableScoping = [int]$managedpropertyRef.EnabledForScoping

        $hasMultipleValues = [int]$managedpropertyRef.HasMultipleValues

        #set the managed property settings

        $newObject.PropertyType = [string]$propertyType.ToString()

        $newObject.IncludeInMd5 = [string]$includeInMd5.ToString()

        $newObject.RespectPriority = [string]$respectPriority.ToString()

        $newObject.FullTextQueriable = [string]$fullTextQueriable.ToString()

        $newObject.EnableScoping = [string]$enableScoping.ToString()

        $newObject.HasMultipleValues = [string]$hasMultipleValues.ToString()

        $xmlfile.objs.AppendChild($newObject) > $null

       

       

    }

    # remove objects with undefined ManagedPropertyName (remove template)

    $xmlfile.objs.obj | Where-Object {$_.ManagedPropertyName -eq ""} | ForEach-Object {[void]$xmlfile.objs.RemoveChild($_)}

    $xmlfile.Save("$path")

       

}catch

{

}

  • Running this script will create three xml files in the c:\deploy\xml path, and update an existing one (exportedfile.xml)

 

  • If I look at the three xml files and do a search for "bono" here is what I see.
    • In the getCrawledMetaDataMapProperty.xml file I see

    • This entry maps the crawled property "ows_Pro_x005f_x0020_Bono_X005f_x0020_Event" to Managed Property with id of "434"
    • Next let's take a look at the Crawled getCrawledMetaDataProperty.xml file
    • Here you see the name that the Mapped xml will be using to map to the crawled property.
    • Now let's take a look at the getMetaDataProperty.xml file
    • Notice the PID. This is the id of this particular property. You'll notice it being referenced in the getCrawledMetaDataMapProperty.xml file in the first screen shot.
    • Now that we all three xmls , we're going to perform the import into the destination server.
    • The exported file has all the necessary attributes needed to create a managed property and to map that property to a crawled property on the destination server and thus create a Mapped Property

IMPORTS

  • The "exportedfile.xml" xml file into some directory on the destination server.
  • Make references to it in your import script

$xml = [xml](Get-Content c:\deploy\xml\exportedfile.xml )

       

  • Loop through each one and check to see if those objects exist in the database, if so do nothing otherwise create them
  • #For Crawl Properties if the items don't exist, then simply put an entry in the log file for your records.
  • #For Managed Properties – loop through each section and create scoping, and other attributes and set a number for the true/false value (the xml shows it as true false, but the
  • Powershell method uses 1 or 0's.

try

    {

       

        $external_counter = 0

        $total_counter = 0

        foreach ($mapdata in $xml.Objs.Obj)

        {

            if($mapdata) {

                $total_counter ++

                $created = Get-SPEnterpriseSearchMetadataCrawledProperty -SearchApplication $SearchService | Where-Object {$_.Name -eq $mapdata.CrawledPropertyName }

       

                if ($created)

                {

                    Write-Host "Crawled Property " + $created.Name " already present" -ForegroundColor:Yellow

                    $message = "Crawled Property "+ $created.Name + " already present"

                    write-log ("!!INFO!!",$message)

                    #get a reference to the managed property

                    $managedpropertyRef = Get-SPEnterpriseSearchMetadataManagedProperty -SearchApplication $SearchService | Where-Object {$_.Name -eq $mapdata.ManagedPropertyName }

                    #get a reference to the crawl property

                    $crawledpropertyRef = Get-SPEnterpriseSearchMetadataCrawledProperty -SearchApplication $SearchService | Where-Object {$_.Name -eq $mapdata.CrawledPropertyName }

                    if($managedpropertyRef) {

                        #if Managed Property does not exist then create it

                        $createdMap = Get-SPEnterpriseSearchMetadataMapping -SearchApplication $SearchService -ManagedProperty $managedpropertyRef

                        if($createdMap)

                        {

                            write-log ("!!INFO!!" , "Mapped Property Exists for " + $managedpropertyRef.Name)

                        }else{

                            New-SPEnterpriseSearchMetadataMapping -SearchApplication $SearchService -ManagedProperty $managedpropertyRef -CrawledProperty $crawledpropertyRef

                            write-log ("!!INFO!!" , "New Mapped Property created for "+ $managedpropertyRef.Name)

                            $external_counter ++

                        }

                    }

                    else {

                        try

                        {

       

                            #create the managed property and then create the mapping

                            $propertyType = [int]$mapdata.PropertyType

                            $includeInMd5 =[int]$mapdata.IncludeInMd5

                            $respectPriority =[int]$mapdata.RespectPriority

                            $fullTextQueriable =[int]$mapdata.FullTextQueriable

                            $enableScoping = [int]$mapdata.EnabledForScoping

                            $hasMultipleValues = [boolean]$hasMultipleValues

                            #write-log ("!!INFO!!" , "About to create a new Managed Property -Name "+ $mapdata.ManagedPropertyName +" -Type "+$propertyType) #+" -EnabledForScoping "+ $enableScoping + " -FullTextQueriable "+$fullTextQueriable + " -IncludeInMd5 "+$includeInMd5 + " -RespectPriority "+$respectPriority)

       

                            $managedproperty = New-SPEnterpriseSearchMetadataManagedProperty -SearchApplication $SearchService -Name $mapdata.ManagedPropertyName -Type $propertyType -EnabledForScoping $enableScoping -FullTextQueriable $fullTextQueriable -IncludeInMd5 $includeInMd5 -RespectPriority $respectPriority

                            if($managedproperty -ne $null){

                                $managedproperty.HasMultipleValues = $hasMultipleValues

                                $managedproperty.update()

                            }

                            New-SPEnterpriseSearchMetadataMapping -SearchApplication $SearchService -ManagedProperty $managedproperty -CrawledProperty $crawledpropertyRef

                            write-log ("!!INFO!!" , "New Mapped Property created for "+ $managedpropertyRef.Name)

                            $external_counter ++

                        }catch [Exception]

                        {                            Write-Host "There was an error trying to add Mapped Property " + $mapdata.CrawledPropertyName -ForegroundColor:Red

                            write-log ("!!ERROR!!","There was an error trying to add Mapped Property " + $mapdata.CrawledPropertyName)

                            return $_.Exception.Message

                        }

       

                    }

                }

                else {

                    Write-Host "Crawled Property " + $mapdata.CrawledPropertyName + " Does Not Exist" -ForegroundColor:Red

                    write-log ("!!INFO!!", "Crawled Property " + $mapdata.CrawledPropertyName + " Does Not Exist")

                }

       

       

            }

        }

        write-log ("!!TOTALS!!","Of "+ $total_counter + "there were "+ $external_counter +" mapped properties created")

    }catch

    {

    } 

Here are the links to download the scripts.

Download link for the Export Script
Download link for Import Script

March 15
Submit Feedback WebPart Continued! (AVOID SPAM)

I recently got  feedback on the "submit feedback" webpart in this site.  

QUESTION

"Hi there! I'm not a developer but just a simple user and I like this flyout feature. I just wonder how much spam you get with this, or what you do to avoid this."


ANSWER

Hello;

We get no spam from this feature, and here is how we do it.  As a reference i used this blog.  Basically here are steps we used:

  1. Create an input field in the form call it <input id="fakeField" type="text">
  2. in your CSS hide that field      #fakeField{display:none}
  3. then in the javascript that submits the form do a check for that field.  Humans will not see that form and therefore will not fill it, however a bot would.  if it's filled, then dont submit the form, otherwise submit the form


    if ($('#fakeFieldl').val() == "") {

      //then submit the form

      

    }



 
 
​​​​​​

Content Contributors

Blog Posts