I'm a new learner to Powershell and a bit new to SharePoint as well.

I'm learning powershell to create a script that uploads files to a sub-site library inside SharePoint. I managed to get it working and uploading .doc files to my library, however I also want fill in any metadata specified in additional columns with the file at the same time. I'm not using the SharePoint snap-in and instead using the webclient functions. Here is the simple powershell script

# create the Variable Path and Pass the source folder path

$path = "THE FILE"

# create the Variable destination and pass the URL of the SharePoint List
$destination = "SharePoint SubSite"

# Store the current user default credentials in the Variable Credentials
$credentials = [System.Net.CredentialCache]::DefaultCredentials;

# Create the object of the Webclient 

$webclient = New-Object System.Net.WebClient;

$webclient.Credentials = $credentials;

$webclient.UploadFile($destination + “/” + "Filename", “PUT”, TheFile)

This code works but there is a couple things I don't understand.

  1. Why do I have to add + "/" and what does PUT DO? Why doesn't this ($destination, $filename) just work?

  2. The file uploads perfectly with the + / syntax, however I don't know how to use the webclient functions to pass in metadata to specified columns in the document library when uploading the file to the library.

Much Thanks.


Put The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server.

"/" is used to create the complete URL for the File location. i.e.library path is http://portal.contoso.com/sites/stuff/Docs then file location will be http://portal.contoso.com/sites/stuff/Docs**/**filename

I am not sure about the updating the properties of file using the WebClient, may be somebody else comment on this.

  • Thanks for the explanation. I'm new to Powershell I just didn't know about nit picky things like that. I just try to read the function and see what parameters it takes. I hope I can figure out how to update columns in the library when uploading files through the webclient. I thought maybe it is parsed through the parameters in the string. Guess not. Sep 22 '14 at 13:44


If you're new to PowerShell and want to upload documents to SharePoint, I can't recommend the PnP PowerShell cmdlets enough. It was built by top members of the SharePoint Development Community to simplify interacting with SharePoint using PowerShell.

The instructions to install the cmdlets are on the PnP PowerShell home page, but you would use a simple command like this to install the Office 365/SharePoint Online version:

Install-Module SharePointPnPPowerShellOnline

Once installed, you need to connect your PowerShell session using this command (in this example, using Office 365/SharePoint Online):

Connect-PnPOnline -Url https://yoursite.sharepoint.com -UseWebLogin

Once connected, you can upload files and set their metadata in one command:

Add-PnPFile -FileName sample.docx -Folder "Documents" -Values @{Modified="1/1/2016"; Created="1/1/2017"; Editor=23}

Check out the Add-PnPFile cmdlet reference page for more information.

The PnP cmdlets are not necessary, but they make things easier. If you'd prefer using PowerShell directly, let me know and I'll gladly amend my answer.

I hope this helps.


You can use the below PowerShell script to file upload in SharePoint online:

#Load SharePoint CSOM Assemblies
#Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
#Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

$fileName = "File_Uploading_Report"
#'yyyyMMddhhmm   yyyyMMdd
$enddate = (Get-Date).tostring("yyyyMMddhhmmss")
#$filename =  $enddate + '_VMReport.doc'  
$logFileName = $fileName +"_"+ $enddate+"_Log.txt"   
$invocation = (Get-Variable MyInvocation).Value  
$directoryPath = Split-Path $invocation.MyCommand.Path  

if(!(Test-Path -path $directoryPathForLog))  
            New-Item -ItemType directory -Path $directoryPathForLog
            #Write-Host "Please Provide Proper Log Path" -ForegroundColor Red   

#$logPath = $directoryPath + "\" + $logFileName 

$logPath = $directoryPathForLog + "\" + $logFileName 

$isLogFileCreated = $False 

#DLL location

$directoryPathForDLL=$directoryPath+"\"+"Dependency Files"
if(!(Test-Path -path $directoryPathForDLL))  
            New-Item -ItemType directory -Path $directoryPathForDLL
            #Write-Host "Please Provide Proper Log Path" -ForegroundColor Red   

#DLL location


Add-Type -Path $clientDLL
Add-Type -Path $clientDLLRuntime

#Files to upload location

$directoryPathForFileToUploadLocation=$directoryPath+"\"+"Files To Upload"
if(!(Test-Path -path $directoryPathForFileToUploadLocation))  
            New-Item -ItemType directory -Path $directoryPathForFileToUploadLocation
            #Write-Host "Please Provide Proper Log Path" -ForegroundColor Red   

#Files to upload location ends here.

function Write-Log([string]$logMsg)  
        Write-Host "Creating Log File..."   
        if(!(Test-Path -path $directoryPath))  
            Write-Host "Please Provide Proper Log Path" -ForegroundColor Red   
            $script:isLogFileCreated = $True   
            Write-Host "Log File ($logFileName) Created..."   
            [string]$logMessage = [System.String]::Format("[$(Get-Date)] - {0}", $logMsg)   
            Add-Content -Path $logPath -Value $logMessage   
        [string]$logMessage = [System.String]::Format("[$(Get-Date)] - {0}", $logMsg)   
        Add-Content -Path $logPath -Value $logMessage   

#The below function will upload the file from local directory to SharePoint Online library.

Function FileUploadToSPOnlineLibrary()
        [Parameter(Mandatory=$true)] [string] $SPOSiteURL,
        [Parameter(Mandatory=$true)] [string] $SourceFilePath,
        [Parameter(Mandatory=$true)] [string] $File,
        [Parameter(Mandatory=$true)] [string] $TargetLibrary,
        [Parameter(Mandatory=$true)] [string] $UserName,
        [Parameter(Mandatory=$true)] [string] $Password


        $securePassword= $Password | ConvertTo-SecureString -AsPlainText -Force  
        #Setup the Context
        $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SPOSiteURL)
        $ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $securePassword)

        $list = $ctx.Web.Lists.GetByTitle($TargetLibrary)


        $fileOpenStream = New-Object IO.FileStream($SourceFilePath, [System.IO.FileMode]::Open)  
        $fileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation  
        $fileCreationInfo.Overwrite = $true  
        $fileCreationInfo.ContentStream = $fileOpenStream  
        $fileCreationInfo.URL = $File  
        $uploadFileInfo = $list.RootFolder.Files.Add($FileCreationInfo)  

        Write-host -f Green "File '$SourceFilePath' has been uploaded to '$tarGetFilePath' successfully!"

            $ErrorMessage = $_.Exception.Message +"in uploading File!: " +$tarGetFilePath
            Write-Host $ErrorMessage -BackgroundColor Red
            Write-Log $ErrorMessage 


$userName = "YourSPOAccount@YourTenantDomain.com"
$password = "YourPassWord"
$securePassword= $password | ConvertTo-SecureString -AsPlainText -Force

#Variables ends here.

$filesCollectionInSourceDirectory=Get-ChildItem $filesFolderLoaction -File   


    #Extract the each file item from the folder.
    ForEach($oneFile in $filesCollectionInSourceDirectory)


                FileUploadToSPOnlineLibrary -SPOSiteURL $siteURL -SourceFilePath $oneFile.FullName -File $oneFile -TargetLibrary $listName -UserName $UserName -Password $Password

                $fileUploadingMessage=$uploadItemCount.ToString()+": "+$oneFile.Name; 
                Write-Host $fileUploadingMessage -BackgroundColor DarkGreen
                Write-Log $fileUploadingMessage


            $ErrorMessage = $_.Exception.Message +"in: " +$oneFile.Name
            Write-Host $ErrorMessage -BackgroundColor Red
            Write-Log $ErrorMessage 


    Write-Host "========================================================================"
    Write-Host "Total number of files uploaded: " $filesCollectionInSourceDirectory.Count 
    Write-Host "========================================================================"

For the execution of the details about the above script, please refer the below article:

SharePoint Online Automation – O365 – Upload files to document library using PowerShell CSOM

For updating the metadata column, you can use the below script:

#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

$UserName = "yourusername@globalsharepoint.onmicrosoft.com"
$Password = "ThisIsTestPassword"
$SecurePassword= $Password | ConvertTo-SecureString -AsPlainText -Force
$BatchSize =1000

#Setup the Context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)

#Get the List
$List = $Ctx.Web.Lists.GetByTitle($ListName)
$emptyString = ""
#Define CAML Query to get Files from the list in batches
$Query = New-Object Microsoft.SharePoint.Client.CamlQuery
$Query.ViewXml = "@

$count =0

#Get List Items in Batches

    $ListItems = $List.GetItems($Query)

    #Update Postion of the ListItemCollectionPosition
    $Query.ListItemCollectionPosition = $ListItems.ListItemCollectionPosition

    If ($ListItems.Count -eq 0) { Break }

    #Update List Item
    ForEach($Item in $ListItems)
        #Update List Item Title as File Name


        If($documentStatus -eq "Approved")


            #Get the List Item with all metadata fields of the File
            #$ListItem = $file.ListItemAllFields



    Write-Host "============================================================="
    Write-Host $count
    Write-Host "============================================================="

}While ($Query.ListItemCollectionPosition -ne $null)

Source Article:

SharePoint Online Automation – O365 – Update document library metadata using PowerShell CSOM

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.