Skip Ribbon Commands
Skip to main content

Quick Launch

Todd Klindt's home page > Todd Klindt's SharePoint Admin Blog > Posts > How to Upload Files to SharePoint 2013 with PowerShell
April 06
How to Upload Files to SharePoint 2013 with PowerShell

Every once in a while I get to add a little flair to a project I’m working on. Recently I was working on a couple of projects that intersected, sort of. First, I’ve been writing some scripts to automate some processes we have. These scripts do some pretty good logging to the file system in case there are problems. The average person would have stopped there, but not me. I wanted to take it a step farther. I added a bit where the script uploads the log files to a SharePoint document library. This makes them easier to get to for support personnel, and it makes it easier to search through them for specific issues. SharePoint saves the day again.

The other project I’ve working on is making my Netcast production more automated. Part of that process was using PowerShell to edit the MP3 tags on my Netcast files. While I was pretty proud of that, the previous project made me  realize I could take things one step further and have that same script go ahead and upload the MP3 file when it’s finished. One less thing for me to put off when I’m procrastinating. Hooray efficiency. Plus I get braggin’ rights. Score!

On the surface, these two things sound like they’re the same thing, uploading files to SharePoint. Once you get into the weeds though, they’re actually different. In the first case I’m uploading a file to a local SharePoint server. This is pretty simple. While PowerShell doesn’t have a Upload-SPFile cmdlet we’re pretty close to it. Easy peasy. In the second case I’m uploading the files to a remote SharePoint server. Since it’s a remote server we can’t just add the SharePoint PowerShell module and use the same techniques as we would with a local server. Subtle differences, but important differences. As I was searching for “Upload files to SharePoint with PowerShell” I found most articles covered one or the other. Which is very handy if your situation matches the article’s. Not so handy if they don’t. So I wrote this blog post to cover both scenarios.

Scenario 1: Uploading Files to SharePoint on the SharePoint Server

Here’s a quick example of how to upload a document on a SharePoint server using the SharePoint PowerShell module which uses the SharePoint Object Model.

# Set the variables
$WebURL = “http://portal.contoso.com/sites/stuff”
$DocLibName = “Docs”
$FilePath = “C:\Docs\stuff\Secret Sauce.docx”

# Get a variable that points to the folder
$Web = Get-SPWeb $WebURL
$List = $Web.GetFolder($DocLibName)
$Files = $List.Files

# Get just the name of the file from the whole path
$FileName = $FilePath.Substring($FilePath.LastIndexOf("\")+1)

# Load the file into a variable
$File= Get-ChildItem $FilePath

# Upload it to SharePoint
$Files.Add($DocLibName +"/" + $FileName,$File.OpenRead(),$false)
$web.Dispose()

In the case we use the Add member of the SPFileCollection class. It has a few overloads, so check them out, there might be one that better fits what you’re trying to do.

Scenario 2: Uploading Files to SharePoint from a Remote Machine

Since we can’t use the object model to upload files remotely we have to go about it a different way. I use the WebClient object, though there might be other ways. Here’s an example:

# Set the variables
$destination = "http://portal.contoso.com/sites/stuff/Docs”
$File = get-childitem “C:\Docs\stuff\Secret Sauce.docx”

# Since we’re doing this remotely, we need to authenticate
$securePasssword = ConvertTo-SecureString "pass@word1" -AsPlainText -Force
$credentials = New-Object System.Management.Automation.PSCredential ("contoso\johnsmith", $securePasssword)

# Upload the file
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = $credentials
$webclient.UploadFile($destination + "/" + $File.Name, "PUT", $File.FullName)

Like the SPFileCollection class’ Add member, the UploadFile member of the WebClient class has a few overloads to consider. Check them out so you know what your options are.

PowerShell is cool. SharePoint is cool. Uploading files is cool. It just makes sense to use PowerShell to upload files to SharePoint. Hopefully this blog post covers all the scenarios you might encounter.

tk

ShortURL: http://www.toddklindt.com/PoshUploadFiles

Edit 4/8/2014 – 1,000 apologies. The code in Scenario 2 didn’t work. I should have checked it better. It’s all good now.

Comments

Re: How to Upload Files to SharePoint 2013 with PowerShell

# Get just the name of the file from the whole path
$FileName = $FilePath.Substring($FilePath.LastIndexOf("\")+1)

Split-Path $FilePath -Leaf
is more readable. Keep your code clean.

$securePasssword = ConvertTo-SecureString "pass@word1" -AsPlainText -Force
$credentials = New-Object System.Management.Automation.PSCredential ("contoso\johnsmith", $securePasssword)

with powershell v3 and higher you can use Invoke-WebRequest, which supports the "-UseDefaultCredentials" parameter. It will use the currently logged in user credentials, so if you're on a domain joined machine in the same domain as your sharepoint - that's the easiest way to go.

--Piotr Siódmak
 on 4/7/2014 4:37 AM

Re: How to Upload Files to SharePoint 2013 with PowerShell

Hi Piotr,
Thanks for your comments. They're both really good. You're right, Split-Path would be better than the mess I have. I will for sure change my internal script. I may or may not change this blog post. We'll see. I don't like changing blog posts after I've published them. So if I don't change this blog post it's not commentary on your suggestion. :)

I did not use Invoke-WebRequest and defaultcredentials because in my case my workstation (where I'm uploading the file from) and my SharePoint server are not in the same domain. It is a good suggestion for machines that are all in the same domain though.

Thanks for the comment, Piotr. I appreciate it.

tk
Todd O. KlindtNo presence information on 4/7/2014 8:29 AM

Re: How to Upload Files to SharePoint 2013 with PowerShell

Hi Todd,

on my systems $FilePath has no properties 'Name' or 'FullName'. Therefore your last line of the web upload script does not work for me.

So I simply Piotr's suggestion with your script and the changed the last line to the following two.

$FileName = $FilePath.Substring($FilePath.LastIndexOf("\")+1)
$webclient.UploadFile($destination + "/" + $FileName, "PUT", $FilePath)

This way it is working for me totally fine.

--Andre
 on 4/8/2014 2:44 AM

Re: How to Upload Files to SharePoint 2013 with PowerShell

Yup, the script was broken. I fixed it. I even tested it this time.

tk
Todd O. KlindtNo presence information on 4/9/2014 10:43 PM

check in file at the same time

Hi,
Script works fine, however on SP2013 file is not checked in after it is uploaded, is there a way to automate check in as well?
 on 8/25/2014 2:42 AM

403 error with scenario 2 and o365

I'm getting a 403 forbidden error when using the 2nd option to upload files to an o365 tenant.

I'm sure my creds are correct.

Do these methods work for o365?
 on 11/25/2014 9:39 PM

Check In

Could someone can help me with the check in after upload the file.
 on 12/1/2014 2:09 PM

Nice

Script worked for me.
Thanks a lot.
 on 2/9/2015 7:01 AM

Re: Nice

Glad it helped. :)

tk
Todd O. KlindtNo presence information on 2/13/2015 8:54 AM

Invoke-WebRequest alternative

Invoke-WebRequest issues

Thanks for the article, I've started with it.

Piotr noted that Invoke-WebRequest would be the simplest way and indeed, all you need to upload a file is:

Invoke-WebRequest -Uri "http://server/web/library/file.ext" -InFile "C:\Somewhere\file.ext" -Method PUT -UseDefaultCredentials

The only problem I've encountered that InFile requests write access to the local file being uploaded, which is absurd.
The problem is real when you upload files from a Visual Studio solution with source control - the checked-in files are read-only and, consequently, you cannot upload them.
The workaround is to read the file separately w/o requesting write access:
$content = [System.IO.File]::ReadAllBytes("C:\Somewhere\file.ext")
Invoke-WebRequest -Uri "http://server/web/librafy/file.ext" -Body $content -Method PUT -UseDefaultCredentials

And, for those who prefer to stick to WebClient, you can use the caller credentials just by:
$webclient.UseDefaultCredentials = $true

Michał Kołodziejczyk
 on 2/27/2015 8:03 AM
1 - 10Next

Add Comment

Items on this list require content approval. Your submission will not appear in public views until approved by someone with proper rights. More information on content approval.

Title


Body *


Today's date *

Select a date from the calendar.
Please enter today's date so I know you are a real person

Twitter


Want a message when I reply to your comment? Put your Twitter handle here.

Attachments

 

 Please Support my Sponsors