Monday, February 13, 2017

Enable / Setup Search Service in Sharepoint through Powershell

Sharepoint has provided an easy approach through Central admin to enable Search service application, but the one known issue with it is, it creates a database on its own. we can also enable this using powershell commands. By doing this, we can provide our own name for the DB.

Below is the step by step commands to be executed to enable Search service using powershell.
 #Add-PSSnapin Microsoft.SharePoint.PowerShell  
 # 1.Setting up some initial variables.  
 write-host 1.Setting up some initial variables.  
 $SSAName = "InternalSearch"  
 $SSADatabase = "InternalSearchDB"  
 $saAppPoolName = "SecurityTokenServiceApplicationPool"  
 $SSI = get-spenterprisesearchserviceinstance -local  
 $err = $null  
 # Start Services search services for SSI  
 write-host Start Services search services for SSI  
 Start-SPEnterpriseSearchServiceInstance -Identity $SSI  
 Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance $SSI  
 # 2.connect to an Application Pool.  
 write-host 2.connect to an Application Pool.  
 $AppPool = Get-SPServiceApplicationPool $saAppPoolName  
 # 3.Create the SearchApplication and set it to a variable  
 write-host 3.Create the SearchApplication and set it to a variable  
 $SearchApp = New-SPEnterpriseSearchServiceApplication -Name $SSAName -applicationpool $AppPool -databasename $SSADatabase  
 #4 Create search service application proxy  
 write-host 4 Create search service application proxy  
 $SSAProxy = new-spenterprisesearchserviceapplicationproxy -name $SSAName" ApplicationProxy" -Uri $SearchApp.Uri.AbsoluteURI  
 # 5.Provision Search Admin Component.  
 write-host 5.Provision Search Admin Component.  
 set-SPenterprisesearchadministrationcomponent -searchapplication $SearchApp -searchserviceinstance $SSI  
 # 6.Create a new Crawl Topology.  
 write-host 6.Create a new Crawl Topology.  
 $CrawlTopo = $SearchApp | New-SPEnterpriseSearchCrawlTopology  
 # 7.Create a new Crawl Store.  
 write-host 7.Create a new Crawl Store.  
 $CrawlStore = $SearchApp | Get-SPEnterpriseSearchCrawlDatabase  
 # 8.Create a new Crawl Component.  
 write-host 8.Create a new Crawl Component.  
 New-SPEnterpriseSearchCrawlComponent -CrawlTopology $CrawlTopo -CrawlDatabase $CrawlStore -SearchServiceInstance $SSI  
 # 9.Activate the Crawl Topology.  
 write-host 9.Activate the Crawl Topology.  
 do  
 {  
   $err = $null  
   $CrawlTopo | Set-SPEnterpriseSearchCrawlTopology -Active -ErrorVariable err  
   if ($CrawlTopo.State -eq "Active")  
   {  
     $err = $null  
   }  
   Start-Sleep -Seconds 10  
 }  
 until ($err -eq $null)  
 # 10.Create a new Query Topology.  
 write-host 10.Create a new Query Topology.  
 $QueryTopo = $SearchApp | New-SPenterpriseSEarchQueryTopology -partitions 1  
 # 11.Create a variable for the Query Partition  
 write-host 11.Create a variable for the Query Partition  
 $Partition1 = ($QueryTopo | Get-SPEnterpriseSearchIndexPartition)  
 # 12.Create a Query Component.  
 write-host 12.Create a Query Component.  
 New-SPEnterpriseSearchQueryComponent -indexpartition $Partition1 -QueryTopology $QueryTopo -SearchServiceInstance $SSI  
 # 13.Create a variable for the Property Store DB.  
 write-host 13.Create a variable for the Property Store DB.  
 $PropDB = $SearchApp | Get-SPEnterpriseSearchPropertyDatabase  
 # 14.Set the Query Partition to use the Property Store DB.  
 write-host 14.Set the Query Partition to use the Property Store DB.  
 $Partition1 | Set-SPEnterpriseSearchIndexPartition -PropertyDatabase $PropDB  
 # 15.Activate the Query Topology.  
 write-host 15.Activate the Query Topology.  
 do  
 {  
   $err = $null  
   $QueryTopo | Set-SPEnterpriseSearchQueryTopology -Active -ErrorVariable err -ErrorAction SilentlyContinue  
   Start-Sleep -Seconds 10  
   if ($QueryTopo.State -eq "Active")  
     {  
       $err = $null  
     }  
 }  
 until ($err -eq $null)  
 Write-host "Your search application $SSAName is now ready"  

Sunday, February 12, 2017

Migrate Sharepoint User Account to a New Login Name

There might be many occasions where we have to change the Users' account, could be the domain change or name change.

 Also another scenario is, if we have enabled Farm based authentication sharepoint adds some special characters to the account in the start like 'i:0#.w|' and if  we disabled it at later point, these names will not be changed.  We need to migrate / change the account names manually before people start using it. If not, we see 2 accounts for individual users.

we can achieve this functionality using Poweshell script. Considering above scenario, below is the script used to migrate resources in bulk when we are moving back form Farm based to windows authentication.

Below script is to get all the people present in the current system to a CSV File.
 function GetSPWebUsers($SiteCollectionURL)   
 {   
   [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null   
   $site = new-object Microsoft.SharePoint.SPSite($SiteCollectionURL)   
   $web = $site.openweb()   
   $siteUsers = $web.SiteUsers   
 @(foreach ($user in $siteUsers) {  
   $usergroup = New-Object System.Object  
      $usergroup | Add-Member -type NoteProperty -name AccountName -value $user.LoginName  
    Write-Output $usergroup   
 }) | Export-Csv c:\userlist.csv -NoTypeInformation   
   $web.Dispose()   
   $site.Dispose()   
 }   
 GetSPWebUsers $args[0]  
 #to execute, run the command as below  
 #GetSPWebUsers "http://<<site collection URL>>"  

By running above script, we get all the users' login names to a CSV file which will be used as an input of below code where we migrate individual users to the windows accounts which are formed by removing the starting set of special characters "i:0#.w|"
 Add-PSSnapin Microsoft.SharePoint.PowerShell  
 function MigrateUserOrGroups($csvFile)  
 {  
   #Getting the SPFarm object  
   $farm = Get-SPFarm  
   Import-Csv $csvFile | ForEach-Object{  
   Write-Host "Migrating User" $_.login "to" $_.login.Substring(7) -ForegroundColor Green  
   $farm.MigrateUserAccount( $_.login, $_.login.Substring(7), $false )  
   Write-Host "Migration Completed" -ForegroundColor Cyan  
   }  
   # $farm.Name  
 }  
 MigrateUserOrGroups $args[0]  
 #to execute, run the command as below  
 #MigrateUserOrGroups "c:\userlist.csv"  

You can modify the code as per your requirement.

Thursday, February 9, 2017

Display Files / Folders from a Document Library in Sharepoint

Below is the code to display documents / folders from a library in a Sharepoint environment, in a Tree View.

we are using SPServices and JQuery to achieve this  functionality.

 <div id='status' style='color:#d41414;display:none;padding:5px'>  
 </div>  
 <div id='main-block' style='display:none'>  
      <div><h3>Documents</h3></div>  
      <div id="0">  
      </div>  
 </div>  
 <script src="/InternalResources/jquery.min.js"></script>  
 <script src="/InternalResources/jquery.SPServices-0.7.2.min.js"></script>  
 <script language="javascript" type="text/javascript">  
 $(document).ready(function(){  
      //Enter the list name. If url is different, please update url variable too.  
      //Here code takes the current context and current website  
   var list = "TestFolders";  
   var url = list + "/";   
      createTree(url, 0, list);       
  });  
 function createTree(url, tagID, list){  
   //get the url to define the level of tree,  
   $().SPServices({  
   operation: "GetListItems",  
   async: false,  
   listName: list,  
   CAMLViewFields: "<ViewFields><FieldRef Name='Title' /><FieldRef Name='ID' /><FieldRef Name='EncodedAbsUrl' /></ViewFields>",  
   CAMLQueryOptions: "<QueryOptions><Folder>" + url + "</Folder></QueryOptions>",  
   completefunc: function (xData, Status) {  
           if($(xData.responseXML).SPFilterNode("z:row").length > 0) {  
                $("#"+tagID+"").append("<ul id='prime-"+tagID+"'>");  
                $(xData.responseXML).SPFilterNode("z:row").each(function() {  
                     var id = $(this).attr("ows_ID");  
                     var title = $(this).attr("ows_Title");     
                     var folder =  $(this).attr("ows_FileLeafRef").split(";#")[1];   
                     $("#prime-"+tagID+"").append("<li id='"+id+"'>" + " <a href='"+$(this).attr("ows_EncodedAbsUrl")+"'>" + folder + " </a></li>");                  
                 var thisFSObjType = $(this).attr("ows_FSObjType").split(";#")[1];  
                 if(thisFSObjType == 1) {  
                     //auto call the function createTree again, to get subfolders and files, assigning a new url/subfolder and id  
                     createTree(url+'/'+folder, id, list);       
                 }  
                 });  
                 $("#"+tagID+"").append("</ul>");  
                 $('#status').css('display','none');  
                 $('#main-block').css('display','block');  
           }  
           else     {  
                $('#status').html('No documents found.');  
                $('#status').css('display','block');  
           }  
      }  
  });   
 }  
 </script>  

Takeaways from Threshold limits of Sharepoint Lists

Few takeaways of Sharepoint Lists with large size.

  • If the data crossed the threshold value, applying filters on multiple indexed columns won’t display records. 
  • The first filter should be the Indexed column and only one indexed column should be used in a filter criteria
  • We cant index a column which has multi select enabled.
  • Threshold will not effect the performance of an individual item access.
  • If list crosses view threshold, we can't use it as lookup reference in any other list. 
Also, its better not to apply many permission restrictions  as it checks for individual permission set while fetching a record, which may impact performance.

For reference, use below links.

https://support.office.com/en-us/article/Manage-large-lists-and-libraries-in-SharePoint-b8588dae-9387-48c2-9248-c24122f07c59

https://support.office.com/en-us/article/Manage-lists-and-libraries-with-many-items-fba0c8b7-79bb-4ea4-9aff-bf145a689e8e