Reputation: 1
I am writing a Powershell script which will upload an Excel document to Atlassian Confluence page via REST API, using token authentication.
Write-Host "Start of script"
$userToken = "TOKEN"
$pageId = "PAGE-ID"
$fileName = "All_Employee_List.xlsx"
$rootFolder = "C:\moonfall\Powershell\Server Side\General Server Scripts"
$subFolder = "All_Employee_list\All_Employee_List_SRV_2"
$filePath = Join-Path $rootFolder $subFolder
$wpURL = "https://DOMAIN/rest/api/content/"
$Headers = @{
'Authorization' = "Bearer $userToken"
'X-Atlassian-Token' = 'nocheck'
}
# Get the attachment ID if it exists
$uri = $wpURL + $pageId + "/child/attachment?filename=$fileName&expand=body.storage,version,space,ancestors"
$attachment = Invoke-RestMethod -Method GET -Headers $Headers -Uri $uri
$attachmentId = $attachment.results.id
# If the attachment doesn't exist, create it
if (!$attachmentId) {
$uri = $wpURL + $pageId + "/child/attachment"
#after this file path check it won't upload to confluence anymore, it just says access to the path is denied
if (-not (Test-Path $filePath)) {
Write-Error "File does not exist at $filePath"
return
}
try {
$fileBytes = [System.IO.File]::ReadAllBytes(${filePath})
} catch {
Write-Error "Failed to read file at ${filePath}: $_"
return
}
$fileEncoded = [System.Convert]::ToBase64String($fileBytes)
$delimiter = [System.Guid]::NewGuid().ToString()
$LF = "`r`n"
$bodyData = (
"--$delimiter",
"Content-Disposition: form-data; name=`"file`"; filename=`"$fileName`"",
"Content-Type: application/octet-stream$LF",
$fileEncoded,
"--$delimiter--$LF"
) -join $LF
Invoke-RestMethod -Uri $uri -Method POST -ContentType "multipart/form-data; boundary=$delimiter" -Headers $Headers -Body $bodyData
Write-Output "Attachment created successfully."
} else {
Write-Output "Attachment already exists. Skipping creation."
}
# Set the attachment as the primary viewable attachment
$uri = $wpURL + $attachmentId + "/?minorEdit=true"
$bodyData = @{
"id" = $attachmentId
"version" = @{
"number" = $attachment.version.number + 1
}
"type" = "attachment"
"title" = $fileName
"container" = @{
"id" = $pageId
"type" = "page"
}
"metadata" = @{
"comment" = @{
"value" = "Automatically uploaded from PowerShell script."
}
"labels" = @()
"properties" = @{
"download" = @{
"value" = @{
"downloadAll" = "true"
}
}
}
}
"extensions" = @{
"mediaType" = @{
"value" = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
"macroEnabled" = "true"
}
}
"status" = "current"
} | ConvertTo-Json
# Make the request
$response = Invoke-RestMethod -Uri $uri -Method POST -Headers $Headers -ContentType "multipart/form-data; boundary=$delimiter" -Body $bodyData
# Print the response
$response
When I run the script in Powershell terminal with admin privileges I get the error:
Failed to read file at 'FILE-PATH': Exception calling "ReadAllBytes" with "1" argument(s): "Access to the path 'FILE-PATH' is denied.
But when I remove the file path check of $filebytes it writes a slightly different error:
Exception calling "ReadAllBytes" with "1" argument(s): "Access to the path 'C:\moonfall\Powershell\Server Side\General Server Scripts\All_Employee_list\All_Employee_List_SRV_2' is denied."
At line:29 char:5
+ $fileBytes = [System.IO.File]::ReadAllBytes($filePath)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : UnauthorizedAccessException
Exception calling "ToBase64String" with "1" argument(s): "Value cannot be null.
Parameter name: inArray"
At line:30 char:5
+ $fileEncoded = [System.Convert]::ToBase64String($fileBytes)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentNullException
results size _links
------- ---- ------
{@{id=123455572; type=attachment; status=current; title=All_Employee_List.xlsx; version=; container=; metadata=; extensions=; _links=; _expandable=}} 1 @{base=https://DOMAIN; context=}
Attachment created successfully.
Invoke-RestMethod : The remote server returned an error: (415).
At line:84 char:13
+ $response = Invoke-RestMethod -Uri $uri -Method POST -Headers $Header ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
And uploads the file as attachment to the page but the file has 0.0 kb and is nothing inside when opened. So as I see it I have two problems with this script. Please if anyone could help, this is all very much new to me and been trying to solve this for 3 weeks now and also with the help of ChatGPT.
Upvotes: 0
Views: 831
Reputation: 5351
You missed adding the file name to the file path:
$fileName = "All_Employee_List.xlsx"
$rootFolder = "C:\moonfall\Powershell\Server Side\General Server Scripts"
$subFolder = "All_Employee_list\All_Employee_List_SRV_2"
$filePath = Join-Path $rootFolder $subFolder ## File name missing?
So ReadAllBytes(${filePath})
tries to read the folder and chokes. The error message is not really accurate
Upvotes: 0