Working with folders and files via SharePoint 2013 REST in PowerShell

Overview

In the previous post we’ve already discussed how to perform CRUD operations by sending HTTPS requests to SharePoint RESTful web services in PoweShell. The Invoke-RestSPO function was introduced for that purpose since  Invoke-RestMethod cmdlet does not support claims based authentication and it makes this cmdlet impossible to use in O365 and SharePoint Online scenarios.

This time I am going to demonstrate how  to perform basic create, read, update, and delete (CRUD) operations on folders and files with the SharePoint 2013 REST interface using Invoke-RestSPO function.

Explore the REST service files and folder syntax

SharePoint 20123 Files and Folders REST syntax

 

Working with folders

Folder resource: represents a folder on a SharePoint Web site

Endpoint URI: http://<site url>/_api/web/getfolderbyserverrelativeurl(‘/<folder name>‘)

Supported HTTP methods:  GET  |  POST  |  DELETE  |  MERGE  |  PUT

The following examples demonstrates how to perform basic CRUD operations with Folder resource.

 

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")
. ".\Invoke-RestSPO.ps1"
<#
.SYNOPSIS
Retieve Folder
.DESCRIPTION
Read Folder operation via SharePoint 2013 REST API
url: http://site url/_api/web/GetFolderByServerRelativeUrl('/Shared Documents')
method: GET
headers:
Authorization: "Bearer " + accessToken
accept: "application/json;odata=verbose" or "application/atom+xml"
.NOTES
Prerequisite : Invoke-RestSPO function
.EXAMPLE
$Folder = Get-SPOFolder -WebUrl $WebUrl -UserName $UserName -Password $Password -FolderUrl '/Shared Documents/Folder To Read'
#>
Function Get-SPOFolder(){
Param(
[Parameter(Mandatory=$True)]
[String]$WebUrl,
[Parameter(Mandatory=$True)]
[String]$UserName,
[Parameter(Mandatory=$False)]
[String]$Password,
[Parameter(Mandatory=$True)]
[String]$FolderUrl
)
$Url = $WebUrl + "/_api/web/GetFolderByServerRelativeUrl('" + $FolderUrl + "')"
Invoke-RestSPO $Url Get $UserName $Password
}
<#
.SYNOPSIS
Create Folder
.DESCRIPTION
Create Folder operation via SharePoint 2013 REST API.
url: http://site url/_api/web/folders
method: POST
body: { '__metadata': { 'type': 'SP.Folder' }, 'ServerRelativeUrl': '/document library relative url/folder name'}
Headers:
Authorization: "Bearer " + accessToken
X-RequestDigest: form digest value
accept: "application/json;odata=verbose"
content-type: "application/json;odata=verbose"
content-length:length of post body
.NOTES
Prerequisite : Invoke-RestSPO function
.EXAMPLE
$Folder = Create-SPOFolder -WebUrl $WebUrl -UserName $UserName -Password $Password -FolderUrl '/Shared Documents/Folder To Create'
#>
Function Create-SPOFolder(){
Param(
[Parameter(Mandatory=$True)]
[String]$WebUrl,
[Parameter(Mandatory=$True)]
[String]$UserName,
[Parameter(Mandatory=$False)]
[String]$Password,
[Parameter(Mandatory=$True)]
[String]$FolderUrl
)
$Url = $WebUrl + "/_api/web/folders"
$folderPayload = @{
__metadata = @{'type' = 'SP.Folder' };
ServerRelativeUrl = $FolderUrl;
} | ConvertTo-Json
$contextInfo = Get-SPOContextInfo $WebUrl $UserName $Password
Invoke-RestSPO Url $Url Method Post UserName $UserName Password $Password Metadata $folderPayload RequestDigest $contextInfo.GetContextWebInformation.FormDigestValue
}
<#
.SYNOPSIS
Update Folder
.DESCRIPTION
Update Folder operation via SharePoint 2013 REST API.
url: http://site url/_api/web/GetFolderByServerRelativeUrl('/Folder Name')
method: POST
body: { '__metadata': { 'type': 'SP.Folder' }, 'Name': 'New name' }
Headers:
Authorization: "Bearer " + accessToken
X-RequestDigest: form digest value
"IF-MATCH": etag or "*"
"X-HTTP-Method":"MERGE",
accept: "application/json;odata=verbose"
content-type: "application/json;odata=verbose"
content-length:length of post body
.NOTES
Prerequisite : Invoke-RestSPO function
.EXAMPLE
Update-SPOFolder -WebUrl $WebUrl -UserName $UserName -Password $Password -FolderUrl '/Shared Documents/Folder To Update' -FolderName "New Folder Name"
#>
Function Update-SPOFolder(){
Param(
[Parameter(Mandatory=$True)]
[String]$WebUrl,
[Parameter(Mandatory=$True)]
[String]$UserName,
[Parameter(Mandatory=$False)]
[String]$Password,
[Parameter(Mandatory=$True)]
[String]$FolderUrl,
[Parameter(Mandatory=$True)]
[String]$FolderName
)
$Url = $WebUrl + "/_api/web/GetFolderByServerRelativeUrl('" + $FolderUrl + "')"
$folderPayload = @{
__metadata = @{'type' = 'SP.Folder' };
}
if($FolderName) {
$folderPayload['Name'] = $FolderName
}
$folderPayload = $folderPayload | ConvertTo-Json
$contextInfo = Get-SPOContextInfo $WebUrl $UserName $Password
Invoke-RestSPO Url $Url Method Post UserName $UserName Password $Password Metadata $folderPayload RequestDigest $contextInfo.GetContextWebInformation.FormDigestValue ETag "*" XHTTPMethod "MERGE"
}
<#
.SYNOPSIS
Delete Folder
.DESCRIPTION
Delete Folder operation via SharePoint 2013 REST API.
url: http://site url/_api/web/GetFolderByServerRelativeUrl('/Folder Name')
method: POST
Headers:
Authorization: "Bearer " + accessToken
X-RequestDigest: form digest value
"IF-MATCH": etag or "*"
"X-HTTP-Method":"DELETE"
.NOTES
Prerequisite : Invoke-RestSPO function
.EXAMPLE
Delete-SPOFolder -WebUrl $WebUrl -UserName $UserName -Password $Password -FolderUrl '/Shared Documents/Folder To Delete'
#>
Function Delete-SPOFolder(){
Param(
[Parameter(Mandatory=$True)]
[String]$WebUrl,
[Parameter(Mandatory=$True)]
[String]$UserName,
[Parameter(Mandatory=$False)]
[String]$Password,
[Parameter(Mandatory=$True)]
[String]$FolderUrl
)
$Url = $WebUrl + "/_api/web/GetFolderByServerRelativeUrl('" + $FolderUrl + "')"
$contextInfo = Get-SPOContextInfo $WebUrl $UserName $Password
Invoke-RestSPO Url $Url Method Post UserName $UserName Password $Password RequestDigest $contextInfo.GetContextWebInformation.FormDigestValue ETag "*" XHTTPMethod "DELETE"
}

view raw
Folders-RestSPO.ps1
hosted with ❤ by GitHub

 

Working with files

Folder resource: represents a file in a SharePoint Web site that can be a Web Part Page, an item in a document library, or a file in a folder.

Endpoint URI: http://<site url>/_api/web/getfilebyserverrelativeurl(‘/<folder name>/<file name>‘)

Supported HTTP methods:  GET  |  DELETE  |  POST  (File resource)

The following examples demonstrates how to perform basic operations with File resource including:

  • upload file into SharePoint
  • download  file from a SharePoint

 

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")
. ".\Invoke-RestSPO.ps1"
<#
.SYNOPSIS
Retieve Files in Folder
.DESCRIPTION
Read Files operation via SharePoint 2013 REST API
url: http://site url/_api/web/GetFolderByServerRelativeUrl('/Folder Name')/Files
method: GET
headers:
Authorization: "Bearer " + accessToken
accept: "application/json;odata=verbose" or "application/atom+xml"
.NOTES
Prerequisite : Invoke-RestSPO function
.EXAMPLE
$Files = Get-SPOFiles -WebUrl $WebUrl -UserName $UserName -Password $Password -FolderUrl '/Shared Documents/Folder'
#>
Function Get-SPOFiles(){
Param(
[Parameter(Mandatory=$True)]
[String]$WebUrl,
[Parameter(Mandatory=$True)]
[String]$UserName,
[Parameter(Mandatory=$False)]
[String]$Password,
[Parameter(Mandatory=$True)]
[String]$FolderUrl
)
$Url = $WebUrl + "/_api/web/GetFolderByServerRelativeUrl('" + $FolderUrl + "')/Files"
Invoke-RestSPO $Url Get $UserName $Password | % { $_.results }
}
<#
.SYNOPSIS
Delete File
.DESCRIPTION
Delete Files operation via SharePoint 2013 REST API
url: http://site url/_api/web/GetFileByServerRelativeUrl('/Folder Name/file name')
method: POST
headers:
Authorization: "Bearer " + accessToken
X-RequestDigest: form digest value
IF-MATCH: etag or "*"
X-HTTP-Method:"DELETE"
.NOTES
Prerequisite : Invoke-RestSPO function
.EXAMPLE
Delete-SPOFile -WebUrl $WebUrl -UserName $UserName -Password $Password -FileUrl '/Shared Documents/Folder/File To Delete'
#>
Function Delete-SPOFile(){
Param(
[Parameter(Mandatory=$True)]
[String]$WebUrl,
[Parameter(Mandatory=$True)]
[String]$UserName,
[Parameter(Mandatory=$False)]
[String]$Password,
[Parameter(Mandatory=$True)]
[String]$FileUrl
)
$Url = $WebUrl + "/_api/web/GetFileByServerRelativeUrl('" + $FileUrl + "')"
$contextInfo = Get-SPOContextInfo $WebUrl $UserName $Password
Invoke-RestSPO Url $Url Method Post UserName $UserName Password $Password RequestDigest $contextInfo.GetContextWebInformation.FormDigestValue ETag "*" XHTTPMethod "DELETE"
}
<#
.SYNOPSIS
Download File
.DESCRIPTION
Read File operation via SharePoint 2013 REST API
url: http://site url/_api/web/GetFileByServerRelativeUrl('/Folder Name/file name')/$value
method: GET
headers:
Authorization: "Bearer " + accessToken
.NOTES
Prerequisite : Invoke-RestSPO function
.EXAMPLE
Download-SPOFile -WebUrl $WebUrl -UserName $UserName -Password $Password -FileUrl '/Shared Documents/Folder/File To Download' -DownloadPath 'c:\downloads'
#>
Function Download-SPOFile(){
Param(
[Parameter(Mandatory=$True)]
[String]$WebUrl,
[Parameter(Mandatory=$True)]
[String]$UserName,
[Parameter(Mandatory=$True)]
[String]$Password,
[Parameter(Mandatory=$True)]
[String]$FileUrl,
[Parameter(Mandatory=$True)]
[String]$DownloadPath
)
$Url = $WebUrl + "/_api/web/GetFileByServerRelativeUrl('" + $FileUrl + "')/`$value"
$fileContent = Invoke-RestSPO Url $Url Method Get UserName $UserName Password $Password BinaryStringResponseBody $True
#Save
$fileName = [System.IO.Path]::GetFileName($FileUrl)
$downloadFilePath = [System.IO.Path]::Combine($DownloadPath,$fileName)
[System.IO.File]::WriteAllBytes($downloadFilePath,$fileContent)
}
<#
.SYNOPSIS
Upload File
.DESCRIPTION
Create File operation via SharePoint 2013 REST API
url: http://site url/_api/web/GetFileByServerRelativeUrl('/Folder Name/file name')
method: POST
headers:
Authorization: "Bearer " + accessToken
X-RequestDigest: form digest value
IF-MATCH: etag or "*"
X-HTTP-Method:"DELETE"
.NOTES
Prerequisite : Invoke-RestSPO function
.EXAMPLE
Upload-SPOFile -WebUrl $WebUrl -UserName $UserName -Password $Password -FolderUrl '/Shared Documents/Folder' -UploadFilePath 'Physical Path to File'
#>
Function Upload-SPOFile(){
Param(
[Parameter(Mandatory=$True)]
[String]$WebUrl,
[Parameter(Mandatory=$True)]
[String]$UserName,
[Parameter(Mandatory=$True)]
[String]$Password,
[Parameter(Mandatory=$True)]
[String]$FolderUrl,
[Parameter(Mandatory=$True)]
[String]$UploadFilePath
)
$FileInfo = New-Object System.IO.FileInfo($UploadFilePath)
$Url = $WebUrl + "/_api/web/GetFolderByServerRelativeUrl('" + $FolderUrl + "')/Files/add(url='" + $FileInfo.Name + "',overwrite=true)"
$FileContent = [System.IO.File]::ReadAllBytes($FileInfo.FullName)
$contextInfo = Get-SPOContextInfo $WebUrl $UserName $Password
Invoke-RestSPO Url $Url Method Post UserName $UserName Password $Password Body $FileContent RequestDigest $contextInfo.GetContextWebInformation.FormDigestValue
}

view raw
Files-RestSPO.ps1
hosted with ❤ by GitHub

Summary

To summarize, it was demonstrates how to perform basic operations with files and folders, in particular how to  download and upload files via REST. For that purpose we  utilized Invoke-RestSPO function  that is intended for sending HTTPS requests to O365/SharePoint Online REST service.

References

How to: Upload files into Office 365 via PowerShell

Overview

Being one of the most common questions “How to upload files to SharePoint Library?”, i noticed that usually folder structure is not taken into account in the provided solutions.
So i decided to fill the gap and implement another version that allows to preserve folder structure while uploading files.

Prerequisites

PowerShell script

PowerShell script demonstrates how to upload  files within a specified local directory to a Document Library within a Site in an O365 tenant.

Add-Type Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
Function Ensure-Folder()
{
Param(
[Parameter(Mandatory=$True)]
[Microsoft.SharePoint.Client.Web]$Web,
[Parameter(Mandatory=$True)]
[Microsoft.SharePoint.Client.Folder]$ParentFolder,
[Parameter(Mandatory=$True)]
[String]$FolderUrl
)
$folderNames = $FolderUrl.Trim().Split("/",[System.StringSplitOptions]::RemoveEmptyEntries)
$folderName = $folderNames[0]
Write-Host "Creating folder [$folderName] …"
$curFolder = $ParentFolder.Folders.Add($folderName)
$Web.Context.Load($curFolder)
$web.Context.ExecuteQuery()
Write-Host "Folder [$folderName] has been created succesfully. Url: $($curFolder.ServerRelativeUrl)"
if ($folderNames.Length -gt 1)
{
$curFolderUrl = [System.String]::Join("/", $folderNames, 1, $folderNames.Length 1)
EnsureFolder Web $Web ParentFolder $curFolder FolderUrl $curFolderUrl
}
}
Function Upload-File()
{
Param(
[Parameter(Mandatory=$True)]
[Microsoft.SharePoint.Client.Web]$Web,
[Parameter(Mandatory=$True)]
[String]$FolderRelativeUrl,
[Parameter(Mandatory=$True)]
[System.IO.FileInfo]$LocalFile
)
try {
$fileUrl = $FolderRelativeUrl + "/" + $LocalFile.Name
Write-Host "Uploading file [$($LocalFile.FullName)] …"
[Microsoft.SharePoint.Client.File]::SaveBinaryDirect($Web.Context, $fileUrl, $LocalFile.OpenRead(), $true)
Write-Host "File [$($LocalFile.FullName)] has been uploaded succesfully. Url: $fileUrl"
}
catch {
write-host "An error occured while uploading file [$($LocalFile.FullName)]"
}
}
function Upload-Files()
{
Param(
[Parameter(Mandatory=$True)]
[String]$Url,
[Parameter(Mandatory=$True)]
[String]$UserName,
[Parameter(Mandatory=$False)]
[String]$Password,
[Parameter(Mandatory=$True)]
[String]$TargetListTitle,
[Parameter(Mandatory=$True)]
[String]$SourceFolderPath
)
if($Password) {
$SecurePassword = $Password | ConvertTo-SecureString AsPlainText Force
}
else {
$SecurePassword = Read-Host Prompt "Enter the password" AsSecureString
}
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName,$SecurePassword)
$Context.Credentials = $Credentials
$web = $Context.Web
$Context.Load($web)
$list = $web.Lists.GetByTitle($TargetListTitle);
$Context.Load($list.RootFolder)
$Context.ExecuteQuery()
Get-ChildItem $SourceFolderPath Recurse | % {
if ($_.PSIsContainer -eq $True) {
$folderUrl = $_.FullName.Replace($SourceFolderPath,"").Replace("\","/")
if($folderUrl) {
EnsureFolder Web $web ParentFolder $list.RootFolder FolderUrl $folderUrl
}
}
else{
$folderRelativeUrl = $list.RootFolder.ServerRelativeUrl + $_.DirectoryName.Replace($SourceFolderPath,"").Replace("\","/")
UploadFile Web $web FolderRelativeUrl $folderRelativeUrl LocalFile $_
}
}
}
#Usage
$Url = "https://contoso.sharepoint.com"
$UserName = "username@contoso.onmicrosoft.com"
$Password = "password"
$TargetListTitle = "Documents" #Target Library
$SourceFolderPath = "C:\Users\user\Upload" #Source Physical Path
#Upload files
UploadFiles Url $Url UserName $UserName Password $Password TargetListTitle $TargetListTitle SourceFolderPath $SourceFolderPath

view raw
SPOUpload-Files.ps1
hosted with ❤ by GitHub