Thursday, August 14, 2014

Copy Documents and Folders Between Two Libraries With Metadata Using PowerShell

The following PowerShell enables you to copy documents and folders between two SharePoint libraries.

Keywords: SharePoint, SharePoint 2010, SharePoint 2013, PowerShell

Add-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue

function CopyFilesInFolder($srcFolder , $dstFolder)
{
      #get files inside srcFolder
      $srcItems = $srcFolder.files
      $nCount = $srcItems.Count
      $i= $nCount - 1
      #start copying files from srcFodler to dstFolder
      foreach($srcItem in $srcItems )
      {
            Try
            {
                  $srcItem.CopyTo($dstFolder.ServerRelativeUrl + "/" +  $srcItem.Name ,$true)
                  $newFileLoc =  $dstFolder.ServerRelativeUrl + "/" +  $srcItem.Name
                  Write-host $newFileLoc
                 
            }
            Catch [system.exception]
            {
                   $_.Exception.Message
            }
           
            Finally
            {
                   
            }

      }#end while
     
      #iterate over each subfolder inside $srcFolder
      #create equivalent subfolder under $dstFolde
      #call the CopyFilesInFolder
      foreach($srcSubFolder in  $srcFolder.SubFolders)
      {
            if($srcSubFolder.Name -ne "Forms")
            {
                  $dstSubFolder =  $dstFolder.SubFolders.Add($srcSubFolder.Name)
                  CopyFilesInFolder -srcFolder $srcSubFolder  -dstFolder $dstSubFolder
            }
           
      }
     

}#end function


#get source list  and destination list
$web = get-spWeb  "http://URl/"
$srcList = $web.Lists["srcLib" ]
$dstList = $web.Lists["dstLib"]


#get the root folder and items/files
$srcRootFolder = $srcList.RootFolder;
$dstRootFolder = $dstList.RootFolder;
CopyFilesInFolder -srcFolder $srcRootFolder  -dstFolder $dstRootFolder


Enjoy

Wednesday, August 13, 2014

Timer Job Fires Multiple Times

This happens because the way you call your timer job constructor. You should use SPJobLockType.Job NOT SPJobLockType.ContentDatabase.  Constructor Code should look like the following

Keywords: SharePoint, SharePoint 2010, SharePoint 2013, Timer Jobs

public ConventusMDToAXTimerJob(): base()
{
}

public ConventusMDToAXTimerJob(string jobName, SPWebApplication webApplication)
:base(jobName, webApplication, null, SPJobLockType.Job)
{
    this.Title = JOB_NAME;
}

Problem solved. Enjoy

Copy Documents Between Two Libraries With Metadata Using PowerShell

The PowerShell script below shows you how to copy files and their metadata from one library to another.

Keywords: SharePoint, SharePoint 2010, SharePoint 2013, PowerShell

Add-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue

#get source list and destination list
$web = get-spWeb  "http://targetURL/"
$srcList = $web.Lists["srcLib" ]
$dstList = $web.Lists["dstLib"]

#get the content type
$ct = $srcList.ContentTypes["TargetCT"]

#get the root folder and items/files
$srcRootFolder = $srcList.RootFolder
$srcItems = $srcRootFolder.files


#iterate over files and copy them over with properties.
foreach($srcItem in $srcItems)
{
      Try
      {
             #copy over the files
             $sBytes = $srcItem.OpenBinary()
             $dstItem = $dstList.RootFolder.Files.Add($srcItem.Name, $sBytes, $true).Item
           
            #copy over files properties
            foreach($spField in $ct.Fields)
        {
          if ($spField.ReadOnlyField -ne $True )
          {
              $dstItem[$spField.InternalName] = $srcItem.Item[$spField.InternalName];
          }
             
        }
     
        $dstItem.Update()

      }
      Catch [system.exception]
      {
             $_.Exception.Message
      }
     
      Finally
      {
             
      }


}