Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use PowerShell to download files from SharePoint?

I've used the following sites to help me get this far and to troubleshoot.

  1. Download file from SharePoint
  2. How to download newest file from SharePoint using PowerShell
  3. Mike Smith's Tech Training Notes SharePoint, PowerShell and .Net!
  4. Upload file to a SharePoint doc library via PowerShell
  5. Download latest file from SharePoint Document Library
  6. How to iterate each folders in each of the SharePoint websites using PowerShell
  7. PowerShell's Get-ChildItem on SharePoint Library

I am trying to download random files from SharePoint folder, and I have it working for when I actually know the file name and extension.

Working code with name and extension:

$SharePoint = "https://Share.MyCompany.com/MyCustomer/WorkLoad.docx"
$Path = "$ScriptPath\$($CustomerName)_WorkLoad.docx"

#Get User Information
$user = Read-Host "Enter your username"
$username = "$user@MyCompany"
$password = Read-Host "Enter your password" -AsSecureString

#Download Files
$WebClient = New-Object System.Net.WebClient
$WebClient.Credentials = New-Object System.Net.Networkcredential($UserName, $Password)
$WebClient.DownloadFile($SharePoint, $Path)

However, I don't seem to be able to figure out how to do it with multiple files of unknown names or extensions.

I have tried mapping a drive, only to end up with "drive mapping failed" & "The network path was not found." errors:

$SharePoint  = Read-Host 'Enter the full path to Delivery Site'
$LocalDrive  = 'P:'
$Credentials = Get-Credential


if (!(Test-Path $LocalDrive -PathType Container)) {
    $retrycount = 0; $completed = $false
    while (-not $completed) {
        Try {
            if (!(Test-Path $LocalDrive -PathType Container)) {
                (New-Object -ComObject WScript.Network).MapNetworkDrive($LocalDrive,$SharePoint,$false,$($Credentials.username),$($Credentials.GetNetworkCredential().password))
            }
            $Completed = $true
        }
        Catch {
            if ($retrycount -ge '5') {
                Write-Verbose "Mapping SharePoint drive failed the maximum number of times"
                throw "SharePoint drive mapping failed for '$($SharePoint)': $($Global:Error[0].Exception.Message)"
            } else {
                Write-Verbose "Mapping SharePoint drive failed, retrying in 5 seconds."
                Start-Sleep '5'
                $retrycount++
            }
        }
    }
}

I've also used the following code with similar results or no results at all.

#Get User Information
$user = Read-Host "Enter your username"
$username = "$user@MyCompany"
$password = Read-Host "Enter your password" -AsSecureString

#Gathering the location of the Card Formats and Destination folder
$Customer = "$SharePoint\MyCustomer"
$Products = "$Path\$($CustomerName)\Products\"

#Get Documents from SharePoint
$credential = New-Object System.Management.Automation.PSCredential($UserName, $Password)
New-PSDrive -Credential $credential -Name "A" -PSProvider "FileSystem" -Root "$SharePoint"
net use $spPath #$password /USER:$user@corporate

#Get PMDeliverables file objects recursively
Get-ChildItem -Path "$Customer" | Where-Object { $_.name -like 'MS*' } | Copy-Item -Destination $Products  -Force -Verbose
like image 794
RadFox Avatar asked Mar 10 '23 09:03

RadFox


1 Answers

Without defined "input parameters", it's not exactly clear the full solution you need so I'll provide a few snippets of PowerShell that should be of use based on what you've described.

I'll spare you the basics of the various OOTB functions (i.e. Get-SPWeb, etc) though can provide those details as well if needed. I've also been overly explicit in the scripting, though know some of these lines could be chained, piped, etc to be made shorter & more efficient.

This example will iterate over the contents of a SharePoint Library and download them to your local machine:

$Destination = "C:\YourDestinationFolder\ForFilesFromSP"
$Web = Get-SPWeb "https://YourServerRoot/sites/YourSiteCollection/YourSPWebURL"
$DocLib = $Web.Lists["Your Doc Library Name"]
$DocLibItems = $DocLib.Items

foreach ($DocLibItem in $DocLibItems) {
    if($DocLibItem.Url -Like "*.docx") {
        $File = $Web.GetFile($DocLibItem.Url)
        $Binary = $File.OpenBinary()
        $Stream = New-Object System.IO.FileStream($Destination + "\" + $File.Name), Create
        $Writer = New-Object System.IO.BinaryWriter($Stream)
        $Writer.write($Binary)
        $Writer.Close()
    }
}

This is pretty basic; the variables up top are where on your local machine you wish to store the download files ($Destination), the URL of your SharePoint Site/Web ($Web) and the name of the Document Library (Your Doc Library Name).

The script then iterates through the items in the Library (foreach ($DocLibItem in $DocLibItems) {}), optionally filters for say items with a .docx file extension and downloads each to your local machine.

You could customize this further by targeting a specific sub-folder within the Doc Library, filter by metadata or properties of the Docs or even iterate over multiple Sites, Webs and/or Libraries in one script, optionally filtering those based on similar properties.

like image 192
Stevangelista Avatar answered Mar 19 '23 09:03

Stevangelista