Bulk Upload Files to SharePoint using PowerShell

Requirement: Upload multiple files from a local folder to SharePoint document library along with their Metadata.

Bulk upload can be done via the SharePoint web interface by selecting multiple file upload, however setting metadata may be an issue, when it comes to a large number of documents.

PowerShell to Bulk Upload Files to SharePoint Library:

To bulk upload all files from a given folder, use this PowerShell script:

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
 
#Function to Upload File
Function Upload-AllFilesFromDir($WebURL, $DocLibName, $FolderPath)
{
    #Get the Web and List to upload the file
    $web = Get-SPWeb $WebURL
      
    #Get the Target Document Library to upload
    $List = $Web.GetFolder($DocLibName)
 
    #Get the Files from Local Folder
    $Files = Get-ChildItem $FolderPath #You can filter files by: -filter “*.pdf” 

    #upload the files
    Foreach ($File in $Files)
    {
        #Get the Contents of the file to FileStream 
        $stream = (Get-Item $file.FullName).OpenRead()
    
        # Set Metadata Hashtable For the file - OPTIONAL
        $Metadata = @{"Country" = "United States"; "Domain" = "Sales"}
    
        #upload the file              
        $uploaded = $List.Files.Add($File.Name, $stream, $Metadata, $TRUE)
    
        #dispose FileStream Object
        $stream.Dispose()
    }
}
  
#call the upload function
Upload-AllFilesFromDir "https://SharePoint.crescent.com/sites/sales/" "Shared Documents" "c:\Documents\"

How about importing files, folders, and sub-folders from a network file share (or local drive) to SharePoint? How to Import Network File Share to SharePoint using PowerShell?

Upload Files from CSV and apply Metadata in Bulk: 
Here is my CSV file with a list of file names and metadata.

Bulk Upload Files to SharePoint using PowerShell

PowerShell to upload and apply metadata in bulk:

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue 

#Configuration Variables
$SiteURL="https://sharepoint.crescent.com/sites/sales/"
$LibraryName="Team Docs"
$FilesPath="d:\FilesToUpload\"
$CSVFilePath="d:\UploadData.csv"

#Get the Web
$Web = Get-SPWeb $SiteURL
#Get the Target Document Library to upload
$Library = $Web.GetFolder($LibraryName)

#Get CSV file contents
$CSVData = Import-CSV -path $CSVFilePath

#Iterate through each Row in the CSV
Foreach ($Row in $CSVData)
{
    write-host "Uploading File:"$Row.FileName

    #Get the File from local disk 
    $SourcePath= Join-Path $FilesPath -ChildPath $Row.FileName
    $SourceFile = (Get-ChildItem $SourcePath).OpenRead()

    #Set Metadata Hashtable For the file
    $Metadata = @{"Country" = $Row.Country; "Department" = $Row.Department}

    #upload the file              
    $uploaded = $Library.Files.Add($Row.FileName, $SourceFile, $Metadata, $TRUE)
}

To upload multiple files and folders to SharePoint Online using PowerShell, use: Bulk Upload files to SharePoint Online using PowerShell

Salaudeen Rajack

Salaudeen Rajack - Information Technology Expert with Two-decades of hands-on experience, specializing in SharePoint, PowerShell, Microsoft 365, and related products. He has held various positions including SharePoint Architect, Administrator, Developer and consultant, has helped many organizations to implement and optimize SharePoint solutions. Known for his deep technical expertise, He's passionate about sharing the knowledge and insights to help others, through the real-world articles!

36 thoughts on “Bulk Upload Files to SharePoint using PowerShell

  • Hello i try this and i have an error “Add-PSSnapin : No snap-ins have been registered for Windows PowerShell version 5.” cant use the $web = Get-SPWeb $WebURL

    Reply
    • Well, You have to run this script from any of the SharePoint Server on your On-premises farm! If yes, Make sure you are running 64 bit version of PowerShell.

      Reply
  • Hi,

    First, I’m not that familiar with powershell. So, it could be a silly question.

    I tested you procedure and I have something strange.

    The procedure reads well the different rows but doesn’t recognize the sharepoint fields.

    See exemple below. Can somebody helps me ?

    CSVData : @{Sujet;Year;Doc1=Test1;2015;60.docx} @{Sujet;Year;Doc1=Test2;2016;60}

    Row : @{Sujet;Year;Doc1=Test1;2015;60.docx}

    Sujet :

    Year :

    Uploading File :

    Reply
  • Another great post!

    Is it possible to all documents to be uploaded into multiple SharePoint Sites using this script. I don’t want to create and run separate script for each different SharePoint Site. FYI – All Sites are within the same site collection.

    Thanks,
    Uttkarsh

    Reply
    • I guess, I was not very descriptive in explaining my request apology for that. The script should almost loop through each site and upload documents with update metadata from the same Upload.csv

      Is it possible for you to expand the existing script to include the below capabilities:

      1. Allow multiple sites to be included
      2. Allow SitesNames [URL] data to be retrieved from Upload.CSV file similar to FileNames and Metadata.

      Please let me know if you any questions.

      Thanks,
      Uttkarsh

      Reply
  • Hello …The script is uploading the document but it is just overwriting th efirst one so ultimately i’m left with only one document in the library. any help?

    Reply
  • Hi Guys,

    I have a Site URL where i want to upload a file on daily basis.
    Will this script work, as we looking to automate using task scheduler where the file should uploaded automatically.

    Reply
    • Sure! Just replace the parameters such as site to upload, file location and place this script in windows task scheduler.

      Reply
  • Hi I am getting this error.

    Can you help, please

    Get-SPWeb : El término ‘Get-SPWeb’ no se reconoce como nombre de un cmdlet, función, archivo de script o programa ejecutable. Compruebe si escribió
    correctamente el nombre o, si incluyó una ruta de acceso, compruebe que dicha ruta es correcta e inténtelo de nuevo.

    Reply
  • Hi. I can used this script for sharepoint foundation (WEB).

    Thanks.
    Great Job.

    Reply
  • Here is my Script
    Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

    #Configuration Variables
    $SiteURL=”https://SP2013Dev/”
    $LibraryName=”Team Docs”
    $FilesPath=”c:FilesToUpload”
    $CSVFilePath=”c:Uploads.csv”

    #Get the Web
    $Web = Get-SPWeb $SiteURL

    #Get the Target Document Library to upload
    $Library = $Web.GetFolder($LibraryName)

    #Get CSV file contents
    $CSVData = Import-CSV -path $CSVFilePath

    #Iterate through each Row in the CSV
    Foreach ($Row in $CSVData)
    {

    write-host “Uploading File:”$Row.FileName

    #Get the File from local disk
    $SourcePath= Join-Path $FilesPath -ChildPath $Row.FileName

    $SourceFile = (Get-ChildItem $SourcePath).OpenRead()

    Error
    Uploading File:
    Cannot convert argument “file”, with value: “System.Object[]”, for “Add” to type “System.Byte[]”: “Cannot convert the “System.IO.FileStream” value of type
    “System.IO.FileStream” to type “System.Byte”.”
    At C:up.ps1:33 char:5
    + $uploaded = $Library.Files.Add($Row.FileName, $SourceFile, $Metadata, $TRUE)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

    #Set Metadata Hashtable For the file
    $Metadata = @{“Country” = $Row.Country; “Depart” = $Row.Depart}

    #upload the file
    $uploaded = $Library.Files.Add($Row.FileName, $SourceFile, $Metadata, $TRUE)

    }

    Reply
  • Hi I am getting this error when uploading from csv file
    Uploading File:
    Cannot convert argument “file”, with value: “System.Object[]”, for “Add” to type “System.Byte[]”: “Cannot convert the “System.IO.FileStream” value of type
    “System.IO.FileStream” to type “System.Byte”.”
    At C:up.ps1:33 char:5
    + $uploaded = $Library.Files.Add($Row.FileName, $SourceFile, $Metadata, $TRUE)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

    Reply
    • have you resolve this isssue?

      Reply
  • Hi,

    Thanks for the script. Does it delete the files and CVS file from the source folder once upload to Sharepoint is confirmed?
    Thanks.

    Reply
  • Hi Salaudeen,

    I’ve been attempting to use your script for uploading metadata and files to sharepoint but I get a ‘Parse errors detected’ on the line where I’m trying to configure $SiteUrl.

    I think it’s due to the number of quotes, I’ve checked it against your own script but haven’t had any luck. Also I can’t comment the line of code since it includes html and this comment box doesn’t like that.

    Reply
  • Hi Salaudeen,
    we have thousands of documents to upload with individual Metadata. As Nayan and Ankit already asked, it would be great to have a script reading those filenames and the subsequent metadata from an CSV or similar file.

    Your great experience is highly appreciated.

    Regards Wolfgang

    Reply
    • Hi There,

      Added the Script to get Files and Metadata from CSV file and do bulk upload!

      Reply
  • Hi @salaudeen,

    i have 1000+ documents with distinct meta data, ur powersehell will update same metadata with all the documents. I have a excel carrying columns like
    FileName … metadata1 …metadata2 … metadata3.

    Can we map the file name in directory and excel to update metadata. ?

    plz Help !!!

    Reply
  • Hi Salaudeen,
    I am trying to write a similar script. In my case I have an XLS file with respective metadata for all the files. For comparison, the name of file is same as the 1st column in XLS file.
    I am trying to find an efficient way to compare the values and store the related metadata somewhere. And use it for tagging the item uploaded.
    Thanks for any suggestions.

    Reply
  • Hi Salaudeen,
    I am trying to write a similar script. In my case I have an XLS file with respective metadata for all the files. For comparison, the name of file is same as the 1st column in XLS file.
    I am trying to find an efficient way to compare the values and store the related metadata somewhere. And use it for tagging the item uploaded.
    Thanks for any suggestions.

    Reply
    • hey Nayan, if u have found solution for it, plz share. I have the same need.

      Reply
  • Hi Salaudeen,
    Am looking for a similar script the only difference is that am trying to Importing/uploading files from file share to SP 2010 Doc Lib using a CSV which has all the metadata. Please advice. Thanks in advance.

    Reply
  • Dear Salaudeen Rajack,

    Many thanks for sharing such a wonderful blog.

    I am new to Power Shell. When I type it in sharepoint console. I am getting the following details. Can you help me in this regard.

    PS C:UsersAdministrator> Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAc
    tion SilentlyContinue
    PS C:UsersAdministrator> [System.Reflection.Assembly]::LoadWithPartialName(“Mi
    crosoft.SharePoint”)>$null
    PS C:UsersAdministrator> function UploadAllFilesFromDir($WebURL, $DocLibName,
    $FolderPath)
    >> {
    >> $site = New-Object Microsoft.SharePoint.SPSite($WebURL)
    >> $web=$site.OpenWeb()
    >> $List=$web.GetFolder($DocLibName)
    >> $Files = Get-ChildItem $FolderPath
    >> foreach ($File in $Files)
    >> {
    >> $stream = (Get-Item $file.FullName).OpenRead()
    >> $uploaded = $List.Files.Add($File.Name,$stream, $TRUE)
    >> $stream.Dispose()
    >> }
    >> $site.Dispose()
    >> UploadAllFilesFromDir “https://sp2010/sites/training” “Shared Documents” C:Te
    st”
    >>

    Many thanks

    Warm Regards,
    Sathya

    Reply
    • Sathya, Just save the script in a file with .ps1 extension. Now you can run the script either by right clicking and choosing “Run with PowerShell” or from PowerShell Prompt!

      Reply
  • The code works perfectly fine and pretty fast. Just one question though was, I was trying to associate multiple values with multi-value choice column as

    $Metadata = @{“Country” = “United States; India”;}

    but this is not working. Any help would be appreciated.

    Reply
    • Ok. I found a way. We just need to use

      $Metadata = @{“Country” = “;#United States;#India;#”;}

      Reply
  • This script worked great!!

    Thanks much!!!

    Reply
  • Hi,
    I carried out the above and realised it is not working.
    Step for step all are the same with yours. I even did the following
    -added some line of codes to check if the files were being read from the destination and that was a YES.
    -added another line to fine out if the files were being written to the destination just after the code snippet below
    #upload the file
    $uploaded = $List.Files.Add($File.Name, $stream,$Metadata, $TRUE)
    “$File written to destination” | Out-File $ReportFile -Append
    the result came out that the files were written to the destination successfully.

    However when I check the Document library via the GUI, I come up with banks. No file.
    ANy help or ideas?

    Cheers
    Rajiv

    Reply
    • Rajiv,

      I’d check the total item count in the library or log in as the farm admin and check the library again. I had this problem before and it was because the documents needed to be checked in.

      Hope it helps!

      Reply
  • Thank you so much for the post this is very helpful!

    One question, does -filter exclude everything that’s a pdf in this scenario? what if i want it to only get the files that have a pdf file extension?

    Reply
    • Hi Mechachai, -Filter will get you only the filetypes specified. E.g. Get-ChildItem -filter “*.pdf” will retrieve all PDF Files.

      If you want to get all files except PDF, You can use “-Exclude” switch. E.g. Get-ChildItem -exclude “*.pdf”

      Reply
  • Thank you so much!

    Reply
  • I have read ur blogs on SharePoint in past, you are amazing to gain some knowledge to SharePoint. good knowledge to SharePoint and have discussed the things in details to which one can easily understand the things.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *