Wednesday 13 May 2015

Moving Sharepoint Files from one site to another

http://blogs.msdn.com/b/rcormier/archive/2012/11/16/how-to-copy-sharepoint-documents-between-site-collections-using-powershell.aspx
https://gallery.technet.microsoft.com/Copy-all-SharePoint-Files-0999c53f

Download file:
https://drive.google.com/open?id=0B31LRFxQvY3hbWNHM3c4a2E2aGc&authuser=0


$ver = $host | select version
if($Ver.version.major -gt 1) {$Host.Runspace.ThreadOptions = "ReuseThread"}
if(!(Get-PSSnapin Microsoft.SharePoint.PowerShell -ea 0))
{
Write-Progress -Activity "Loading Modules" -Status "Loading Microsoft.SharePoint.PowerShell"
Add-PSSnapin Microsoft.SharePoint.PowerShell
}

##
#Set Static Variables
##


#SourceWebURL is the URL of the web which contains the source list
$SourceWebURL = "http://sharepoint.rcormier.local"

#SoureLibraryTitle is the title of the Source Library where documents reside
$SourceLibraryTitle = "Shared Documents"

#DestinationWebURL is the URL of the web in which you want to transfer your documents
$DestinationWebURL = "http://sharepoint.rcormier.local/sites/sts_0"

#DestinationLibraryTitle is the title of the destionation library in which you want to store your files
$DestinationLibraryTitle = "Shared Documents"

##
#Begin Script
##

#Retrieve the source web, using the parameter provided
$sWeb = Get-SPWeb $SourceWebURL

#Retrieve the source list using the parameter provided
$sList = $sWeb.Lists | ? {$_.Title -eq $SourceLibraryTitle}

#Retrieve the destination web using the parameter provided
$dWeb = Get-SPWeb $DestinationWebURL

#Retrieve the source list using the parameter provided
$dList = $dWeb.Lists | ? {$_.title -like $DestinationLibraryTitle}

#Retrieve all folders in the source list.  This used to maintain the folder structure in source and destination libraries.  This excludes the root folder
$AllFolders = $sList.Folders

#Retrieve the root folder in the source list.
$RootFolder = $sList.RootFolder

#Return all files that exist directly in the root of the library
$RootItems = $RootFolder.files

#Loop through each of the documents discovered in the root of the library and perform some action
foreach($RootItem in $RootItems)
{
    #Get the Binary Stream of the referenced file, such that we can create the same file in the destination environment
    $sBytes = $RootItem.OpenBinary()

    #Create A New file using the name and binary stream from the original document, assign it to a variable.  This variable will later be called when setting properties
    $dFile = $dList.RootFolder.Files.Add($RootItem.Name, $sBytes, $true)

    #Return all fields for the source item which are not read-only
    $AllFields = $RootItem.Item.Fields | ? {!($_.sealed)}

    #Loop through all of the fields returned and perform some action
    foreach($Field in $AllFields)
    {
        #If the source item has a property that matches the name of the field perform some action
        if($RootItem.Properties[$Field.Title])
        {
            #If the destination file does not contain the same property as the source item perform some action.
            if(!($dFile.Properties[$Field.title]))
            {
                #Add a property to the file matching title and value of the same field in the original item
                $dFile.AddProperty($Field.Title, $RootItem.Properties[$Field.Title])
            }
            else
            {
                #If the property already exists, set the value on the destination item to the same value as it was in the source item.
                $dFile.Properties[$Field.Title] = $RootItem.Properties[$Field.Title]
            }

        }
    }
    #Commit the changes by updating the destination file.
    $dFile.Update()
}

#loop through all folders which are not the root folder
foreach($Folder in $AllFolders)
{
    #Since we're looping quite a bit and re-building the ParentFolderURL, make sure it doesn't exist every time we switch folders
    Remove-Variable ParentFolderURL

    #Since we're looping through sections of the folder URL, we need something to start at zero and increment as we loop through sections of the Folder URL
    $i = 0

    #Break the Folder URL up into sections, separated by "/"
    $FolderURL = $Folder.url.Split("/")

    #Perform a variable number of actions against the Folder URL based on the number of sections in FolderURL
    while($i -lt ($FolderURL.count-1))
    {
    #Keep apending the Folder section in order to build the parent folder URL
    $ParentFolderURL = "$ParentFolderURL/" + $FolderURL[$i]

    #Increment the I variable in order to move forward through the folder structure
    $i++
    }

    $CurrentFolder = $dList.Folders | ? {$_.url -eq $ParentFolderURL.substring(1)}
    #If the destination list does not contain a folder with the same name, create it
    if(!($CurrentFolder.Folders | ? {$_.name -eq $Folder.Name}))
    {
        #Create a Folder in the destination library with the same name as it had in the source library, in the same relative location
        $NewFolder = $dlist.Folders.Add(("$DestinationWebURL" + $ParentFolderURL), [Microsoft.SharePoint.SPFileSystemObjectType]::Folder, $Folder.name)

        #Finalize creating the folder by calling update
        $NewFolder.update()
    }
    else
    {
        #If the folder already exists, retrieve the folder where the file will be created
        $NewFolder = $dList.Folders | ? {$_.name -eq $Folder.Name}
    }

    #Return all files from the source list.  we will use this later to perform updates on items
    $AllFiles = $sList.Items

    #Return all items from the current folder
    $sItems = $Folder.folder.Files

    #If the folder we're currently in has more than zero objects, perform some actions.
    if($Folder.Folder.Files.count -gt 0)
    {
        #Perform some actions against each object in the current folder
        foreach($item in $sItems)
        {
            #Get the relative URL from the current item            
            $Relative = ($Item.ServerRelativeUrl).substring(1)

            #Based on the relative path of the current item, retrieve the file from the site
            $TargetItem = $AllFiles | ? {$_.URL -eq $Relative}

            #Retrieve the binary stream of the current file
            $sBytes = $TargetItem.File.OpenBinary()

            #Create a file in destination library, same relative folder, using the current file's name and binary stream
            $dFile = $Newfolder.Folder.Files.Add($TargetItem.Name, $sBytes, $true)

            #Return all fields for the source item which are not read-
            $AllFields = $TargetItem.Fields | ? {!($_.sealed)}

            #Loop through all of the fields returned and perform some action
            foreach($Field in $AllFields)
            {
                #If the destination file does not contain the same property as the source item perform some action.
                if($TargetItem.Properties[$Field.Title])
                {
                    #If the destination file does not contain the same property as the source item perform some action.
                    if(!($dFile.Properties[$Field.title]))
                    {
                        #Add a property to the file matching title and value of the same field in the original item
                        $dFile.AddProperty($Field.Title, $TargetItem.Properties[$Field.Title])
                    }
                    else
                    {
                        #If the property already exists, set the value on the destination item to the same value as it was in the source item.
                        $dFile.Properties[$Field.Title] = $TargetItem.Properties[$Field.Title]
                    }

                }
            }
            #Commit the changes by updating the destination file.
            $dFile.Update()
                    }
    }
}

Thursday 7 May 2015

Jquery Accordin-- jquery-multi-open-accordion

<div id="multiAccordion">
<h3><a href="#">tab 1</a></h3>
<div>
Lorem ipsum dolor sit amet
</div>
<h3><a href="#">tab 2</a></h3>
<div>
Lorem ipsum dolor sit amet
</div>
<h3><a href="#">tab 3</a></h3>
<div>
Lorem ipsum dolor sit amet
</div>
<h3><a href="#">tab 4</a></h3>
<div>
Lorem ipsum dolor sit amet
</div>
</div>
Script:
$(function(){
$('#multiAccordion').multiAccordion();
});
 Update:
$(function(){

  // this will make the second tab by default opened (index starts from 0)
  $('#multiAccordion').multiAccordion({active: 1 }); 

  // [ OR ]
  // supports multiple tabs to be opened by default
  $('#multiAccordion').multiAccordion({active: [1, 2, 3] }); 

  // show all tabs
  $('#multiAccordion').multiAccordion({active: 'all' });

  // hide all tabs
  $('#multiAccordion').multiAccordion({active: 'none' });

  // you can set the options as any jQuery UI plugin using option method
  $('#multiAccordion').multiAccordion('option', 'active', 'all');
});
 
 
Jquery:
/*
 * jQuery UI Multi Open Accordion Plugin
 * Author : Anas Nakawa (http://anasnakawa.wordpress.com/)
 * Date  : 22-Jul-2011
 * Released Under MIT License
 * You are welcome to enhance this plugin at https://code.google.com/p/jquery-multi-open-accordion/
 */
(function($){
 
 $.widget('ui.multiAccordion', {
  options: {
   active: 0,
   showAll: null,
   hideAll: null,
   _classes: {
    accordion: 'ui-accordion ui-widget ui-helper-reset ui-accordion-icons',
    h3: 'ui-accordion-header ui-helper-reset ui-state-default ui-corner-all',
    div: 'ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom',
    divActive: 'ui-accordion-content-active',
    span: 'ui-icon ui-icon-triangle-1-e',
    stateDefault: 'ui-state-default',
    stateHover: 'ui-state-hover'
   } 
  },

  _create: function() {
   var self = this,
   
   options  = self.options,
   
   $this = self.element,
   
   $h3 = $this.children('h3'),
   
   $div = $this.children('div');
   
   $this.addClass(options._classes.accordion);
   
   $h3.each(function(index){
    var $this = $(this);
    $this.addClass(options._classes.h3).prepend('<span class="{class}"></span>'.replace(/{class}/, options._classes.span));
    if(self._isActive(index)) {
     self._showTab($this)
    }
   }); // end h3 each
   
   $this.children('div').each(function(index){
    var $this = $(this);
    $this.addClass(options._classes.div);
   }); // end each
   
   $h3.bind('click', function(e){
    // preventing on click to navigate to the top of document
    e.preventDefault();
    var $this = $(this);
    var ui = {
     tab: $this,
     content: $this.next('div')
    };
    self._trigger('click', null, ui);
    if ($this.hasClass(options._classes.stateDefault)) {
     self._showTab($this);
    } else {
     self._hideTab($this);
    }
   });
   
   
   $h3.bind('mouseover', function(){
    $(this).addClass(options._classes.stateHover);
   });
   
   $h3.bind('mouseout', function(){
    $(this).removeClass(options._classes.stateHover);
   });
   
   // triggering initialized
   self._trigger('init', null, $this);
   
  },
  
  // destroying the whole multi open widget
  destroy: function() {
   var self = this;
   var $this = self.element;
   var $h3 = $this.children('h3');
   var $div = $this.children('div');
   var options = self.options;
   $this.children('h3').unbind('click mouseover mouseout');
   $this.removeClass(options._classes.accordion);
   $h3.removeClass(options._classes.h3).removeClass('ui-state-default ui-corner-all ui-state-active ui-corner-top').children('span').remove();
   $div.removeClass(options._classes.div + ' ' + options._classes.divActive).show();
  },
  
  // private helper method that used to show tabs
  _showTab: function($this) {
   var $span = $this.children('span.ui-icon');
   var $div = $this.next();
   var options = this.options;
   $this.removeClass('ui-state-default ui-corner-all').addClass('ui-state-active ui-corner-top');
   $span.removeClass('ui-icon-triangle-1-e').addClass('ui-icon-triangle-1-s');
   $div.slideDown('fast', function(){
    $div.addClass(options._classes.divActive);
   });
   var ui = {
    tab: $this,
    content: $this.next('div')
   }
   this._trigger('tabShown', null, ui);
  },
  
  // private helper method that used to show tabs 
  _hideTab: function($this) {
   var $span = $this.children('span.ui-icon');
   var $div = $this.next();
   var options = this.options;
   $this.removeClass('ui-state-active ui-corner-top').addClass('ui-state-default ui-corner-all');
   $span.removeClass('ui-icon-triangle-1-s').addClass('ui-icon-triangle-1-e');
   $div.slideUp('fast', function(){
    $div.removeClass(options._classes.divActive);
   });
   var ui = {
    tab: $this,
    content: $this.next('div')
   }
   this._trigger('tabHidden', null, ui);
  },
  
  // helper method to determine wether passed parameter is an index of an active tab or not
  _isActive: function(num) {
   var options = this.options;
   // if array
   if(typeof options.active == "boolean" && !options.active) {
    return false;
   } else {
    if(options.active.length != undefined) {
     for (var i = 0; i < options.active.length ; i++) {
      if(options.active[i] == num)
       return true;
     }
    } else {
     return options.active == num;
    }
   }
   return false;
  },
  
  // return object contain currently opened tabs
  _getActiveTabs: function() {
   var $this = this.element;
   var ui = [];
   $this.children('div').each(function(index){
    var $content = $(this);
    if($content.is(':visible')) {
     //ui = ui ? ui : [];
     ui.push({
      index: index,
      tab: $content.prev('h3'),
      content: $content
     });
    }
   });
   return (ui.length == 0 ? undefined : ui);
  },
  
  getActiveTabs: function() {
   var el = this.element;
   var tabs = [];
   el.children('div').each(function(index){
    if($(this).is(':visible')) {
     tabs.push(index);
    }
   });
   return (tabs.length == 0 ? [-1] : tabs);
  },
  
  // setting array of active tabs
  _setActiveTabs: function(tabs) {
   var self = this;
   var $this = this.element;
   if(typeof tabs != 'undefined') {
    $this.children('div').each(function(index){
     var $tab = $(this).prev('h3');
     if(tabs.hasObject(index)) {
      self._showTab($tab);
     } else {
      self._hideTab($tab);
     }
    });
   }
  },
  
  // active option passed by plugin, this method will read it and convert it into array of tab indexes
  _generateTabsArrayFromOptions: function(tabOption) {
   var tabs = [];
   var self = this;
   var $this = self.element;
   var size = $this.children('h3').size();
   if($.type(tabOption) === 'array') {
    return tabOption;
   } else if($.type(tabOption) === 'number') {
    return [tabOption];
   } else if($.type(tabOption) === 'string') {
    switch(tabOption.toLowerCase()) {
     case 'all':
      var size = $this.children('h3').size();
      for(var n = 0 ; n < size ; n++) {
       tabs.push(n);
      }
      return tabs;
      break;
     case 'none':
      tabs = [-1];
      return tabs;
      break;
     default:
      return undefined;
      break;
    }
   }
  },
  
  // required method by jquery ui widget framework, used to provide the ability to pass options
  // currently only active option is used here, may grow in the future
  _setOption: function(option, value){
   $.Widget.prototype._setOption.apply( this, arguments );
   var el = this.element;
   switch(option) {
    case 'active':
     this._setActiveTabs(this._generateTabsArrayFromOptions(value));
     break;
    case 'getActiveTabs':
     var el = this.element;
     var tabs;
     el.children('div').each(function(index){
      if($(this).is(':visible')) {
       tabs = tabs ? tabs : [];
       tabs.push(index);
      }
     });
     return (tabs.length == 0 ? [-1] : tabs);
     break;
   }
  }
  
 });
 
 // helper array has object function
 // thanks to @Vinko Vrsalovic
 // http://stackoverflow.com/questions/143847/best-way-to-find-an-item-in-a-javascript-array
 Array.prototype.hasObject = (!Array.indexOf ? function (o) {
     var l = this.length + 1;
     while (l -= 1) {
         if (this[l - 1] === o) {
             return true;
         }
     }
     return false;
   }: function (o) {
     return (this.indexOf(o) !== -1);
   }
 );
 
})(jQuery); 


Reference:

https://anasnakawa.wordpress.com/2011/01/25/jquery-ui-multi-open-accordion/

Powershell:Add and deploy multiple wsp

Introduction

In SharePoint 2010 if we want to deploy the wsp; we will just right click the project and select deploy. SharePoint will take care of deploying with the given settings.
But,we can’t deploy the package in the same way in other environments like UAT, PreProduction or Production (unless you are a super user having permission in all environments and you have source code of the package)
In this article I will provide a generic method where you just provide the path of the folder where wsp is located (more than one wsp is also supported) and the function will take care to install wsp. It will be very useful while deploying in any environments

Deploy WSP

Following is the example how to use the generic function Deploy-SPSolution
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Remove-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue
Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue
 
function WaitForInsallation([string] $Name)
{
        Write-Host -NoNewline "Waiting for deployment job to complete" $Name "."
        $wspSol = get-SpSolution $Name
        while($wspSol.JobExists)
        {
            sleep 2
            Write-Host -NoNewline "."
            $wspSol = get-SpSolution $Name
        }
        Write-Host "job ended" -ForegroundColor green
}
 
Function Deploy-SPSolution ($WspFolderPath)
{
    $wspFiles = get-childitem $WspFolderPath | where {$_.Name -like "*.wsp"}
 
    ForEach($file in $wspFiles)
    {
        $wsp = Get-SPSolution | Where{$_.Name -eq $file.Name}
        if($wsp -eq $null)
        {
            write-host "Adding solution"
            Add-SPSolution -LiteralPath ($WspFolderPath + "\" + $file.Name)
        }
        else
        {
            write-host "solution already exists"
 
            if($wsp.Deployed -eq $true)
            {
                write-host "solution is deployed already, updating the solution"
                Update-SPSolution -identity $wsp.SolutionId -LiteralPath ($WspFolderPath + "\" + $file.Name) -GACDeployment
            }
             else
            {
               write-host "Removing solution"
               Remove-SPSolution -identity $wsp.SolutionId -confirm:$false
 
                write-host "Adding solution"
               Add-SPSolution -LiteralPath ($WspFolderPath + "\" + $file.Name)
            }
            WaitForInsallation -Name $wsp.Name
        }
 
        $wsp = Get-SPSolution | Where {$_.Name -eq $file.Name}
        if($wsp -ne $null)
        {
            write-host "installing solution"
            Install-SPSolution -identity $wsp.SolutionId -GACDeployment -force
        }
        WaitForInsallation -Name $wsp.Name
 
    }
    write-host "Done"
}
try
{
        Deploy-SPSolution "C:\Custom\Projects\AdiCodes\WspPackages"
}
catch
{
    write-host $_.exception
 
}

Description

Usage:
Deploy-SPSolution “C:\Custom\Projects\AdiCodes\WspPackages”
“C:\Custom\Projects\AdiCodes\WspPackages” is the folder path where wsp packages are resided.
Function will read all the wsp’s inside the specified folder.
Deploy-SPSolution will be using another function WaitForInsallation inside it.
This function is necessary because, we cannot install application before previous job is completed. If this function is not there we will get errors similar like

Install-SPSolution : A deployment or retraction is already under way for the solution “xxx.wsp”, and only one deployment or retraction at a time is supported.

If you are getting the error that means, you are trying to deploy wsp where timer job is already busy deploying with previous wsp.
You can try checking timer job status from central admin. If timer job is still running you cannot deploy until its job is done.
If at any case you are stuck and always getting this error, then you need to restart timer job in web front end server and also in app server.

Remarks

The above function considers the wsp’s to be deployed in GAC. If the wsp is targeted to a specific webapplication with any CASPolicies rather than GAC, remove the code from line 49 to 55 and place the following code in the above function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$url="http://AdisGroup/MySite"
write-host "url address" $url
$webApp=Get-SPWebApplication -identity $url
$wsp = Get-SPSolution | Where {$_.Name -eq $file.Name}
$DeployedWebapps=$sol.DeployedWebApplications | where {$_.Url -like $url }
if($DeployedWebapps -eq $null)
{
    Write-host "Deploy Solution" $wsp.Name
    #Change the following line of code according to the targetted settings of wsp
    $wsp |Install-SPSolution -WebApplication $webApp.Url -CASPolicies -GACDeployment -Force
}
else
{
    Write-host "Update Solution" $wsp.Name
    $wsp |Update-SPSolution  -LiteralPath $wsp.FullName -Force
}
WaitForInsallation -Name $wsp.Name

Conclusion

With the above method it should be quicker to deploy any wsp in any environment without dependency on visual studio.
I prefer using logging and config mechanism to include along with code to make it more generic.
Refer best way to use config file and how to log information in powershell if you are not aware of.
If you are stuck up or if you face any problems while executing the above script, drop a comment. Happy coding :)

You may also like