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 "http://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

Information Technology Professional with Two decades of SharePoint Experience.

34 thoughts on “Bulk Upload Files to SharePoint using PowerShell

  • October 9, 2020 at 11:07 AM

    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
  • April 8, 2019 at 4:33 AM

    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
    • April 9, 2019 at 4:52 AM

      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
  • May 2, 2018 at 8:05 PM

    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
  • March 20, 2018 at 1:57 PM

    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
    • March 22, 2018 at 6:23 AM

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

      Reply
  • February 14, 2018 at 6:11 PM

    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
  • April 27, 2017 at 2:24 AM

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

    Thanks.
    Great Job.

    Reply
  • March 23, 2017 at 1:04 PM

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

    #Configuration Variables
    $SiteURL=”http://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
  • March 23, 2017 at 1:01 PM

    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
    • February 25, 2020 at 8:58 AM

      have you resolve this isssue?

      Reply
  • May 4, 2016 at 12:01 AM

    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
  • May 3, 2016 at 3:05 PM

    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
  • October 26, 2015 at 9:21 AM

    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
    • April 20, 2016 at 3:45 PM

      Hi There,

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

      Reply
  • September 4, 2015 at 10:41 AM

    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
  • May 5, 2015 at 9:39 AM

    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
  • May 5, 2015 at 8:57 AM

    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
    • September 4, 2015 at 11:50 AM

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

      Reply
  • October 8, 2013 at 8:08 AM

    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
  • September 18, 2013 at 2:49 AM

    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 “http://sp2010/sites/training” “Shared Documents” C:Te
    st”
    >>

    Many thanks

    Warm Regards,
    Sathya

    Reply
    • September 18, 2013 at 8:46 AM

      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
  • May 10, 2013 at 7:33 AM

    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
    • May 10, 2013 at 12:42 PM

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

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

      Reply
  • May 1, 2013 at 10:10 PM

    This script worked great!!

    Thanks much!!!

    Reply
  • March 14, 2013 at 8:24 AM

    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
    • March 14, 2013 at 1:33 PM

      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
  • February 21, 2013 at 9:47 PM

    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
    • February 24, 2013 at 12:15 PM

      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
  • January 10, 2013 at 5:45 PM

    Thank you so much!

    Reply
  • October 2, 2012 at 9:48 AM

    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