Wednesday, May 11, 2016

SharePoint 2016 Installation and Configuration + Workflow Manager



As you would know the SharePoint 2016 was made available for general public a few days ago .I am lucky enough to get my hands on it .Below is my experience and troubleshooting with installation of SharePoint 2016 and configuring it .
       I tried the single server installation here ,as it was my Development server ,so i created a LocalUser account .For production environment it is always recommend you use the Service account which is a Active Directory account.

1)Download the SQL server 2014  standard/Enterprise .
2)Download the SharePoint server 2016
3)Download the Visual Studio 2015 enterprise.

4)I started with SQL server installation and added all the features except the native reporting service which i am pretty sure I was not going to use ,if required I would use SharePoint integrated mode for Reporting . There are number of materials available on internet if you are doing the installation and configuration of SQL for first time ,I aint going to explain the same here .It is pretty simple if you follow the steps .I would recommend you to configure SQL in Mixed mode ,add a SQL account too .I gave the Admin right to the LocalUser for the SQL services.

5)Luckily all is well SQL got configured succesfully !!

6) Next up SharePoint 2016 , before touching this ,I would recommend you check the internet connection ,make sure its accessible as the pre-installer would need the internet to download the required SW .
7)Click on the prerequisite.exe , it would run and download and configure all the required SW for sharepoint installation .
8)Once done it would restart the machine .
9)Next up the big man SharePoint 2016 !!
10) Click on Setup.exe and run the installation 
11)It would ask for product key provide one
12)You would end up in a window which ask for farm id to configure and database server 
13) You provide the LocalUser  as configuration account you would end up in a error as below

Local User cannot be used to configure Sharepoint ,use domain user  !!

If you had the experience with installation of older SharePoint versions you would know that ,Since it is a Standlone config you dont require domain account to configure .Because all my SQL ,sharepoint etc are in same machine . Also you have a work around to overcome the issue .You would create Config DB through powershell and later run the configuration again 

14)So I did the same  opened Powershell and typed 

New-SpconfigurationDatabase

Unfortunately this wasnot working out !!

Reason one or more parameter is missing 

15) Oh I realised now !! New feature in SharePoint 2016 ,you could assign the role to the server during the installation itself ,you can install as AppServer ,webFront end ,Distributed cache server etc etc .lot more info available on internet :)

So I tried the below commands


New-SPConfigurationDatabase -LocalServerRole SingleServerFarm

Since I was running everything in same machine I gave server role as SingleServerFarm

It would ask for few input provide the same and 

Your Config DB is created just with the local account now  :)

Run the SharePoint Configuration Wizard ,It ask you to disconnect or remain in same farm .
Choose option to Remain  and proceed with the configuration  .

My SharePoint 2016 Site was up and running  :)

So now the SharePoint 2016 config was done ,I was in search on supporting tools

16)There is no SharePointPoint available and SharePoint 2013 to be installed to do the job.

17)For the Workflow configuration you still have the framework which is being used in the Sharepoint 2013 

Install Webplatform installer  .

18) Search for Workflow Manager 1.0 Refresh   and install ,
19)This would also install the ServiceBus ,Workflow client and Appfabric .
20)After the installation a Configuration wizard is run to configure the Service bus and WF .Number of materials are available to assist on this as it is a old process .

21) Error in WF configuration  the api-version in the query string is not supported

Found out that this issue is due to the Service bus 

Installion Service bus cummulative update fixed the issue !!

22) Next step as usual as in SharePoint 2013 once the WF configuration Wizard is completed ,Run the Powershell command to create service application in sharepoint .So I opened Sharepoint Management Studio and typed in the below commands 

Register-SPWorkflowService -SPSite "http://sharepointst/sitecollection" -WorkflowHostUri "http://sharepointst:12991"

Since I was using http for WF i used the 12991 port ,you can config for https too ,again internet has the info to help you out on this .

23)Found the below error 

Forbidden erorr 503

24)Luckily this error is familar to me ,I had worked on this 2 yrs ago while working on sharepoint 2013 RTM version and the resolution is here in my other blog

http://sharepointerthilosh.blogspot.in/search/label/workflow/

25)Now All is well Start working on SharePoint 2016 


Planning to integrate SharePoint 2016 with SSRS in integrate mode ,hoping to update the post on the same ASAP :)

Happy coding !! :) :) 

(Updated  the Post with below details)

After all this successful messages I thought it would be a cake walk using Visual studio 2015 with Sharepoint ,to my surprise I did not find the Sharepoint 2016 templates  in VS2015 ,as usual i installed the Office developer tools for Visual Studio 2015 ,was able to find the templates for 2010 and 2013 development was sharepoint but no signs of 2016 templates . Finally after lot of goooooling found that there are two versions of Visual Studio 
Visual Studio 2015 and Visual Studio 15 .So I ended up do trail and error with all the combinations of VS and developer tools and finally found the below two are the ones which provided me with Sharepoint 2016 templates .

Visual Studio 15 preview  -->link
Microsoft Office developer Tools Preview -- >Link

Looks like these two packages are still not released as final versions  !! Comment below if I am wrong  :) :) 







Friday, November 27, 2015

SharePoint Migration Lookup error

There was site in SharePoint 2010 and I was planning to move it to SharePoint 2013 version by performing a Content db migration .

The site had a list which consists of lookup columns ,these were lookup to other list.But the point here was that these columns were hidden while it was created through element.xml in the solution .The list was working fine in SharePoint 2010 ,But when I migrated the 2010 site to SharePoint 2013 the link of the lookup is lost and the data is been displayed as a text field Eg: "#2;lookupValue" etc .
This was creating few problems in my solution due to mismatch in the values of the list itms .I had to fix the lookup column .Below is the resolution to this migration error



I placed the below code in Content Editor WebPart and made the field readable,This changed the column back as lookup .Later you can change the column to readonly =true


<content id="Main" contentplaceholderid="PlaceHolderMain" runat="server"></content><script language="ecmascript" type="text/ecmascript">
        var fieldCollection;
        var field;
        var list;
        function UpdateField() {
            var clientContext = SP.ClientContext.get_current();
            if (clientContext != undefined && clientContext != null) {
                var webSite = clientContext.get_web();
                this.list = webSite.get_lists().getByTitle("ListA");
                this.fieldCollection = list.get_fields();
                this.field = fieldCollection.getByTitle("Column1");
                this.field.set_readOnlyField(false);
                this.field.update();

            clientContext.load(this.fieldCollection);
            clientContext.load(this.field);
                clientContext.executeQueryAsync(Function.createDelegate(this, this.OnLoadSuccess), Function.createDelegate(this, this.OnLoadFailed));
            }
        }
        function OnLoadSuccess(sender, args) {
            alert("Field deleted successfully.");
        }
        function OnLoadFailed(sender, args) {
            alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
        }
</script><input type="button" id="btnUpdateField" onclick="UpdateField()" value="Change ReadOnly"/> 

Jquery function after delay


Some times functions under the method " $(document).ready(function()" doesnot get called .You can use the delay as below and call the events.

setTimeout(function()
{
$(document).ready(function(){
$("#downloads").click(function (e) {

                alert('test');

            });
});},1000);

Tuesday, September 8, 2015

Move Sharepoint folders and files in list/Libraries through powershell



I had this folder movement structure of
1)Adjacency
    2)Group
          3)Subgroup

Below is the Powershell code through which I achieved it.It can be used to move files and folders in the same library or to different library.You could also pick only the subfolders to be moved or the whole main folder to be moved



$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"
}


$logFile = "LogFile_MoveFiles.txt"

function create-fileitems()
    {
     [CmdletBinding()]
     param(
[Parameter(position=1, mandatory=$true, parametersetname="Default")] [Microsoft.SharePoint.SPDocumentLibrary]$SourceList,
[Parameter(position=2, mandatory=$true, parametersetname="Default")] [Microsoft.SharePoint.SPDocumentLibrary]$DestinationList,
     [Parameter(position=3, mandatory=$true, parametersetname="Default")] [string] $SourceAdjacencyToMove,
     [Parameter(position=4, mandatory=$true, parametersetname="Default")] [string] $ConfirmAdjToMove,
     [Parameter(position=5, mandatory=$true, parametersetname="Default")] [string] $SourceGroupToMove,
     [Parameter(position=6, mandatory=$true, parametersetname="Default")] [string] $DestinationAdjToMove,
     [Parameter(position=7, mandatory=$true, parametersetname="Default")] [Microsoft.SharePoint.SPWeb]$sourceweb
     )
        $src = $SourceList
        $tgt = $DestinationList
        $SourceAdjacency = $SourceAdjacency
        $AllFolders = $src.Folders
        $srcRootFolder = $src.RootFolder
        $allfiles = $src.items
        $RootItems = $srcRootFolder.files
        $destRootFolder = $tgt.RootFolder
        $arrListFolderURLToDelete = New-Object System.Collections.ArrayList
        Try
         {
          foreach($Folder in $src.RootFolder.SubFolders)
           {
         if($Folder.Name -eq $SourceAdjacencyToMove)
           {
            $srcFolderURL = $folder.url
            $destFolderURL = $srcFolderURL          
            $destFolderURL = $destFolderURL -replace $SourceAdjacencyToMove, $DestinationAdjToMove
            $srcItems = $Folder.folder.files
            if(!($tgt.Folders | ? {$_.URL -eq $destFolderURL}))
            {
             
                $parentFolderURL = $Folder.ParentFolder.ServerRelativeUrl
                $newFolder = $src.Additem($parentFolderURL,[Microsoft.SharePoint.SPFileSystemObjectType]::Folder,$DestinationAdjToMove)
                $newFolder.Update()
                write-host -ForegroundColor Green "Folder Creation:"$destFolderURL" - Complete"
                Add-Content $logFile "Folder Creation: $destFolderURL - Complete"
            }          
               foreach($subFolder in $Folder.SubFolders)
               {
                   if($ConfirmAdjToMove -eq "N" -or $ConfirmAdjToMove -eq "n")
                     {
                        if($subFolder.Name -eq $SourceGroupToMove)
                        {
                            MoveGroup $Folder $subFolder $srcRootFolder $destRootFolder $tgt $AllFiles
                            $arrListFolderURLToDelete.Add($subFolder.URL) | Out-Null
                        }
                     }
                   else
                     {
                       MoveGroup $Folder $subFolder $srcRootFolder $destRootFolder $tgt $AllFiles
                       $arrListFolderURLToDelete.Add($subFolder.URL) | Out-Null
                     }
                   
               }
             if($ConfirmAdjToMove -eq "Y" -or $ConfirmAdjToMove -eq "y")
               {
                 $arrListFolderURLToDelete.Add($Folder.URL) | Out-Null
               }  
                     
           }

        }
          Foreach($folderURLToDelete in $arrListFolderURLToDelete)
           {

                $folderToDelete = $sourceweb.GetFolder($folderURLToDelete)
                $folderToDelete.Delete()

             }
         }
        catch
         {
            Write-Host  $_.Exception.Message
            Add-Content $logFile    "***Error description Starts****`n"
            Add-Content $logFile    $_.Exception.Message      
            Add-Content $logFile    "***Error description ends****`n"
         }

      }

 function MoveGroup($Folder,$subFolder , $srcRootFolder ,$destRootFolder,$tgt,$AllFiles)
    {
        $srcSubFolderURL = $subFolder.url
        $destSubFolderURL = $srcSubFolderURL                  
        $destSubFolderURL = $destSubFolderURL -replace $SourceAdjacencyToMove, $DestinationAdjToMove
        $srcSubItems = $subFolder.folder.files
          if(!($tgt.Folders | ? {$_.URL -eq $destSubFolderURL}))
              {
                        $parentFolderURL = $Folder.serverrelativeurl
                        $parentFolderURL = $parentFolderURL -replace $SourceAdjacencyToMove, $DestinationAdjToMove                                              
                        $newFolder = $src.Additem($parentFolderURL,[Microsoft.SharePoint.SPFileSystemObjectType]::Folder,$subFolder.name)
                        $newFolder.Update()
                        write-host -ForegroundColor Green "Folder Creation:"$destSubFolderURL" - Complete"
                        Add-Content $logFile "Folder Creation: $destSubFolderURL - Complete"
                      }
                   
                foreach($sub2Folder in $subFolder.SubFolders)
                      {
                            $srcSub2FolderURL = $sub2Folder.url
                            $destSub2FolderURL = $srcSub2FolderURL                          
                            $destSub2FolderURL = $destSub2FolderURL -replace $SourceAdjacencyToMove, $DestinationAdjToMove
                            $srcSub2Items = $sub2Folder.folder.files
                            if(!($tgt.Folders | ? {$_.URL -eq $destSub2FolderURL}))
                              {
                                $parentFolderURL = $subFolder.serverrelativeurl              
                                $parentFolderDestination = $destRootFolder                              
                                $parentFolderURL = $parentFolderURL -replace $SourceAdjacencyToMove, $DestinationAdjToMove                                                      
                                $newFolder = $src.Additem($parentFolderURL,[Microsoft.SharePoint.SPFileSystemObjectType]::Folder,$sub2Folder.name)
                                $newFolder.Update()
                                write-host -ForegroundColor Green "Folder Creation:"$destSub2FolderURL" - Complete"
                                Add-Content $logFile "Folder Creation: $destSub2FolderURL - Complete"
                              }
                     
                       $destFolder = $src.Folders | ? {$_.url -eq $destSub2FolderURL}
                             if($sub2Folder.Files.count -gt 0)
                              {
                                $srcItems = $sub2Folder.Files
                                    foreach ($item in $srcItems)
                                    {
                                        $sourceListItem = $item.Item
                                        [Microsoft.Office.RecordsManagement.RecordsRepository.Records]::UndeclareItemAsRecord($sourceListItem)
                                        $Relative = $Item.URL
                                        $TargetItem = $AllFiles | ? {$_.URL -eq $Relative}
                                        $sBytes = $TargetItem.File.OpenBinary()
                                        $dFile = $destFolder.Folder.Files.Add($TargetItem.Name, $sBytes, $true)
                                        $ditem = $dfile.Item
                                        $ditem["Modified"] = $Item.TimeLastModified.ToLocalTime()
                                        $ditem["Created"] = $Item.TimeCreated.ToLocalTime()
                                        $ditem["Author"] = $Item.Author
                                        $ditem["Editor"] = $Item.ModifiedBy                                                                              
                                        $ditem.SystemUpdate($true)
                                        $dFile.CheckIn("Check in by Administrator")
                                        $dFile.Update()
                                        write-host -ForegroundColor Green "File Creation:" $dfile.name" - Complete"
                                        Add-Content $logFile "File Creation: $dfile.name - Complete"
                                    }
                               }
                       }
   }
 


$siteURL = Read-Host "Enter the Site collection URL - Eg:http://Yourwebapplication:1234/ "
$site = Get-SPSite -Identity  $siteURL
$sourceweb = $site.Openweb()
$sourcelist = $sourceweb.lists["LibraryA"]
$destinationlist = $sourceweb.lists["LibraryB"]

$SourceAdjacencyToMove = Read-Host "Enter the name of source Adjacency to be moved"
$DestinationAdjToMove = Read-Host "Enter the name of Destination Adjacency where the files has to be moved to :"
$ConfirmAdjToMove = Read-Host "Press (Y) to move all files ,Press (N) to select Group"


if($ConfirmAdjToMove -eq "N" -or $ConfirmAdjToMove -eq "n")
    {
        $SourceGroupToMove =Read-Host "Enter the Name of Group to be moved"
        create-fileitems -sourcelist $sourcelist -destinationlist $destinationlist -SourceAdjacencyToMove $SourceAdjacencyToMove  -ConfirmAdjToMove  $ConfirmAdjToMove -SourceGroupToMove $SourceGroupToMove -DestinationAdjToMove $DestinationAdjToMove -sourceweb $sourceweb
    }
elseif($ConfirmAdjToMove -eq "Y" -or $ConfirmAdjToMove -eq "y")
    {
        $SourceGroupToMove = " "
        create-fileitems -sourcelist $sourcelist -destinationlist $destinationlist -SourceAdjacencyToMove $SourceAdjacencyToMove  -ConfirmAdjToMove  $ConfirmAdjToMove -SourceGroupToMove $SourceGroupToMove -DestinationAdjToMove $DestinationAdjToMove  -sourceweb $sourceweb
    }




Note: I am using the "[Microsoft.Office.RecordsManagement.RecordsRepository.Records]" because I am working on the Record center and my files are marked as records .Without un-declaring as record ,you cannot perform any action on the document even through powershell or through C# codes.



Monday, March 2, 2015

Add Expiration/Rentention policy in Sharepoint Through powershell


Below is the power-shell script which can be used to add expiration/Retention policy in any version of share-point  through powershell.This helps in moving the policy from one environment to other in a very easy and hassle free way.
               Below power shell script adds the expiration policy to the Content Type at the site collection level ,This is designed to add at Site collection level because this can be run in the Content Hub hosting site and the policy can be migrated to other site collections which are leveraging the Hub.You can make the necessary changes to the script to add the policy at the "Library level" or" to the "content type " at the library level by instantiating the suitable object .
      The script below add the expiration policy like "DocumentDate+0 days" move to "Recycle bin"
"DocumentDate" is my custom column of DateTime type field.



$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"
}
$logFile = "LogFile_RDM_Expiration_Policy"

function AddExpirationPolicy($web , $contentTypes)
 {
     try
     {
        $arrayCT = $contentTypes.Split(",")
        foreach($CT in $arrayCT)
         {
              Write-host -for yellow "Checking if the Content type" $CT "exists ?"
              Add-Content $logFile "Checking if the Content type $CT exists ?"
              $CT = $web.ContentTypes[$CT]
              if($CT -ne $null)
              {
                Write-host -ForegroundColor green "Content Types -" $CT.Name  "exists !!"
                Add-Content $logFile "Content Types - $CT.Name exists !!"
                $policy=[Microsoft.Office.RecordsManagement.InformationPolicy.Policy]::GetPolicy($CT);
                 if ($policy -eq $null)
                   {
                    $policy=[Microsoft.Office.RecordsManagement.InformationPolicy.Policy]:: CreatePolicy($CT,$null);
                    $policy=[Microsoft.Office.RecordsManagement.InformationPolicy.Policy]::GetPolicy($CT);
                   }
                $policy.Description="Thilosh expiration Policy";
                $policy.Statement="Thilosh expiration Policy";
                $policy.Update();
                $expirypolicyexists=$false;
                if ($policy.Items.Count -ne 0)
                {
                foreach ($policyitem in $policy.Items)
                {
                    if ($policyitem.Name -eq "Retention")
                    {
                        $expirypolicyexists=$true;
                    }
                }
                }
                if ($expirypolicyexists -eq $false)
                 {
                $policyFeatureID = [Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration];
                #Expires data when the current date is equal to the document date set for the record      
                $customData = '<Schedules nextStageId="2">
                                <Schedule type="Default">
                                <stages>
                                  <data stageId="1">
                                    <formula id="Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration.Formula.BuiltIn">
                                      <number>0</number>
                                      <property>DocumentDate</property>                        
                                      <period>days</period>
                                    </formula>
                                    <action type="action" id="Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration.Action.MoveToRecycleBin" />
                                  </data>
                                </stages>
                              </Schedule>
                            </Schedules>'
                $policy.Items.Add($policyFeatureID,$customData);
                #$policy.Items.Add("Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration",$customData);
                $policy.Update();
                Write-Host -ForegroundColor Green  "Expiration  policy added for thr Content Type -" $CT.Name
                Add-Content $logFile "Expiration  policy added for thr Content Type - $CT.Name"
                 }
                else
                 {
                   Write-Host -ForegroundColor Red  "An expiry policy already exists and is not overwritten for the Content type -" $CT.Name
                   Add-Content $logFile   "An expiry policy already exists and is not overwritten for the Content type - $CT.Name"
                 }
              }
              else
              {
                Write-host -ForegroundColor red "Content Types -" $CT  "doesnot exists !!"
                Add-Content $logFile "Content Types - $CT doesnot exists !!"
              }
         
       }
     }
     catch
     {
         Write-Host  $_.Exception.Message      
         Add-Content $logFile    "***Error description Starts****`n"
         Add-Content $logFile    $_.Exception.Message        
         Add-Content $logFile    "***Error description ends****`n"

     }
 }

 $siteURL = Read-Host "Enter the Site collection URL - Eg:http://Thilosh:1234/ "
 $site = Get-SPSite -Identity  $siteURL
 $web = $site.RootWeb
 $contentTypes =  "ContentType1,ContentType2,ContentType3"

 AddExpirationPolicy $web $contentTypes

 $web.Dispose();
 $site.Dispose();




Read-Host "Press enter Key to exit !!"



Now you must be thinking how do I change the formula in "$customData ".This is very simple,You must have heard about a tool named "Sharepoint Manager" by using this you should be able to create formula for literally anything what ever possible in the sharepoint :)