powershell download file from Get-PnPListItem - powershell

Im new to scripting and powershell so bare with me.
My goal is to connect to Sharepoint online, and download the latest file uploaded to the a specific site.
Currently I am able to Connect to Sharepoint with Connect-PnPonline, then i use PnPListItem to query the file i need, but i am stuck at the last step to download the file.
here is my code:
cls
$SPOsite="https://example.sharepoint.com/sites/example"
$TargetFile="C:\example"
Connect-PnPOnline -Url $SPOsite -ClientId xxxxx-xxxxx-xxxxx-xxxx -ClientSecret secretsecret112233
$ListItems = Get-PnPListItem -List Documents | select -last 1
$ctx= Get-PnPContext
foreach ($item in $ListItems)
{
$file = $item.file
$fileversions = $file.Versions
$ctx.load($file)
$ctx.load($fileversions)
$ctx.ExecuteQuery()
Write-Host $file.Name,$fileversions.VersionLabel
}
Get-PnPFile -Url "https://example.sharepoint.com/sites/example" -Filename $ListItems -Path $TargetFile -AsFile
Error message that i get is
Get-PnPFile : File Not Found.
At \\cifs-share.example.org\Usershome\user\Desktop\PowerShell\dwnldSPfiles.ps1:20 char:1
+ Get-PnPFile -Url "https://example.sharepoint.com/sites/example" -Fi ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (:) [Get-PnPFile], ServerException
+ FullyQualifiedErrorId : EXCEPTION,PnP.PowerShell.Commands.Files.GetFile

Try this:
$SharePointFolderPath = "Shared Documents"
$Files = Get-PnPFolderItem -FolderSiteRelativeUrl $SharePointFolderPath -ItemType File
foreach($File in $Files) {
if($File.Name -eq "file name"){
Get-PnPFile -Url $File.ServerRelativeUrl -Path c:\Temp -FileName $File.Name -AsFile
}
}
Url should be the ServerRelativeUrl to the file which you want to download.

Related

try catch block inside nested foreach loop

I will upload file under folder onTeams with PowerShell. I am using some try/catch block inside if/else statement. How can we improve my script? Or what do you recommend? I want to know is whether there is any way to make this code run better. I'm new to Powershell, so I don't know what looks like bad code or good code.
Let's say, I've run my script in November 2022. It will create a folder called 2022-10 under "/sites/Team/Shared Documents/General/Documents/2022"
Or I've run my script in February 2023. Firstly, it will create called 2023 mail folder for new year under "/sites/Team/Shared Documents/General/Documents/ Then it will create folder called 2023-01 under "/sites/Team/Shared Documents/General/Documents/2023"
And so on.
My script:
#Config Variables
$SiteURL = "https://company.sharepoint.com/sites/Team"
$SourceFilePath ="C:\Documents\report.csv"
$DestinationFolderPath = "/sites/Team/Shared Documents/General/Documents" #Server Relative URL
Try {
#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -ClientId "47bf0ca0-1d8a-xxxx-xxx-xxxx" -Tenant 'tenant.onmicrosoft.com' -Thumbprint <Thumbprint>
}
catch {
write-host "Error: $($_.Exception.Message)" -foregroundcolor Red
}
$year= get-date -Format yyyy
$FolderURL = $DestinationFolderPath + "/" + $year
#Try to Get the Folder
$Folder = Get-PnPFolder -Url $FolderURL -ErrorAction SilentlyContinue
#sharepoint online powershell To check if folder exists
If($Folder -ne $null)
{
Write-Host -f Green "Folder exists!"
Try{
$d = (get-date).AddMonths(-1).ToString("yyyy-M")
$FolderPATHLastMonth = $DestinationFolderPath + "/" + $year
Add-PnPFolder -Name $d -Folder $FolderPATHLastMonth
$DestinationFolderPath = $FolderPATHLastMonth + "/" + $d
Add-PnPFile -Path $SourceFilePath -Folder $DestinationFolderPath -ErrorAction Stop
}
catch{
echo $_.Exception
}
}
Else
{
Write-Host -f Yellow "Folder does not exists!"
Try{
Add-PnPFolder -Name $year -Folder $DestinationFolderPath
$d2 = (get-date).AddMonths(-1).ToString("yyyy-M")
$FolderPATHLastMonth = $DestinationFolderPath + "/" + $year
Add-PnPFolder -Name $d2 -Folder $FolderPATHLastMonth
$DestinationFolderPath = $FolderPATHLastMonth + "/" + $d2
Add-PnPFile -Path $SourceFilePath -Folder $DestinationFolderPath -ErrorAction Stop
}
catch{
echo $_.Exception
}
}

Uploading 2 files with same name to FTP using powershell script

I am a beginner at powershell script and I am stuck
I am trying to upload 2 xml files with the same name to FTP, but I am getting the following error
Exception calling "UploadFile" with "2" argument(s): "An
exception occurred during a WebClient request." At
C:\powershell\ExternalWidgets\upload-to-ftp.ps1:51 char:16
+ $webclient.UploadFile($uri.AbsoluteUri, $LocalPath)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WebException`
Here is the script:
#SET CREDENTIALS
$credentials = new-object System.Net.NetworkCredential($user, $pass)
cd $target
$DirectoryContent = Get-ChildItem -Directory
foreach($item in $DirectoryContent){
cd $item
$currentFolderItems = Get-ChildItem
foreach( $subfolderItem in $currentFolderItems)
{
if ($subfolderItem.name -eq "package.json") {
$subItem = Get-ChildItem -Directory
foreach($subItem in $subItem)
{
if ($subItem.name -eq "coverage") {
$files = Get-ChildItem -Path $subItem
$n = 0
foreach ($file in $files)
{
#rename coverage file
if($file.Name -eq "cobertura-coverage.xml") {
$newFileName=$file.Name.Replace("cobertura-coverage.xml","cobertura-coverage$n.xml")
Rename-Item $file -NewName $newFileName
$newFileName
}
$n++
}
}
}
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = New-Object
System.Net.NetworkCredential($user,$pass)
$uri = New-Object System.Uri($ftp + "/" + $folder)
#Delete files from FTP
# $fileUploaded =($uri + "\" + $newFileName)
# $fileUploaded
# Remove-Item $fileUploaded
$LocalPath =($target + "\" + $item + "\" + "coverage" + "\" +
$newFileName).Replace(".\", "").Replace('\', '/')
$webclient.UploadFile($uri, $LocalPath)
#cd..
}
}
cd ..
}
I also get an error when I want to rename one of the files. What step am I missing? Thank you

File not found trying to get all versions of a file from OneDrive using get-PnPFile

I'm looking to write a PowerShell script to download of all versions from a single OneDrive file, but I can't get a valid URL for Get-PnPFile to accept.
$ctx= Get-PnPContext
$item = Get-PnPFile -Url [url] -AsListItem
$file = $item.file
$ctx.Load($file)
$fileVersions = $file.Versions
$ctx.Load($fileVersions)
$ctx.ExecuteQuery()
foreach ($version in $fileVersions) {
Get-PnPFile -Url $version.Url -Path z:\tmp -FileName ($file.Name + " " + $version.VersionLabel + ".json") -AsFile
}
}
Powershell documentation suggests you can use a site-relative Url for the -Url
the $version.Url has the format _vti_history/2662400/Documents/[filename]
adding /personal/[email_address]/... doesn't resolve the 'File Not Found' error for me.
Get-PnPFile is not able to download the file from _vti_history. You need to use the CSOM functionality $version.OpenBinaryStream().
For SharePoint Online I'm using following code:
Get-PnPFile -Url $item.ServerRelativeUrl -Path $destinationFolderPath -AsFile -Force # Latest version
$ctx= Get-PnPContext
$ctx.Load($item.Versions)
$ctx.ExecuteQuery()
foreach ($version in $item.Versions)
{
$versionValue = $version.VersionLabel
$str = $version.OpenBinaryStream()
$ctx.ExecuteQuery()
$filename = (Split-Path $item.ServerRelativeUrl -Leaf) + "." + $versionValue
$filepath = Join-Path $destinationFolderPath $filename
$fs = New-Object IO.FileStream $filepath ,'Append','Write','Read'
$str.Value.CopyTo($fs) # Older version
$fs.Close()
}

Powershell - Saving downloaded file on network share

The PS1 needs to download an XML file from a remote HTTP server and save it on a network share.
Summary of the script is as follows
$timer = (Get-Date -Format yyyyMMdd_hhmmss)
$storageDir = "\\10.16.99.99\what\ever\Folder"
$filename1 = "John_" + "$timer.xml"
$webclient = New-Object System.Net.WebClient
$url1 = "http://whateverURL/John.xml"
$file1 = "$storageDir\$filename1"
$webclient.DownloadFile($url1,$file1)
$source = "\\10.16.99.99\what\ever\Folder"
$target = "\\10.16.99.99\what\ever\TargetFolder"
$files = get-childitem $source -Recurse
foreach ($file in $files){
if ($file.LastWriteTime -ge (get-date).AddMinutes(-10)){
$targetFile = $target + $file.FullName.SubString($source.Length)
New-Item -ItemType File -Path $targetFile -Force
Copy-Item $file.FullName -destination $targetFile
Start-Sleep -s 3
}
}
When I run the script, I get following error through PowerShell CMD
Exception calling "DownloadFile" with "2" argument(s): "An exception occurred during a WebClient
request."
At D:\StagisEE\GlobalListing\GL_download.ps1:318 char:3
+ $webclient.DownloadFile($url1,$file1)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WebException
Therefore I added the following lines to see what the variables are that will be used in the webClient command
Write-Host $url1
Write-Host $file1
Which gave me the following, additional, results
http://whateverURL/John.xml
\\10.16.99.99\what\ever\Folder\John_20191224_103412.xml
My question is why that the webClient is failing while the variables seems to be ok?
Or is he struggling due to the network location?

Trying to upload files to subfolder in Sharepoint Online via Powershell

I am new to Powershell and I am trying to upload files from a local folder into Sharepoint online. I seem to get the files into the library, but not into the second subfolder where i want them.
Script so far:
#Specify tenant admin and site URL
$User = "admin#contoso.no"
$SiteURL = "https://contoso.sharepoint.com"
$Folder = "E:\LocalFolder"
$DocLibName = "Libraryname"
$FolderName = "Folder/SubFolder"
#Add references to SharePoint client assemblies and authenticate to Office 365 site – required for CSOM
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
$Password = "password" | ConvertTo-SecureString -AsPlainText -Force
#Bind to site collection
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($User,$Password)
$Context.Credentials = $Creds
#Retrieve list
$List = $Context.Web.Lists.GetByTitle($DocLibName)
$Context.Load($List)
$Context.ExecuteQuery()
#Retrieve folder
$FolderToBindTo = $List.RootFolder.Folders
$Context.Load($FolderToBindTo)
$Context.ExecuteQuery()
$FolderToUpload = $FolderToBindTo | Where {$_.Name -eq $FolderName}
#Upload file
Foreach ($File in (dir $Folder -File))
{
$FileStream = New-Object IO.FileStream($File.FullName,[System.IO.FileMode]::Open)
$FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
$FileCreationInfo.Overwrite = $true
$FileCreationInfo.ContentStream = $FileStream
$FileCreationInfo.URL = $File
$Upload = $FolderToUpload.Files.Add($FileCreationInfo)
$Context.Load($Upload)
$Context.ExecuteQuery()
}
If I use &FolderName = "Folder" the script runs fine. But what do i do to get the files into a subfolder? If I set a filepath as FolderName it does not work. I get the following errors:
You cannot call a method on a null-valued expression.
+ $Upload = $FolderToUpload.Files.Add($FileCreationInfo)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Cannot find an overload for "Load" and the argument count: "1".
+ $Context.Load($Upload)
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodCountCouldNotFindBest
enter code here
Been stuck on this for days :(
The error You cannot call a method on a null-valued expression. occurs since the $FolderToUpload object is not getting initialized at line:
$FolderToUpload = $FolderToBindTo | Where {$_.Name -eq $FolderName}
when $FolderName object points to sub folder name
The point is that $List.RootFolder.Folders returns only a folders located one level beneath under list or library, hence sub folder could not be referenced this way.
Instead you could consider the following options to reference a sub folder to add a file.
Using FileCreationInformation.Url property
Use FileCreationInformation.Url property to specify the folder url for a uploaded file.
#Retrieve list
$List = $Context.Web.Lists.GetByTitle($DocLibName)
$Context.Load($List.RootFolder)
$Context.ExecuteQuery()
#Upload file(s)
Foreach ($File in (dir $Folder -File))
{
$FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
$FileCreationInfo.Overwrite = $true
$FileCreationInfo.Content = [System.IO.File]::ReadAllBytes($File.FullName)
$FileCreationInfo.URL = $List.RootFolder.ServerRelativeUrl + "/" + $FolderName + "/" + $File.Name
$UploadFile = $List.RootFolder.Files.Add($FileCreationInfo)
$Context.Load($UploadFile)
$Context.ExecuteQuery()
}
Using Web.GetFolderByServerRelativeUrl method
Use Web.GetFolderByServerRelativeUrl method to retrieve a folder where file have to be uploaded:
#Retrieve list
$List = $Context.Web.Lists.GetByTitle($DocLibName)
$Context.Load($List.RootFolder)
$Context.ExecuteQuery()
$TargetFolder = $Context.Web.GetFolderByServerRelativeUrl($List.RootFolder.ServerRelativeUrl + "/" + $FolderName);
#Upload file(s)
Foreach ($File in (dir $Folder -File))
{
$FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
$FileCreationInfo.Overwrite = $true
$FileCreationInfo.Content = [System.IO.File]::ReadAllBytes($File.FullName)
$FileCreationInfo.URL = $File.Name
$UploadFile = $TargetFolder.Files.Add($FileCreationInfo)
$Context.Load($UploadFile)
$Context.ExecuteQuery()
}
You can also use the Office 365 Import service to bulk upload files to sharepoint online instead of using CSOM scripts.
This uses the new Sharepoint API which provides much faster speeds without any throttling as it uses scalable azure infrastructure.
https://support.office.com/en-us/article/Use-network-upload-to-import-SharePoint-data-to-Office-365-ed4a43b7-c4e3-45c8-94c8-998153407b8a