Thursday, January 22, 2015

Set Managed Metadata Field using CSOM via PowerShell in SharePoint online (Office 365)

Context: I was working on a project to migrate data from Lotus notes to SharePoint online. In this context, I had to use Client object model to create list items and set the values of the fields in the list. One of the challenge that I came across was how to set a managed metadata field value using CSOM and PowerShell.

Solution: The following is the code that I wrote to achieve this task. I used an example that was using JSOM to set the Managed metadata field. I converted the same logic using CSOM and PowerShell.
cls

#Your SharwPoint online Credentials
$siteUrl = “https://test.sharepoint.com/sites/dev3”
$username = "testAccount@test.onmicrosoft.com"
[string]$pwd = “Password“
$password = $pwd | ConvertTo-SecureString -AsPlainText -Force
$listName = "Taxonomy List";

# Load the Client object Model Assemblies

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Taxonomy")

function getContext()
{
    $context = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl)
    $credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $password)
    $context.Credentials = $credentials

    return $context;
}
$context = getContext;

# load the List
$mainList = $context.Web.Lists.GetByTitle($listName);
$context.Load($mainList);
$context.ExecuteQuery();

# load the Taxonomy Field
$TaxonomyKategorieFld = $mainList.Fields.GetByInternalNameOrTitle($taxonomyField) 
$context.Load($TaxonomyKategorieFld)
$context.ExecuteQuery();

# Create the item object in the Taxonomy List
$itemCreationInfo = New-Object Microsoft.SharePoint.Client.ListItemCreationInformation;
$item = $mainList.AddItem($itemCreationInfo);
$item.set_item("Title","Test Taxonomy Item");
$item.Update();

# Create Taxonomy Session
$sTaxonomySession = [Microsoft.SharePoint.Client.Taxonomy.TaxonomySession]::GetTaxonomySession($context);
$sTaxonomySession.UpdateCache();
$context.Load($sTaxonomySession);
$context.ExecuteQuery();

# Load Default Term Store (Site Settings --> Term Store Management) 
$sTermStore = $sTaxonomySession.GetDefaultSiteCollectionTermStore();
$context.Load($sTermStore);
$context.ExecuteQuery();


if($sTermStore.IsOnline)
{
    $sGroup = $sTermStore.Groups.GetByName($sGroupName); # Get the Term Group
    $sTermSet = $sGroup.TermSets.GetByName($tsName); # Get the Term Set
    $context.Load($sTermSet);    
    $context.ExecuteQuery();
    $terms = $sTermSet.GetAllTerms(); # Load all the Terms in the TermSet
    $context.Load($terms);
    $context.ExecuteQuery();
            
    $txField = [Microsoft.SharePoint.Client.ClientContext].GetMethod("CastTo").
               MakeGenericMethod([Microsoft.SharePoint.Client.Taxonomy.TaxonomyField]).
               Invoke($context, $TaxonomyKategorieFld)    
    $termQuery = "Kunden";
    $termQuery1 = "Acme";
    $termValues = @();
    foreach($term in $terms)
    {
        # When Kunden or Aceme Terms found, add to the Taxonomy Field
        if(($term.Name -eq $termQuery) -or ($term.Name -eq $termQuery1)) 
        {
            $termValues +=  "-1;#" + $term.Name + "|" + $term.Id;
            $termValuesString = $termValues -join ";#"
        }    
    }    
        
    $termValues = new-object Microsoft.SharePoint.Client.Taxonomy.TaxonomyFieldValueCollection($context, $termValuesString, $txField)
    $txField.SetFieldValueByValueCollection($item, $termValues);
    $item.Update();
    $context.Load($item);
    $context.ExecuteQuery();
}

$context = $null;
Reference: http://sharepoint.stackexchange.com/questions/113146/how-do-you-properly-write-to-a-managed-metadata-column-from-jsom-sharepoint-20

Cheers.. :)

Friday, January 16, 2015

Recover and Restore SharePoint Group Users

Context: SharePoint Owner of a site accidently deleted the ‘Members’ group and wanted the group with all users back.

Solution: First I restored the backup of the Content database in the Test environment and mounted it to the Web Application. 
Once the Site collection is available, I wrote a PowerShell Script to export the Users of the ‘members’ Group into Csv file. The following is the code that I wrote;

clear

if((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null)
{
    Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}

$siteUrl = "https://test.sharepoint.group/sites/1112"
$csvPath = "C:\Users\salman\Desktop\Export Csv\UsersRetrieved.csv"

$site = Get-SPSite $siteUrl

$group = $site.RootWeb.SiteGroups.GetByName("Site_Member");

$userList = @()
foreach($user in $group.Users)
{
    $psUser = New-Object PSObject -Property @{
        "ID" = $user.ID
        "Display Name" = $user.DisplayName
        "Login Name" = $user.LoginName
        
    }
    $userList += $psUser;
}

if($userList.length -gt 0)
{
    $userList | Export-Csv -Path $csvPath
    Write-Host "Total Users exported: " $group.Users.Count;
}

$site.Dispose();



Then, I created a group named as Site_Members manually by looking at the settings from the testing environment site group.

Once the group is ready, I copied the csv file created with the Import script in the Production environment and ran the following PS script in the production environment.

clear

if((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null)
{
    Add-PSSnapin "Microsoft.SharePoint.PowerShell"
}

$siteUrl = "https://sharepoint.group/sites/1112"
$csvPath = "C:\Users\salman\Desktop\Export Csv\UsersRetrieved.csv";
$groupName = "Site_Member";

$site = Get-SPSite $siteUrl

$group = $site.RootWeb.Groups.GetByName("$groupName");
if(Test-Path $csvPath)
{
    $usersList = Import-Csv -Path $csvPath
    foreach($user in $usersList)
    {
        $name = $user."Login Name";        
        $user = $site.RootWeb.EnsureUser($name)        
        $group.AddUser($user);
    }    
}

Thursday, January 15, 2015

Publish a List as Catalog and consume it in Search Results WebPart

Context: I wanted to publish a list as Catalog and later wanted to consume list’s data in a ‘Search Results’ webpart. The following diagram shows bird’s eye view of my problem;



 Solution: The figure shows that Site Collection A is publishing and B is consuming. So, first we are going to publish a list as Catalog. The following series of steps should be followed to make a list as Catalog.

  • Publish List as Catalog
  1. First create Site Columns as those will later be used as managed properties in the Search schema and will be consumed in the Results Search web part. Go to (Site Settings -> Site Columns). 
  2. Create a custom list named a ‘Cars’.
  3. Add the Site Columns into the Cars list. Add also some dummy data in the list.
  4. Now go to the (Site Settings-> Site Collection Features-> Enable ‘Cross-Site Collection Publishing).
  5. Now enable the Catalog Settings by going to (List (Cars)-> List Settings-> Catalog Settings). On the Catalog Setting page, select ‘Enable this library as catalog’ as shown below; 
  6. Now the Site Collection A with a list ‘Cars’ is ready to be consumed into the Site Collection B. Let’s now go to the Site Collection B and add ‘Search Results webpart’.

  • Setup Site Collection to Consume list catalog
  1. Before you add the webpart, first go to your Search Service and add the ‘Site Collection A’ url in the Content Sources (Search Service Application-> Content Sources) and start a full crawl by right clicking the content source.
  2. Go to the Site Collection B and activate a Site Collection feature ‘SharePoint Server Publishing Infrastructure’.
  3. Now go to (Site Settings -> Manage site features -> Activate ‘SharePoint Server Publishing’).
  4.  Once it is activated, you will find ‘Manage catalog connection’ option added into the Site Administration group.
  5. Go to ‘Manage catalog connections’, click catalog ‘connect to catalog’. SharePoint will show number of catalogs to be consumed as shown in the figure. Click connect on your publishing catalog list.
Your Site collection is now ready to consume the List catalog ‘Cars.
  • Attach list with Search Results WebPart
Follow the following series of steps to add a list catalog ‘Cars’ to Search Results webpart.

  1. Before you add the webpart, first go to your Search Service and add the ‘Site Collection A’ url in the Content Sources (Search Service Application --> Content Sources) and start a full crawl by right clicking the content source.
  2. Go to the webpart properties and click change query.
  3. Select the list and click ‘Test query’ button. You will immediately get a preview of the search results as shown below;
  4. Click Apply button to finalize the changes and Save your page to see the ‘Search Result’ webpart working.
That's it enjoy working with List catalog and Search Results webpart in SharePoint...