Uploading folders in sharepoint from powershell

My below code successfully read a folder and uploades the subfolder one by one as a zip file in SharePoint. But if any of my file is of Zip extension, it gives me an error. I would like to know how can I fix my existing code below to handle the zip files as well so that it loads both the zip folder and non-zip files and folders in the SharePoint. I tried multiple tings like removing .zip extension in the Create-Archive and file but it does not work. error received:

2020-12-09T15:49:05.7979920Z Invoke-RestMethod : The remote server returned an error: (400) Bad Request. 2020-12-09T15:49:05.7981233Z At D:\a\r1\a_DevOpsScripts\ReleaseNoteScripts\UploadInSharePoint.ps1:55 char:17 2020-12-09T15:49:05.7982104Z + … $response = Invoke-RestMethod $uploadURLObject.uploadUrl -Method 'PUT … 2020-12-09T15:49:05.7982819Z + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2020-12-09T15:49:05.7983312Z + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc 2020-12-09T15:49:05.7983979Z eption 2020-12-09T15:49:05.7984369Z + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

 

param($ClientID,$ClientSecret,$WId,$RName,$RReqFor,$SPid,$LibId)
$tempDirectory = "temp"
# arguments defined from predefined variables in argument section of powershell stage of pipeline
$workingDirectory = "$WId"
$CLIENT_ID = "$ClientID"
$CLIENT_SECRET = "$ClientSecret"
$SharePointSiteId = "$SPid"
$LibraryId = "$LibId"
$azx = "$RName" +"_"+"$RReqFor"
$adx = ($azx.Split("[")[0])
$artifactname = $adx.Substring(0,$adx.Length-1)


# Get access token
Function GET-TOKEN 
{
    param($clientId, $clientSecret)
    $tokenHeaders = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $tokenHeaders.Add("Content-Type", "application/x-www-form-urlencoded")
    $tokenBody = "client_id="+ $clientId + "&scope=https%3A//graph.microsoft.com/.default&client_secret=" + $clientSecret + "&grant_type=client_credentials"
    $tokenBody
    $tokenResponse = Invoke-RestMethod 'https://login.microsoftonline.com/test.onmicrosoft.com/oauth2/v2.0/token' -Method 'POST' -Headers $tokenHeaders -Body $tokenBody
    return $tokenResponse    
}


# upload the file
Function UPLOAD-FILE
{
    param($workingDir, $tempDir, $clientId, $clientSecret, $artifactname)
  
    
    Get-ChildItem $workingDir | ForEach-Object {
    
    $name = $_.FullName.Split("\")[-1]
    CREATE-ARCHIVE -workingDir $_.FullName -tempDir $tempDir -name $name
    $file = $_.FullName + "\" +$tempDir + "\" + "$($name).zip"         
    
    $fileSize = (Get-Item $file).length       
    $uploadURLObject = GET-UPLOADLINK -clientId $clientId -clientSecret $clientSecret -artifactname $name
    $tokenObject = GET-TOKEN -clientId $clientId -clientSecret $clientSecret
    $uploadHeaders = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $uploadHeaders.Add("Content-Type", "application/json")
    $uploadHeaders.Add("Content-Range", "bytes " + 0 +"-" + ($fileSize-1) + "/" + $fileSize)
    $uploadHeaders.Add("Content-Length", $fileSize)
    $uploadHeaders.Add("Authorization", "Bearer "+ $tokenObject.access_token)    
    $uploadBody = [System.IO.File]::ReadAllBytes($file)
    $response = Invoke-RestMethod $uploadURLObject.uploadUrl -Method 'PUT' -Headers $uploadHeaders -Body $uploadBody
    $response | ConvertTo-Json  
    REMOVE-TEMPDIR -workingDir $_.FullName -tempDir $tempDirectory
    }
    
    
}
Function GET-UPLOADLINK
{
    param($clientId, $clientSecret, $artifactname)
    $tokenObject = GET-TOKEN -clientId $clientId -clientSecret $clientSecret
    $uploadLinkRequestHeaders = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $uploadLinkRequestHeaders.Add("Content-Type", "application/json")
    $uploadLinkRequestHeaders.Add("Authorization", "Bearer "+ $tokenObject.access_token)
    $uploadLinkRequestBody = ""     
    #update the actual link  
    $fullname = "https://graph.microsoft.com/v1.0/sites/$($SPid)/drives/$($LibId)/root/children/"    
    $comname = $fullname + $artifactname    
    $uploadLinkResponse = Invoke-RestMethod "$($comname).zip/createUploadSession" -Method 'POST' -Headers $uploadLinkRequestHeaders -Body $uploadLinkRequestBody
    $uploadLinkResponse | ConvertTo-Json
    return $uploadLinkResponse    
}

Function CREATE-ARCHIVE
{
    param($workingDir, $tempDir, $name )
    write-host $workingDir
    cd $workingDir
    md $tempDir
    #Compress-Archive -Path $workingDir -DestinationPath $workingDir\$tempDir\$artifactname
    Compress-Archive -Path $workingDir -DestinationPath $workingDir\$tempDir\$name
}

Function REMOVE-TEMPDIR
{
    param($workingDir, $tempDir)
    #This will be the last step
    rm $workingDir\$tempDir -Recurse   
}



UPLOAD-FILE -workingDir $workingDirectory -tempDir $tempDirectory -clientId $CLIENT_ID -clientSecret $CLIENT_SECRET -artifactname $artifactname
powershell

 

If your server has enabled WebDAV, have you tried robocopy? I have done that in the past. Also, make sure someone has not configured the server to block ZIP file types.

https://www.sharepointdiary.com/2013/12/blocked-file-types-in-sharepoint-2013.html

This is version dependent. The latest version of SP does not block any types by default.

@TonyD05, nothing is blocked, I am able to create and upload zip file in SharePoint from other services, it seems the zip is already an archive and hence converting an archive to an archive is not something we should do, it works fine for non.zip files. now i am looking for a way where i can directly upload the zip without creating an archive. Hope you get my point. Problem is I am unable to call the file directly here