Last Update: Sep 04, 2024 | Published: Apr 19, 2017
Managing user content inside of SharePoint Online is the least favorite work of every administrator I know. While moving one file from Document Library A to Document Library B is not exactly hard, using a mouse to move hundreds of files based on a metadata value is just plain terrible. When that type of job comes up, the only good solution is to use a third-party tool. Not anymore. Thanks to the might of PowerShell and the Patterns and Practices (PNP) PowerShell, you can now write your own script to do the work for you. You can be the office hero.
To do this magic without a third-party tool, you need to install the PNP PowerShell. If you are not familiar with these awesome and free tools, then check out my previous article. It will give you some context and walk you through installing PNP. Watching this should only take you 5 minutes. After that, you just need access to the content.
With the official SharePoint Online Management Shell, you have to be a global administrator in Office 365 to make things work. You connect to the tenant and then work down from there. With the PNP PowerShell, you connect at the site collection level and all of the cmdlets are just making web API calls. If you have permissions to copy a file in the browser, you have access with the PNP PowerShell. Pretty cool.
In this example, we will look at ways to move, copy, and remove files from SharePoint Online document libraries. If you are more of the watch Shane do it type instead of the reading about it type, you can watch Move SharePoint Online Files with PowerShell.
This will get you connected but it is a pain in the backside. For better password management options, check out Managing Usernames and Passwords with PowerShell for SharePoint Online. This is how the cool kids are doing it.
No, I am not going to write you instructions for creating two document libraries using your browser. But, I need you to go to the site collection you connected to with your browser and create two document libraries. OldHome and NewHome should be the names. Upload three files to OldHome. Once you are done, we will move the files from OldHome to NewHome. I named my three files Document 1.docx, Document 2.docx, and Document 3.docx because I am very creative. It is important to remember that the files have to have words in them. SharePoint does not like blank files.
There are countless file properties you now have access to with PowerShell but we do not have countless time together. Let’s look at a few key things you need to know for this exercise. After we are done, you can go exploring on your own. Tweet me the fun things you find.
Time to run some PowerShell:
Get-PnPListItem OldHome
This will show you the files you uploaded. It is normal for the Title to be blank. You can manually add one. You will need to know a valid ID for the next step. If you are following along, 1 will be valid. If you are using existing document libraries, then you may not have a 1. When you upload your first document, it is id 1. If you delete that file, then upload it again, it will be assigned id 2. SharePoint does not reuse IDs. It is possible that you will not have an id 1.
Now assign one of the documents to a variable and look at the properties:
$cow = get-pnplistitem -id 1 -List OldHome $cow.FieldValues
So much fun there. You can see that they hide the actual filename in FileLeafRef. FileRef contains the full path to the file. This is all information you will need to automate a solution.
This is not very useful. It is worth noting that the Move cmdlet is available. We do not use this in the script because we are going to introduce some fun with metadata in the next article. It is easier to copy the file, then the metadata, and then delete the original. But that is for another day.
$Source = $cow.FieldValues.FileRef $TargetLib = "/NewHome/" $Target = $TargetLib + $cow.FieldValues.FileLeafRef Move-PnPFile -ServerRelativeUrl $Source -TargetUrl $Target -Force
Breaking that down should be pretty easy but here are the details:
This is the same as a move but uses different cmdlets. We covered the reason for this method earlier, which is that we can do even cooler things later. If you want to replace the Copy and Remove cmdlets with Move, have at it. It will not hurt my feelings.
$Items = Get-PNPListItem -List "OldHome" $TargetLib = "/NewHome/" foreach ($Item in $Items) { $source = $item.FieldValues.FileRef $target = $TargetLib + $item.FieldValues.FileLeafRef Copy-PnPFile -SourceUrl $source -TargetUrl $target -Force -ErrorAction Stop Remove-PNPFile -ServerRelativeUrl $source -Force }
Here are a couple of notes from the above PowerShell. Most of it has been covered already:
Awesome! All of your files have been moved from one document library to the other.
While this example is not exactly exciting, it does provide a great foundation. From here, you could build out the script to only move files based on a specific metadata value or copy the files and the metadata. This would allow you to retain the modify date and user. The sky is the limit and that is the beauty of PowerShell.
The idea for this script actually came from a customer request. Michael, from New York, worked with Bold Zebras to sort a very large document library into many smaller document libraries based on some of the metadata. With his script, we ended up with Try Catch blocks, some CAML, and a bunch of other chaos. I decided not to overrun this article with all of that. If you ever need help with scripts like this, we are always happy to help.
Shane