Blogger

  • This email address is being protected from spambots. You need JavaScript enabled to view it.

    Recent items

Login

SharePoint

SharePoint (49)

Wednesday, 14 November 2012 07:27

Search configuration (also for anonymous)

Written by

Search Service Application Configuration

To configure the SharePoint 2010 search, first of all must create a Search Service Application.

To do this, goto Central Administration -> Application Management -> Manage service Applications -> New -> Search service application. For my scopes, I've created an administrator account on my machine only for the crawler and during the Search Service Application creation, I've used this account as crawler account.

After that, I've setup two content sources:

  • One: this content source is used to index the content
    • Name: Local SharePoint sites
    • Content Source Type: SharePoint Sites
    • Start Addresses: http://<URL web app> (For each web apps). Remember that if you have an anonymous zone and it's URL is different by the site collection URL, it is preferable that you specify only anonymous url otherwise into anonymous zone, the content search can be empty.
  • Two: this content source is used to index the user profile
    • Name: spw.m.My.all
    • Content Source Type: SharePoint Sites
    • Start Addresses: sps3://<URL web app> (For each web apps).

First to launch a content full crawl, add the crawler user into a sharepoint group that have permission to read the content. After that, you can launch a full crawl of Local SharePoint sites content sorce.

To be sure that the search works fine, go to Crawl log (the link is on the left menù of search service application). For both contente soruces, see that there aren't Top level error (or if there are, you must correct them).

 

User Profile indexing

To have all user profile properties as Crawled and Mapped properties (to use after into the people search webparts), I advice to create a new sharepoint user profile and populate it with all information.
Do that, launch a full crawl of the content source spw.m.My.all.

 

While I was implementing an sorting code behind for the global navigation (or current), I found a defect in SharePoint 2010. The property web.Navigation.TopNavigationBar (or web.Navigation.QuickLaunch) always returns 0 items until you make a change through the UI (Site Action -> Site settings -> Navigation settings) and after that you can take action code behind and manipulate the sorting.


I needed to do it all without any interaction with the UI. To do this I had to add only the first time all nodes into the SPNavigationNodeCollection.

Show/Hidden csharp code

View source
 
 
 
//This block fixes the SharePoint defect ------------------------
var count = (from SPNavigationNode node in NavigationNodes
             where string.Compare(node.Properties["NodeType"] as string, "Area", true) == 0
             select node).Count();
 
 
if (count < pweb.GetPublishingWebs().Count)
{
    Dictionary<string, SPNavigationNode> nodeHash = new Dictionary<string, SPNavigationNode>();
    foreach (SPNavigationNode node in NavigationNodes)
        nodeHash.Add(node.Url, node);
 
    foreach (PublishingWeb subweb in pweb.GetPublishingWebs())
    {
        if (!nodeHash.ContainsKey(subweb.Url))
        {
            string relUrl = subweb.ParentPublishingWeb.Uri.MakeRelativeUri(subweb.Uri).ToString();
            SPNavigationNode nn = SPNavigationSiteMapNode.CreateSPNavigationNode(
                    subweb.Title, relUrl, NodeTypes.Area,
                    (string.Compare(navigationType,"global",true)==0 ? web.Navigation.TopNavigationBar : web.Navigation.QuickLaunch));
            nn.Update();
        }
    }
 
    web.Update();
}
 
 
 

I recently upgraded my laptop to Windows 8 to take advantage of Hyper-V in the management of my virtual machines.

To get better performance using SharePoint, I bought an SSD and I moved my vhds to the new disk. At this point, I have to change the path of the VHD virtual machine settings and when Itry to do this, I got this error: "Can not add device virtual hard disk."

I tried to change the virtual hard disk file permission, but the error was alsways there.

To resolve this error, one must perform the following steps

  • Mount the VHD (double click on the file)
  • into disk management tool, put offline the disk
  • into virtual machine settings, remove the link to the old path of vhd, add a new physical hard disk and select the offline disk

Et voila, The system can manipulate the vhds on the SSD disk :D

 

During a Term store import, you can incurr in a "Import-SPMetadataWebServicePartitionData: You do not have permission to use the bulk load statement" error as image below.

To resolve this problem, you must add the Managed Metadata Service Application user into bulkadmin DB role.

  1. If you don't now Managed Metadata Service Application user
    • open IIS Manager
    • search the Metadata Application Pool (select an Application pool, click on "View Applications" and see if contains the Metadata Service)
    • when you find the Metadata Applciation Pool, the Identity user is the Metadata Service Application user.
  2. Open Microsoft SQL Server Management Studio
    • click on Security, Server Roles, and double click on bulkadmin Role.
    • in the new window, click on add and write the user finded on the previous step.

After this operation, you can Import your Metadata without problems.

Thursday, 05 July 2012 08:26

Delete field and all its references

Written by

A simple way to delete a Field from all content types, lists and clean all its references, is to run this script (the attachment is at the end of the article):


Show/Hidden bash code

View source
 
 
 
param([string]$serverUrl = $(Throw "You have to specify the serverUrl"),[string]$fieldName = $(Throw "You have to specify the InternalName field to be delete"))
# Load SharePoint PowerShell
$snapin = get-pssnapin | `
    where { $_.Name -eq “Microsoft.SharePoint.PowerShell” }
if($snapin -eq $null)  {
  Add-PsSnapin Microsoft.SharePoint.PowerShell
}
 
#—————————————————————————-
# Delete Field
#—————————————————————————-
 
Write-Output “Start removing field:” $fieldName 
$site = Get-SPSite $serverUrl
$web = $site.RootWeb
 
#Delete field from all content types
foreach($ct in $web.ContentTypes) {
    $fieldInUse = $ct.FieldLinks | Where {$_.Name -eq $fieldName }
    if($fieldInUse) {
        Write-Output “Remove field from CType:” $ct.Name
        $ct.FieldLinks.Delete($fieldName)
        $ct.Update()
    }
}
 
#Delete column from all lists in all sites of a site collection
$site | Get-SPWeb -Limit all | ForEach-Object {
   #Specify list which contains the column
    $numberOfLists = $_.Lists.Count
    for($i=0; $i -lt $_.Lists.Count ; $i++) {
        $list = $_.Lists[$i]
        #Specify column to be deleted
        if($list.Fields.ContainsFieldWithStaticName($fieldName)) {
            $fieldInList = $list.Fields.GetFieldByInternalName($fieldName)
 
            if($fieldInList) {
                Write-Output “Delete column from ” $list.Title ” list on:” $_.URL
 
             #Allow column to be deleted
             $fieldInList.AllowDeletion = $true
             #Delete the column
             $fieldInList.Delete()
             #Update the list
             $list.Update()
            }
        }
    }
}
 
# Remove the field itself
if($web.Fields.ContainsFieldWithStaticName($fieldName)) {
    Write-Output “Remove field:” $fieldName
    $field=$web.Fields.GetFieldByInternalName($fieldName)
    $field.AllowDeletion = $TRUE
    $field.Sealed=$FALSE
    $field.Update()
    $web.Fields.Delete($fieldName)
}
 
$web.Dispose()
$site.Dispose()
 
 
 


To run the script, open powershell and write this command from the same script folder:

DeleteFieldAndAllReferences.ps1 -serverUrl http://www.yoursite.com -fieldName 'InternalFieldNameToBeDeleted'

Monday, 25 June 2012 22:49

Get All indexed User Profile property

Written by

A simple way to know all indexed User Profile property is to query the content DB.

In my case, I need to know for each subtypes, the indexed Property.

To know this information, open the SQL Manager and execute the following query:

Show/Hidden sql code

View source
 
 
 
SELECT TOP 1000 subtypename.ProfileDisplayName, property.PropertyName
  FROM [UserProfile].[dbo].[ProfileSubtypePropertyAttributes] AS subtype 
  JOIN [UserProfile].dbo.[ProfileSubtypeList] AS subtypename  ON  subtype.ProfileSubtypeID = subtypename.ProfileSubtypeID
  JOIN UserProfile].[dbo].[PropertyList] AS property ON subtype.PropertyID = property.PropertyID
  ORDER BY subtypename.ProfileDisplayName
 
 
 
 

 

Sunday, 24 June 2012 21:35

Custom Http Errors

Written by

To personalize the ISS Http Errors (for example the http 401.2 error that occurs when an user click con cancel button when credential popup appears), the user must to put the file under the IIS web site folder.

When an developer work with Sharepoint 2010 and have a farm with more front ends, he must copy the error pages in each front end servers under all webapp folders (under IIS inetpub folder).

To make life easier, the developer can implements a WebApp feature that copy the files in all front end servers and modify the web.config files.

The following code descibe the Feature event handler. After the deploy, the administrator must open the Sharepoint Central admin, choices the webapp and active the feture.

The customError folder will deployed under 14\template\layouts folder and when the feature will be activated, the system provide to copy the files and modify the web.config file to add the httpErrors section under configuration/system.webServer section.

 


Show/Hidden csharp code

View source
 
 
 
using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Administration;
using System.Collections.Generic;
using System.IO;
using Microsoft.SharePoint.Utilities;
 
namespace ApplyCustomIISErrors
{
    [Guid("00000000-0000-0000-0000-000000000000")]
    public class ApplyCustomIISErrorsEventReceiver : SPFeatureReceiver
    {
 
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            SPFarm farm = SPFarm.Local;
            string sourceFolder = SPUtility.GetGenericSetupPath("") + "\\TEMPLATE\\LAYOUTS\\customError\\";
 
            if (!string.IsNullOrEmpty(sourceFolder))
            {
                // dynamically find all files in the source folder    
                List<string> filesToDeploy = new List<string>();
                DirectoryInfo folder = new DirectoryInfo(sourceFolder);
                FileInfo[] filesInFolder = folder.GetFiles();
                foreach (FileInfo file in filesInFolder) { filesToDeploy.Add(file.Name); }
 
                // recurse through each web front end    
                foreach (SPServer server in farm.Servers)
                {
                    if (server.Role == SPServerRole.WebFrontEnd || server.Role == SPServerRole.Application)
                    {
                        try
                        {
                            SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;
                            System.Collections.Generic.Dictionary<SPUrlZone, SPIisSettings> zones = webApp.IisSettings;
                            foreach (System.Collections.Generic.KeyValuePair<SPUrlZone, SPIisSettings> zone in webApp.IisSettings)
                            {
                                SPIisSettings iis = zone.Value;
                                DirectoryInfo dir = iis.Path;
                                string targetPath = dir.ToString() + @"\" + @"customError";
                                string destinationDir = @"\\" + server.Address + @"\" + targetPath.Replace(":", "$");
                                if (!System.IO.Directory.Exists(destinationDir))
                                {
                                    System.IO.Directory.CreateDirectory(destinationDir);
                                }
 
                                // copy support files per web front end
                                foreach (string filename in filesToDeploy)
                                {
                                    string sourceFile = @"\\" + server.Address + @"\" + sourceFolder.Replace(":", "$") + @"\" + filename;
                                    string destinationFile = destinationDir + @"\" + filename;
                                    System.IO.File.Copy(sourceFile, destinationFile, true);
                                }
                            }
                            AddEntryIntoWebConfig(webApp);
 
                        }
                        catch (Exception ex)
                        {
                            
                        }
                    }
                }
            }
        }
 
        #region Web Config Modification
        private const string WebModificationOwnerName = "Automatic Error Pages Deploy Owner";
 
        private void AddEntryIntoWebConfig(SPWebApplication webApp)
        {
            RemoveAllModifications(webApp, WebModificationOwnerName);
 
            string name, value, xpath, xPthRemove;
 
            xpath = "configuration/system.webServer";
            //<HttpErrors errorMode="Custom" existingResponse="Auto" >
            name = "httpErrors[@errorMode='Custom'][@existingResponse='Auto']";
            value = "<httpErrors errorMode='Custom' existingResponse='Auto'></httpErrors>";
            ModifyWebConfig(webApp, xpath, name, value);
            webApp.WebService.Update();
            webApp.WebService.ApplyWebConfigModifications();
 
            xpath = "configuration/system.webServer/httpErrors[2=2]";
            xPthRemove = "configuration/system.webServer/httpErrors[1=1]";
 
            #region HTTP 401
            //<remove statusCode="401" subStatusCode="-1" />
            name = "remove[@statusCode='401'][@subStatusCode='-1']";
            value = "<remove statusCode='401' subStatusCode='-1' />";
            ModifyWebConfig(webApp, xPthRemove, name, value);
 
            //<error statusCode="401" prefixLanguageFilePath="" path="customError\401.html" responseMode="File" />
            name = @"error[@statusCode='401'][@prefixLanguageFilePath=''][@path='customError\401.html'][@responseMode='File']";
            value = @"<error statusCode='401' prefixLanguageFilePath='' path='customError\401.html' responseMode='File' />";
            ModifyWebConfig(webApp, xpath, name, value);
            #endregion
 
            #region HTTP 403
            //<remove statusCode="403" subStatusCode="-1" />
            name = "remove[@statusCode='403'][@subStatusCode='-1']";
            value = "<remove statusCode='403' subStatusCode='-1' />";
            ModifyWebConfig(webApp, xPthRemove, name, value);
 
            //<error statusCode="403" prefixLanguageFilePath="" path="customError\403.html" responseMode="File" />
            name = @"error[@statusCode='403'][@prefixLanguageFilePath=''][@path='customError\403.html'][@responseMode='File']";
            value = @"<error statusCode='403' prefixLanguageFilePath='' path='customError\403.html' responseMode='File' />";
            ModifyWebConfig(webApp, xpath, name, value);
            #endregion
 
            #region other errors
            
            #endregion
 
            try
            {
                webApp.WebService.ApplyWebConfigModifications();
            }
            catch (Exception ex)
            {
                RemoveAllModifications(webApp, WebModificationOwnerName);
                webApp.Update();
                webApp.WebService.ApplyWebConfigModifications();
            }
        }
 
        private void RemoveAllModifications(SPWebApplication webApp, string owner)
        {
            List<SPWebConfigModification> modificationsToRemove = new List<SPWebConfigModification>();
            foreach (SPWebConfigModification modification in webApp.WebConfigModifications)
                if (modification.Owner == owner)
                    modificationsToRemove.Add(modification);
 
            foreach (SPWebConfigModification modification in modificationsToRemove)
                webApp.WebConfigModifications.Remove(modification);
 
            webApp.Update();
        }
 
        private void ModifyWebConfig(SPWebApplication webApp, string path, string nameModif, string valueModif)
        {
            SPWebConfigModification modification = new SPWebConfigModification(nameModif, path);
            modification.Value = valueModif;
            modification.Sequence = 0;
            modification.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
            modification.Owner = WebModificationOwnerName;
 
            webApp.WebConfigModifications.Add(modification);
            webApp.Update();
        }
       
        #endregion
 
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            SPFarm farm = SPFarm.Local;
            string sourceFolder = SPUtility.GetGenericSetupPath("") + "\\TEMPLATE\\LAYOUTS\\customError\\";
            
            // dynamically find all files in the source folder    
            if (!string.IsNullOrEmpty(sourceFolder))
            {
                List<string> filesToDeploy = new List<string>();
                DirectoryInfo folder = new DirectoryInfo(sourceFolder);
                FileInfo[] filesInFolder = folder.GetFiles();
                foreach (FileInfo file in filesInFolder) { filesToDeploy.Add(file.Name); }
 
                // recurse through each web front end    
                foreach (SPServer server in farm.Servers)
                {
                    if (server.Role == SPServerRole.WebFrontEnd || server.Role == SPServerRole.Application)
                    {
                        try
                        {
                            SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;
                            foreach (System.Collections.Generic.KeyValuePair<SPUrlZone, SPIisSettings> zone in webApp.IisSettings)
                            {
                                SPIisSettings iis = zone.Value;
                                DirectoryInfo dir = iis.Path;
                                string targetPath = dir.ToString() + @"\" + @"customError";
                                if (System.IO.Directory.Exists(targetPath))
                                {
                                    foreach (string filename in filesToDeploy)
                                    {
                                        string delFile = @"\\" + server.Address + @"\" + targetPath.Replace(":", "$") + @"\" + filename;
                                        System.IO.File.Delete(delFile);
                                    }
                                    string delDir = @"\\" + server.Address + @"\" + targetPath.Replace(":", "$");
                                    System.IO.Directory.Delete(delDir);
                                }
                            }
 
                            RemoveAllModifications(webApp,WebModificationOwnerName);
                            webApp.WebService.ApplyWebConfigModifications();
                        }
                        catch (Exception ex)
                        {
                        
                        }
                    }
                }
            }
        }
    }
}
 
 
 
 

Page 4 of 4