Why doesn't this script also process the subfolders when it should? - powershell

I want to move all folders as well as subfolders and files in the subfolders from dir 1 to dir 2 in SharePoint Online via PowerShell. The script already moves all files from the main directory of dir 1 (/sites/customer/shared documents/dir 1) to the main directory of dir 2 (/sites/customer/shared documents/dir 2). But somehow it doesn't move files from subfolders like "/sites/customer/shared documents/dir 1/sub 1".
#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
Function Move-SPOFilesBetweenFolders
{
param
(
[Parameter(Mandatory=$true)] [string] $SiteURL,
[Parameter(Mandatory=$true)] [Microsoft.SharePoint.Client.Folder] $SourceFolder,
[Parameter(Mandatory=$true)] [Microsoft.SharePoint.Client.Folder] $TargetFolder
)
Try {
#Write-host "Copying Files from '$($SourceFolder.ServerRelativeUrl)' to '$($TargetFolder.ServerRelativeUrl)'"
#Get all Files from the source folder
$SourceFilesColl = $SourceFolder.Files
$Ctx.Load($SourceFilesColl)
$Ctx.ExecuteQuery()
#Iterate through each file and move
Foreach($SourceFile in $SourceFilesColl)
{
#Get all files from source Folder
$SourceFile =$Ctx.Web.GetFileByServerRelativeUrl($SourceFile.ServerRelativeUrl)
$Ctx.Load($SourceFile)
$Ctx.ExecuteQuery()
$TargetFileUrl = $SourceFile.ServerRelativeUrl -Replace $SourceFolderURL,$TargetFolderURL
Try {
#Move File to destination
$SourceFile.MoveTo($TargetFileUrl, [Microsoft.SharePoint.Client.MoveOperations]::None)
$Ctx.ExecuteQuery()
Write-host -f Green "File Moved to: "$TargetFileURL
}
catch {
Write-host -f Red "File already exists: "$TargetFileURL
}
}
#Process Sub Folders
$SubFolders = $SourceFolder.Folders
$Ctx.Load($SubFolders)
$Ctx.ExecuteQuery()
Foreach($SubFolder in $SubFolders)
{
If($SubFolder.Name -ne "Forms")
{
#Prepare Target Folder
$EnsureFolderURL = $SubFolder.ServerRelativeUrl -Replace $SourceFolderUrl, $TargetFolderUrl
Try {
$Folder=$Ctx.web.GetFolderByServerRelativeUrl($EnsureFolderURL)
$Ctx.load($Folder)
$Ctx.ExecuteQuery()
}
catch {
#Create Folder
if(!$Folder.Exists)
{
$Folder=$Ctx.Web.Folders.Add($EnsureFolderURL)
$Ctx.Load($Folder)
$Ctx.ExecuteQuery()
Write-host "New Folder Created:"$SubFolder.Name -f Yellow
}
}
#Call the function recursively to move all files from source folder to target
Move-SPOFilesBetweenFolders -SiteURL $SiteURL -SourceFolder $SubFolder -TargetFolder $Folder
#Remove the Source Folder
$SubFolder.Recycle() | Out-Null
$Ctx.ExecuteQuery()
}
}
}
Catch {
write-host -f Red "Error Moving File:" $_.Exception.Message
}
}
#Set Parameter values
$SiteURL="https://company.sharepoint.com/sites/customer"
$SourceFolderURL ="/sites/customer/shared documents/dir 1"
$TargetFolderURL ="/sites/customer/shared documents/dir 2"
#Setup Credentials to connect
$Cred= Get-Credential
#Setup the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
#Get the source and Target Folders
$SourceFolder=$Ctx.Web.GetFolderByServerRelativeUrl($SourceFolderURL)
$Ctx.Load($SourceFolder)
$TargetFolder=$Ctx.Web.GetFolderByServerRelativeUrl($TargetFolderURL)
$Ctx.Load($TargetFolder)
$Ctx.ExecuteQuery()
#Call the function
Move-SPOFilesBetweenFolders -SiteURL $SiteURL -SourceFolder $SourceFolder -TargetFolder $TargetFolder
Only files from the main directory /sites/customer/shared documents/dir 1 have been moved to /sites/customer/shared documents/dir 2. The script should also include subfolders and their files.

Related

How to remove large OneDrive folder or subfolder using PowerShell

I'm planning to delete my OneDrive subfolders using PowerShell but I'm unable to do it because the sub folders is prettry large, have too many depth and items so just wondering how should I modify my script so that I can delete it.
Under the Parent Folder, I used to have 5 Subfolders. I was able to delete the other 3 subfolders already but I wasn't able to do it for the remaining 2 because of the reason above.
Add-Type -Path "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.Online.SharePoint.Client.Tenant.dll"
#Key File information for secure connection
$Global:adminUPN = "upn"
$Global:PasswordFile = "C:\scripts\LitHold-OneDrive\key-file\ODpw.txt"
$Global:KeyFile = "C:\scripts\LitHold-OneDrive\key-file\OD.key"
$Global:adminPwd = ""
$CurDate = Get-Date -Format "yyyy-MM-dd"
#Pwd Key Encryption File
$key = Get-Content $Global:KeyFile
$Global:adminPwd = Get-Content $Global:PasswordFile | ConvertTo-SecureString -Key $key
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Global:adminUPN, $Global:adminPwd
#Variables
$SiteURL = "OD URL"
$ServerRelativeUrl= "Documents/parentFolder"
Try {
#Get Credentials to connect
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Global:adminUPN, $Global:adminPwd)
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$ctx.Credentials = $Credentials
#Get the web from URL
$Web = $Ctx.web
$Ctx.Load($Web)
$Ctx.executeQuery()
#Get the Folder object by Server Relative URL
$Folder = $Web.GetFolderByServerRelativeUrl($ServerRelativeUrl)
$Ctx.Load($Folder)
$Ctx.ExecuteQuery()
#Call the function to empty Folder
Empty-SPOFolder $Folder
#Delete the given Folder itself
Write-host -f Green "Deleting Folder:"$Folder.ServerRelativeUrl
$Folder.Recycle() | Out-Null
$Ctx.ExecuteQuery()
}
Catch {
write-host -f Red "Error:" $_.Exception.Message
}
#Function to Delete all files and Sub-folders of a given Folder
Function Empty-SPOFolder([Microsoft.SharePoint.Client.Folder]$Folder)
{
Try {
#Get All Files from the Folder
$Ctx = $Folder.Context
$Files = $Folder.Files
$Ctx.Load($Files)
$Ctx.ExecuteQuery()
#Iterate through each File in the Root folder
Foreach($File in $Files)
{
#Delete the file
Write-Host -f Green "$File.Name"
$Folder.Files.GetByUrl($File.ServerRelativeUrl).Recycle() | Out-Null
$Folder.Files.GetByUrl($File.ServerRelativeUrl).DeleteObject() | Out-Null
Write-host -f Green "Deleted File '$($File.Name)' from '$($File.ServerRelativeURL)'"
}
$Ctx.ExecuteQuery()
#Process all Sub Folders of the given folder
$SubFolders = $Folder.Folders
$Ctx.Load($SubFolders)
$Ctx.ExecuteQuery()
#delete all subfolders
Foreach($Folder in $SubFolders)
{
#Exclude "Forms" and Hidden folders
#Call the function recursively to empty the folder
Empty-SPOFolder -Folder $Folder
#Delete the folder
Write-Host -f Green "$Folder.UniqueId"
#$Ctx.Web.GetFolderById($Folder.UniqueId).Recycle() | Out-Null
$Ctx.Web.GetFolderById($Folder.UniqueId).DeleteObject() | Out-Null
$Ctx.ExecuteQuery()
Write-host -f Green "Deleted Folder:"$Folder.ServerRelativeUrl
}
}
Catch {
write-host -f Red "Error: $Folder.UniqueId - $File.Name " $_.Exception.Message
}
}

Skip error and exception time-outs in for...each loops Powershell

I'm quite new to PS-scripting. I need to download files and folders from Sharepoint using Powershell. The script I have works fine, but it stops running when there is an error/exception. I already removed the try/catch which makes the script continue running after an error/exception, but it still has long time-outs before downloading the next file. And in fact I would like to keep catching the errors so I can log the names of the files that caused an error in a txt-file or so.
What is the best way to do all of this?
Function Download-SPOFolder()
{
param
(
[Parameter(Mandatory=$true)] [string] $SiteURL,
[Parameter(Mandatory=$true)] [Microsoft.SharePoint.Client.Folder] $SourceFolder,
[Parameter(Mandatory=$true)] [string] $TargetFolder
)
Try {
#Create Local Folder, if it doesn't exist
$FolderName = ($SourceFolder.ServerRelativeURL) -replace "/","\"
$LocalFolder = $TargetFolder + $FolderName
If (!(Test-Path -Path $LocalFolder)) {
New-Item -ItemType Directory -Path $LocalFolder | Out-Null
}
#Get all Files from the folder
$FilesColl = $SourceFolder.Files
$Ctx.Load($FilesColl)
$Ctx.ExecuteQuery()
#Iterate through each file and download
Foreach($File in $FilesColl)
{
$TargetFile = $LocalFolder+"\"+$File.Name
#Download the fileS
$FileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($Ctx,$File.ServerRelativeURL)
$WriteStream = [System.IO.File]::Open($TargetFile,[System.IO.FileMode]::Create)
$FileInfo.Stream.CopyTo($WriteStream)
$WriteStream.Close()
write-host -f Green "Downloaded File:"$TargetFile
}
#Process Sub Folders
$SubFolders = $SourceFolder.Folders
$Ctx.Load($SubFolders)
$Ctx.ExecuteQuery()
Foreach($Folder in $SubFolders)
{
If($Folder.Name -ne "Forms")
{
#Call the function recursively
Download-SPOFolder -SiteURL $SiteURL -SourceFolder $Folder -TargetFolder $TargetFolder
}
}
}
Catch {
$msg = $Error[0].Exception.Message
write-host -f Red "Error Downloading Folder! - $msg"
}
}
#Set parameter values
$orgName="myOrgName"
$admin="myUsrName"
$SiteURL="myUrl"
$FolderRelativeUrl="myFolderUrl"
$TargetFolder="C:\Temp"
#Setup Credentials to connect
$cred = Get-Credential -UserName $admin -Message GlobalAdminLogin
Connect-SPOService -Url https://$orgName-admin.sharepoint.com -Credential $cred
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
#Setup the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = $Credentials
#Get the Web
$Web = $Ctx.Web
$Ctx.Load($Web)
$Ctx.ExecuteQuery()
$Web.ServerRelativeUrl+$FolderRelativeUrl
#Get the Folder
$SourceFolder = $Web.GetFolderByServerRelativeUrl($Web.ServerRelativeUrl+$FolderRelativeUrl)
$Ctx.Load($SourceFolder)
$Ctx.ExecuteQuery()
#Call the function to download Folder
Download-SPOFolder -SiteURL $SiteURL -SourceFolder $SourceFolder -TargetFolder $TargetFolder

Empty sharepoint online folder

I am looking for a way to automatically empty a folder in sharepoint online once a day. I think the best way to do this is using a powershell script from a local server. I tried to search this on google but then I can only find how to delete a folder. But I want to delete all the content within a folder and not the folder itself. Does anyone know a good solution or powershell script for this?
Oke i got a working powershell script from the URL that Theo provided: [https://www.sharepointdiary.com/2018/05/sharepoint-online-delete-all-files-in-document-library-using-powershell.html][1]
the script looks like this:
#Load SharePoint CSOM Assemblies
#Download Sharepoint CSOM Assemblies from https://www.microsoft.com/en-us/download/details.aspx?id=42038
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
#Variables for Processing
$SiteURL = "https://tenantname.sharepoint.com/sites/TestTeam"
$LibraryRelativeURL = "/sites/TestTeam/Shared Documents/TEST/TestFolder"
Try {
#Get Credentials to connect
$Cred = Get-Credential
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
#Setup the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = $Credentials
#Get the Library and Files
$Folder=$Ctx.Web.GetFolderByServerRelativeUrl($LibraryRelativeURL)
$Ctx.Load($Folder)
$Files = $Folder.Files
$Ctx.Load($Files)
$Ctx.ExecuteQuery()
#Iterate through each File in the Root folder
Foreach($File in $Files)
{
#Delete the file
$Folder.Files.GetByUrl($File.ServerRelativeUrl).Recycle() | Out-Null
Write-host -f Green "Deleted File '$($File.Name)' from '$($File.ServerRelativeURL)'"
}
$Ctx.ExecuteQuery()
#Process all Sub Folders
$SubFolders = $Folder.Folders
$Ctx.Load($SubFolders)
$Ctx.ExecuteQuery()
Foreach($SubFolder in $SubFolders)
{
#Exclude "Forms" and Hidden folders
If( ($SubFolder.Name -ne "Forms") -and (-Not($SubFolder.Name.StartsWith("_"))))
{
#Delete the folder
$Folder.Folders.GetByUrl($SubFolder.ServerRelativeUrl).Recycle()| Out-Null
Write-host -f Green "Deleted Folder '$($SubFolder.Name)' from '$($SubFolder.ServerRelativeUrl)'"
}
$Ctx.ExecuteQuery()
}
}
Catch {
write-host -f Red "Error:" $_.Exception.Message
}

Uploading bulk files from local system to SharePoint online using PowerShell script throwing an error you cannot call null valued expression

My requirement is to upload multiple files using PowerShell script to SharePoint online.
while uploading files to a folder in the SharePoint document library, it showing me this error.
I am extracting only file name before uploading and create a folder with that filename and want to upload the file in that particular folder using PowerShell script .
#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
### Variables for Processing
$WebUrl = "https://tanviteddu.sharepoint.com/sites/Powershell/"
$LibraryName ="Documents"
$ListURL="/sites/Powershell/Shared Documents/Reports"
$SourceFolder="C:\Hari Priya"
#Setup Credentials to connect
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName,(ConvertTo-SecureString $Password -AsPlainText -Force))
#Set up the context
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($WebUrl)
$Context.Credentials = $Credentials
#Get the Library
$Library = $Context.Web.Lists.GetByTitle($LibraryName)
#upload each file from the directory
Foreach ($File in (dir $SourceFolder -File))
{
$fn=(Split-path -Path $file -Leaf).Split(".")[0];
Try
{
#Set up the context
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl)
$Context.Credentials = $credentials
#Get the List Root Folder
$ParentFolder=$Context.web.GetFolderByServerRelativeUrl($ListURL)
#sharepoint online powershell create folder
$Folder = $ParentFolder.Folders.Add($fn)
$ParentFolder.Context.ExecuteQuery()
Write-host "New Folder Created Successfully!" -ForegroundColor Green
}
catch
{
write-host "Error: $($_.Exception.Message)" -foregroundcolor Red
}
#Get the file from disk
$FileStream = ([System.IO.FileInfo] (Get-Item $File.FullName)).OpenRead()
$FinalUrl=$ListURL+"\"+$fn+"\"+$file
#Upload the File to SharePoint Library
$FileCreationInfo = New-Object
Microsoft.SharePoint.Client.FileCreationInformation
$FileCreationInfo.Overwrite = $true
$FileCreationInfo.ContentStream = $FileStream
$FileCreationInfo.URL = $File
$FileUploaded = $FinalUrl.RootFolder.Files.Add($FileCreationInfo)
#powershell to upload files to sharepoint online
$Context.Load($FileUploaded)
$Context.ExecuteQuery()
#Close file stream
$FileStream.Close()
write-host "File: $($File) has been uploaded!"
}
While uploading, it is showing the error as below:
You cannot call a method on a null-valued expression.
At line:26 char:5
+ $FileUploaded = $FinalUrl.RootFolder.Files.Add($FileCreationInfo)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeExceptio
+ FullyQualifiedErrorId : InvokeMethodOnNull
Cannot find an overload for "Load" and the argument count: "1".
At line:28 char:5
+ $Context.Load($FileUploaded)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodCountCouldNotFindBest
Please help me out
The below is working code - upload files from local drive to SharePoint online using PowerShell CSOM:
#Load SharePoint CSOM Assemblies
#Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
#Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
cls
$fileName = "File_Uploading_Report"
#'yyyyMMddhhmm yyyyMMdd
$enddate = (Get-Date).tostring("yyyyMMddhhmmss")
#$filename = $enddate + '_VMReport.doc'
$logFileName = $fileName +"_"+ $enddate+"_Log.txt"
$invocation = (Get-Variable MyInvocation).Value
$directoryPath = Split-Path $invocation.MyCommand.Path
$directoryPathForLog=$directoryPath+"\"+"LogFiles"
if(!(Test-Path -path $directoryPathForLog))
{
New-Item -ItemType directory -Path $directoryPathForLog
#Write-Host "Please Provide Proper Log Path" -ForegroundColor Red
}
#$logPath = $directoryPath + "\" + $logFileName
$logPath = $directoryPathForLog + "\" + $logFileName
$isLogFileCreated = $False
#DLL location
$directoryPathForDLL=$directoryPath+"\"+"Dependency Files"
if(!(Test-Path -path $directoryPathForDLL))
{
New-Item -ItemType directory -Path $directoryPathForDLL
#Write-Host "Please Provide Proper Log Path" -ForegroundColor Red
}
#DLL location
$clientDLL=$directoryPathForDLL+"\"+"Microsoft.SharePoint.Client.dll"
$clientDLLRuntime=$directoryPathForDLL+"\"+"Microsoft.SharePoint.Client.dll"
Add-Type -Path $clientDLL
Add-Type -Path $clientDLLRuntime
#Files to upload location
$directoryPathForFileToUploadLocation=$directoryPath+"\"+"Files To Upload"
if(!(Test-Path -path $directoryPathForFileToUploadLocation))
{
New-Item -ItemType directory -Path $directoryPathForFileToUploadLocation
#Write-Host "Please Provide Proper Log Path" -ForegroundColor Red
}
#Files to upload location ends here.
function Write-Log([string]$logMsg)
{
if(!$isLogFileCreated){
Write-Host "Creating Log File..."
if(!(Test-Path -path $directoryPath))
{
Write-Host "Please Provide Proper Log Path" -ForegroundColor Red
}
else
{
$script:isLogFileCreated = $True
Write-Host "Log File ($logFileName) Created..."
[string]$logMessage = [System.String]::Format("[$(Get-Date)] - {0}", $logMsg)
Add-Content -Path $logPath -Value $logMessage
}
}
else
{
[string]$logMessage = [System.String]::Format("[$(Get-Date)] - {0}", $logMsg)
Add-Content -Path $logPath -Value $logMessage
}
}
#The below function will upload the file from local directory to SharePoint Online library.
Function FileUploadToSPOnlineLibrary()
{
param
(
[Parameter(Mandatory=$true)] [string] $SPOSiteURL,
[Parameter(Mandatory=$true)] [string] $SourceFilePath,
[Parameter(Mandatory=$true)] [string] $File,
[Parameter(Mandatory=$true)] [string] $TargetLibrary,
[Parameter(Mandatory=$true)] [string] $UserName,
[Parameter(Mandatory=$true)] [string] $Password
)
Try
{
$securePassword= $Password | ConvertTo-SecureString -AsPlainText -Force
#Setup the Context
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SPOSiteURL)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $securePassword)
$list = $ctx.Web.Lists.GetByTitle($TargetLibrary)
$ctx.Load($list)
$ctx.ExecuteQuery()
$tarGetFilePath=$siteURL+"/"+"$TargetLibrary"+"/"+$File
$fileOpenStream = New-Object IO.FileStream($SourceFilePath, [System.IO.FileMode]::Open)
$fileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
$fileCreationInfo.Overwrite = $true
$fileCreationInfo.ContentStream = $fileOpenStream
$fileCreationInfo.URL = $File
$uploadFileInfo = $list.RootFolder.Files.Add($FileCreationInfo)
$ctx.Load($uploadFileInfo)
$ctx.ExecuteQuery()
Write-host -f Green "File '$SourceFilePath' has been uploaded to '$tarGetFilePath' successfully!"
}
Catch
{
$ErrorMessage = $_.Exception.Message +"in uploading File!: " +$tarGetFilePath
Write-Host $ErrorMessage -BackgroundColor Red
Write-Log $ErrorMessage
}
}
#Variables
$siteURL="https://globalsharepoint.sharepoint.com/sites/TestSite/"
$listName="TestDocumentLibrary"
$fromDate="2019-10-28"
$toDate="2019-11-09"
$filesFolderLoaction=$directoryPathForFileToUploadLocation;
$userName = "YourSPOAccount#YourTenantDomain.com"
$password = "YourPassWord"
$securePassword= $password | ConvertTo-SecureString -AsPlainText -Force
#Variables ends here.
$filesCollectionInSourceDirectory=Get-ChildItem $filesFolderLoaction -File
$uploadItemCount=1;
#Extract the each file item from the folder.
ForEach($oneFile in $filesCollectionInSourceDirectory)
{
try
{
FileUploadToSPOnlineLibrary -SPOSiteURL $siteURL -SourceFilePath $oneFile.FullName -File $oneFile -TargetLibrary $listName -UserName $UserName -Password $Password
$fileUploadingMessage=$uploadItemCount.ToString()+": "+$oneFile.Name;
Write-Host $fileUploadingMessage -BackgroundColor DarkGreen
Write-Log $fileUploadingMessage
$uploadItemCount++
}
catch
{
$ErrorMessage = $_.Exception.Message +"in: " +$oneFile.Name
Write-Host $ErrorMessage -BackgroundColor Red
Write-Log $ErrorMessage
}
}
Write-Host "========================================================================"
Write-Host "Total number of files uploaded: " $filesCollectionInSourceDirectory.Count
Write-Host "========================================================================"
Reference URL:
https://global-sharepoint.com/powershell/upload-files-to-sharepoint-online-document-library-using-powershell-csom/

How to delete a zip file after its creation? File keeps being in use

We are currently working on a script, which is zipping a certain file, uploading it to a web server via API and then delete it locally again.
This is our current code:
$sourceFile = "D:\myfile.txt"
$destinationFile = "D:\myfile.zip"
function Add-Zip
{
Param([string]$zipfilename)
if (-not (Test-Path($zipfilename)))
{
Set-Content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $zipfilename).IsReadOnly = $false
}
$shellApplication = New-Object -Com Shell.Application
$zipPackage = $shellApplication.NameSpace($zipfilename)
foreach ($file in $input)
{
$zipPackage.CopyHere($file.FullName)
Start-Sleep -Milliseconds 500
}
}
dir $sourceFile | Add-Zip $destinationFile
Write-Host "zip created"
# code to upload the zip here
Remove-Item $destinationFile
Write-Host "zip removed"
It creates the zip perfectly, upload works too, but when try to delete the zip file using Remove-Item, we get
Remove-Item : Cannot remove item D:\myfile.zip: The process cannot access the file 'D:\myfile.zip' because it is being used by another process.
How can we get rid of this lock? Is there anything we can .Dispose() to be able to delete the file afterwards?
Okay, found another way here: https://danvers72.wordpress.com/2014/11/18/creating-a-zip-file-from-a-single-file/
This is my working code:
$sourceFile = "D:\myfile.txt"
$destinationFile = "D:\myfile.zip"
<#
.Synopsis
Creates a new archive from a file
.DESCRIPTION
Creates a new archive with the contents from a file. This function relies on the
.NET Framework 4.5. On windwows Server 2012 R2 Core you can install it with
Install-WindowsFeature Net-Framework-45-Core
.EXAMPLE
New-ArchiveFromFile -Source c:\test\test.txt -Destination c:\test.zip
#>
function New-ArchiveFromFile
{
[CmdletBinding()]
[OutputType([int])]
Param
(
# Param1 help description
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$false,
Position=0)]
[string]
$Source,
# Param2 help description
[Parameter(Mandatory=$true,
ValueFromPipelineByPropertyName=$false,
Position=1)]
[string]
$Destination
)
Begin
{
[System.Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null
}
Process
{
try
{
Write-Verbose "Creating archive $Destination…."
$zipEntry = "$Source" | Split-Path -Leaf
$zipFile = [System.IO.Compression.ZipFile]::Open($Destination, 'Update')
$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zipfile,$Source,$zipEntry,$compressionLevel)
Write-Verbose "Created archive $destination."
}
catch [System.IO.DirectoryNotFoundException]
{
Write-Host "ERROR: The source $source does not exist!" -ForegroundColor Red
}
catch [System.IO.IOException]
{
Write-Host "ERROR: The file $Source is in use or $destination already exists!" -ForegroundColor Red
}
catch [System.UnauthorizedAccessException]
{
Write-Host "ERROR: You are not authorized to access the source or destination" -ForegroundColor Red
}
}
End
{
$zipFile.Dispose()
}
}
New-ArchiveFromFile -Source $sourceFile -Destination $destinationFile
# code to upload the zip here
Remove-Item $destinationFile