SharePoint 2013 Move Documents to Another Library Using Content Organizer Web Service

A common task for document management system is to move a document from one library to another based on a particular condition or content type. To enable this feature, SharePoint provides some core actions that can let you copy the document to another site collection and then delete it from the source. 

In our case, we want to be able to move the document using a more complex action called Send Document to Repository which moves a document by using the Content Organizer Web Service.

Note:  Content type enables us to organize documents and associate them to content rules which can enable us to route documents to specific document libraries.

Configure the Content Organizer Feature

This core action enables us to move a document to another library within the same site collection using a SharePoint web service named Official File. In order to enable this web service endpoint, we need to enable a site feature and configure some content rules.

We first activate this feature by visiting this page:
  • Click on site setting
  • Click on site features
  • Look for Content Organizer and activate this feature

Content Organizer Rules
Create metadata based rules that move content submitted to this site to the correct library or folder.

This enables the web service that we can use to move the document. The end point is found at a location relative to your site collection for example:

_vti_bin/OfficialFile.asmx  or  sites/demo/_vti_bin/OfficialFile.asmx

Note:  We use this address when we add the workflow action.

This web service address can also be found by visiting the following page: 
  • Site Settings
  • Under Site Administration select Content Organizer Settings

Create the Content Rule

Now that the service is available to the site collection, we need to configure a rule that indicates what type of content type we want to manage and to what library we need to send this content. This is done by visiting the following page:
  • Site Settings
  • Under Site Administration select Content Organizer Rules

We want a rule for the Document content type, and we want to send the document to the ArchiveLibray.  As we can see, here we could route documents based on custom content types to other libraries.

Note: When using custom content types, we can have a more granular set of rules to send documents to other libraries that are based on that content type.

Workflow Send to Document Repository Action

We have now setup all the requirements to be able to send or move our document to another location.  We can now add a workflow using SharePoint Designer.  On our first step, we want to add the Send Document to Repository action.

Note: SharePoint 2010 Workflows provide this action.

This workflow action has three parameters


This action
This allows us to indicate to copy or move the document.

This destination content organizer
This is needed to indicate where the web service is located. Use the address that was identified on the previous sections.

This explanation
Use this parameter to add some comment about the action.

In our example, we are deciding to move the document using our previously defined Content Organizer Web Service. In this example, there are no specific conditions to validate for this action, but this is the area we can validate a document status and run the action accordingly.


We have shown how to use the Content Organizer Web Service and a workflow action. With this approach there are more configuration steps that need to be complete in order to support the solution.  The additional configuration does bring added value as it can enable us to route documents based on their content type to other document libraries.

For cases where a simpler approach is desirable, we can refer to the article below which essentially shows us how to use the Copy and Delete core actions to implement a simpler Move action.

I hope this is able to show you a way to move document across document locations using a workflow action and the Content Organizer Web Service.

Originally published by ozkary.com


SharePoint 2013 Workflow Move Documents With Copy and Delete Actions

 A common task for document management system is to move a document from one library to another when the document approval status meets some condition.  Unfortunately, there is no Move core action provided from the out of box functionality.  There is however other core actions that we can leverage to implement this solution.

Move Documents

Workflow Core Actions

When building our workflows, we can use a couple of actions that enable us to move a document from one document library to another.

Core Action


Use this action to copy the document across document libraries

This list
The item to copy. Set to current item
This list
The target document library


Use this action to delete the document from a document library

This list
The document item to delete. Set to current item

Implementing a Move workflow

After adding a workflow using SharePoint Designer, we can add a couple of actions to the first step.

For the copy item action, we want to select the current item which is a reference to the document that triggers the workflow. We also select the document library where we want to copy the document. This action makes a copy of the document, so this means that the document is located in two different document libraries which may not be the intended behavior.

After the document is copied, we can delete the document from the current location using the Delete action and passing the current item as an argument. This should remove the other copy from the source document library.

In our example, we copy the current item to a Drop Off document library. Since we do not want a copy of the document on the source library, we then delete the current item.

Note:  Current item is the scope object reference to the document that triggers the workflow.


We have shown that a move action can be implemented using the Copy and Delete core actions. For some use cases, this may not be a correct implementation since this creates a copy of the document and a different document id which uniquely identifies a document in the system.

 When this behavior does not meet our requirements, there is another core action that we can use to actually move the document. This approach however comes at a cost of more configuration complexity as well as the need to enable other site features.  We can read more about this on my next blog entry:

I hope this is able to provide you with a simple approach to move a document from one document library to another.

Originally published by ozkary.com


SharePoint Create a host-named Site with PowerShell

On SharePoint, we usually create site collections using the path-based route. This approach aligns very well with the SharePoint online/Office 365 site structure recommendations. With SharePoint 2013, we can create a site collection using a host-named site which allows us to assign a unique DNS name to our site collections. This enables us to deploy multiple sites with different DNS names in the same web application.

Path-named vs Host-named

Site Collection Structure

In order to deploy a host-named site, we need to create a DNS entry that points to the SharePoint host server/farm. We then need to write some code using PowerShell as this feature is not available from the Admin Central.

To create the site collection, we run this custom function from PowerShell with elevated permissions.

# Name: createHostNamedSite
# Description:  Creates a host-named site collection
# Usage
# createSite web-app-name, dns-entry site-name site-description admin-account-name site-template content-database
createHostNamedSite "ozkary.com" "https://demosite1.ozkary.com" "Demo Site 1" "Demo Site 1 Description" "admin-account" "STS#0" "WSS_Content_DB"

Parameter Information

Main SharePoint web app name where site collections are hosted
The unique DNS entry for the site
The name for the site collection
The site description
The site collection owner usually the admin
A site template like team site, document center

Click here to see more templates
The content database for this site collection

createHostNameSite Function

Add-PSSnapin microsoft.sharepoint.powershell -ErrorAction SilentlyContinue

#  Name: createHostNameSite
#  Description: create a host-named site collection
#  Params:
#       $webAppName 
#       $siteUrl
#       $siteName
#       $description
#       $owner
#       $template
#       $contentDatabase 
function createHostNameSite($webAppName, $siteUrl, $siteName, $description, $owner,$template, $contentDatabase)
    write-host "Creating site with parameters " $webAppName, $siteUrl, $siteName, $description, $owner,$template, $contentDatabase , $mapUrl

    $continue = Read-Host -Prompt "Do you want to continue (y/n)"
    if ($continue -eq "y")
        write-host "Provisioning Site...."       
        New-SPSite $siteUrl  -Name $siteName -Description $description -OwnerAlias $owner -Template $template  -ContentDatabase  $contentDatabase  -HostHeaderWebApplication (Get-SPWebApplication $webAppName)               

        write-host "Process cancelled"


On the code , we first include the SharePoint plug-in which enables us to use the New-SPSite cmdlet that handles all the hard work for us.  Another area to notice is that there is the HostHeaderWebApplication parameter for which we pass the SharePoint web application reference by using the Get-SPWebApplication cmdlet. This is what enables us to create the host-named site.

After the site is created, we should be able to type the DNS name, and if it is already created and propagated in your network, the request should be able to be sent to SharePoint which can load the corresponding site properly.

I hope this is helpful and enjoy your site creation automation (DevOps) with PowerShell. 

Originally published by ozkary.com


Powershell Upload Multiple Files to SharePoint

SharePoint document library enables us to manage documents. In some cases, we need to upload multiple files to that library.  A common approach to automate this process is to integrate via the SharePoint Restful APIs. In this article, we take a look at using PowerShell to create a script that can quickly enable this integration without having the need to know all the details of the API.


For our use case, we have a drop location where our files are located. We need to read all the files and upload them to a SharePoint document library.

Note: We can run this snippet using Visual Studio Code. Just save the file with an extension of ps1, and VS Code will guide you on installing the PowerShell extensions.

# include the web cmdlets
Add-PSSnapin microsoft.sharepoint.powershell

# name:  uploadFiles
# purpose: upload multiple files from a shared location
function uploadFiles($path, $siteUrl)

try {

  # gets all the files (-File) in the directory
  $files = Get-ChildItem -Path $path –File

  #iterate thru each file
  foreach($file in $files) 
      $url = $siteUrl + $file
      $filePath = $path + $file

      #upload the file to the server using default credentials from the
      #current session
      $result = Invoke-WebRequest -Uri $url -InFile $filePath -Method PUT

      #if the request status code is successful, we delete the files
      #else write an error message
      if($result.statuscode -eq 200){       
        Remove-Item $filePath -Force
        write-host "Failed to upload" $filePath $result.statuscode
catch {
  write-host "Exception was raised: $PSItem" #psitem is the error object


#uploadFiles parm0 param1
#param[0] shared-location 
#param[1] sharepoint document library url
UploadFiles "\\some-document-path" "https://ozkary.com/shared-docs/"

In this snippet, we first need to include the snap-in for SharePoint. This loads the web cmdlets that provide the implementation abstraction to the SharePoint APIs.

The uploadFiles function enables us to read a folder location and lists only the files. We then iterate thru each file and use the Invoke-WebRequest to load them to a particular SharePoint document library. If the response has Status 200, we know that the upload was a success, and we remove the file. Otherwise, we write to the standard output using write-host.


We should notice that when uploading the files, we use the -DefaultCredentials parameter.  This enables our script to pass the current session credentials to the request.  The credentials are set when the script is executed under the context of a particular service account that has access to the SharePoint document library.

 I hope this provides a quick automated way to upload files to your document libraries.

Originally published by ozkary.com