In my previous post I discussed about managing Confluence page and it’s content. This is the second part of the series. Today, I am going to share some script blocks to manage attachments in Confluence pages. Before you start, you still need to set up access on Confluence to manage pages, content,Space etc.
Let’s set base Confluence API endpoint URL first and assign it to a variable.
$ConfluenceURL = "https://<Confluence Server>/rest/api/content/"
We will also define the API URL portion to manage Attachments as shown below
$attchmentUriPath = "/child/attachment"
Now, it’s time to set Confluence Credential and Authorization Header. It will be used to make API calls with proper credentials.
$cred = Get-Credential
$Headers = @{'Authorization' = "Basic "+[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(($cred.UserName+":"+[System.Runtime.InteropServices.marshal]::PtrToStringAuto([System.Runtime.InteropServices.marshal]::SecureStringToBSTR($cred.Password)) )))
'X-Atlassian-Token' = 'nocheck'
}
Once we have set up credential and header, it is time to start working with the API to manage attachments. We will start by listing all attachments in a page and then look for a particular attachment. If we find it, we will update it with a newer updated file from my system. If it is not there already, we will upload that file as a new attachment.
With that plan, let’s start scripting…
List Attachments in Confluence Page
#Provide Page Id to find out all attachments in it
$pageId = "12345"
$attchArray = @() #Define an array to hold the list of all attachments.
$uri = "$($ConfluenceURL)$($pageId)$($attchmentUriPath)?expand=body.storage,version,space,ancestors"
$listOfAttachments = Invoke-WebRequest -Method GET -Headers $Headers -Uri $uri | ConvertFrom-Json
foreach($result in $listOfAttachments.results){
$obj = New-Object psobject
$obj | Add-Member NoteProperty id $result.id
$obj | Add-Member NoteProperty name $result.title
$attchArray += $obj
}
#Array of all attachments have been generated
So, with above script block, we have generated the list of all attachments in a Confluence page.
Check existence of an Attachment in Confluence Page
Previously, we listed all attachments in Confluence page. Now we will check if a particular file exists as an attachment on the page. It will return Boolean True or False based on the status.
$pageId = "12345" # Page id to search for attachment
$fName = "test.txt" # File name to search in the attachment list
$uri = "$($ConfluenceURL)$($pageId)$($attchmentUriPath)?expand=body.storage,version,space,ancestors"
$listOfAttachments = Invoke-WebRequest -Method GET -Headers $Headers -Uri $uri | ConvertFrom-Json
foreach($result in $listOfAttachments.results){
if($result.title -eq $fName){
return $true
}
}
return $false
Upload Attachment to Confluence Page
Let’s assume, the file we are looking for is not there in the list of attachments. So, we will upload this file to the Confluence page. As Confluence treats the file as data stream, we need to set a demarcation to let Confluence know the end of file. Pay attention to the script block where we are defining the data stream with delimiter of end of stream and line feed. You need to provide the Page Id, File name and File path at the source system. Also, this is a POST API call as we are uploading files to Confluence.
$pageId = "12345" # Page Id to upload this attachment
$fName = "test.txt" # File to attach
$fPath = "C:\TestDir\test.txt" # File path reference
$fileBytes = [System.IO.File]::ReadAllBytes($fPath);
$fileEncode = [System.Text.Encoding]::GetEncoding('UTF-8').GetString($fileBytes);
$delimiter = [System.Guid]::NewGuid().ToString();
$LF = "`r`n";
$bodyData = (
"--$delimiter",
"Content-Disposition: form-data; name=`"file`"; filename=`"$fName`"",
"Content-Type: application/octet-stream$LF",
$fileEncode,
"--$delimiter--$LF"
) -join $LF
$uri = "$($ConfluenceURL)$($pageId)$($attchmentUriPath)"
Invoke-RestMethod -Uri $uri -Method POST -ContentType "multipart/form-data; boundary=`"$delimiter`"" -Headers $Headers -Body $bodyData
Update Attachment in Confluence Page
So, now we have our file attached to Confluence Page. However, we made some changes to the file and decided to update it in Confluence too. Following script block will help you to do exactly the same. It is very much similar to upload process discussed above, just a small change to the API URL path as we have a file already exists with that name. You need to provide the attachment id to update. You can use Check existence of an Attachment in Confluence Page section. Instead of just returning Boolean value, you can return the attachment id using $result.id in that script block.
$attachmentId = "abc123" # Attachment Id to be updated
$fPath = "C:\TestDir\test.txt" # File path reference
$fName = "test.txt" # File name
$pageId = "12345" # Confluence Page Id
$fileBytes = [System.IO.File]::ReadAllBytes($fPath);
$fileEncode = [System.Text.Encoding]::GetEncoding('UTF-8').GetString($fileBytes);
$delimiter = [System.Guid]::NewGuid().ToString();
$LF = "`r`n";
$bodyData = (
"--$delimiter",
"Content-Disposition: form-data; name=`"file`"; filename=`"$fName`"",
"Content-Type: application/octet-stream$LF",
$fileEncode,
"--$delimiter--$LF"
) -join $LF
$attchmentIdUriPath = "/child/attachment/$attachmentId/data"
$uri = "$($ConfluenceURL)$($pageId)$($attchmentIdUriPath)"
Invoke-RestMethod -Uri $uri -Method POST -ContentType "multipart/form-data; boundary=`"$delimiter`"" -Headers $Headers -Body $bodyData
Delete Attachment from Confluence Page
So far, we have performed create, update, list operations on Attachments in a Confluence page. Finally, we will complete this post with a Delete operation of Attachments. This is a very straight forward operation.We will implement a DELETE method while making API call. You need to provide Attachment Id to delete along with the Page Id.
$pageId = "12345" # Confluence Page id
$attachmentId = "abc123" # Attachment Id to delete
$attchmentIdUriPath = "/child/attachment/$attachmentId"
$uri = "$($ConfluenceURL)$($pageId)$($attchmentIdUriPath)"
Invoke-WebRequest -Method DELETE -Headers $Headers -Uri $uri | ConvertFrom-Json
That’s it. You should be able to manage Confluence attachments using Powershell and Confluence API after going through this post.