jiralib.ps1 Powershell library
# File: jiralib.ps1
# Startdate: 2020-06-23 08:59
# Dependencies:
# credlib.ps1
. "scripts\Functions\credlib.ps1"
$jiraCloudCred = Get-Shared-Credential -User "bgstack15@example.com" -PasswordCategory "jira-cloud-api-token-bgstack15"
${global:CloudHeaders} = Get-Basic-Base64-Auth-Headers -Credential $jiraCloudCred
Function List-Attachments-On-Issue {
[CmdletBinding(SupportsShouldProcess)]
Param(
[Parameter(Mandatory = $False)][string]$Server = "example.atlassian.net",
[Parameter(Mandatory = $True) ][string]$Issue,
[Parameter(Mandatory = $False)][Hashtable]$cloudHeaders = ${global:cloudHeaders}
)
Process {
$result = Invoke-RestMethod -Headers $cloudHeaders -Uri "https://${Server}/rest/api/3/issue/${Issue}" -ContentType "application/json"
$results = $result.fields.attachment
$results
}
}
# Usage: List-Attachments-On-Issue -Issue "PROJ-2" | Download-Attachments -OutDirectory "C:\Output"
Function Download-Attachments {
[CmdletBinding(SupportsShouldProcess)]
Param(
[Parameter(Mandatory = $False,ValueFromPipeLine = $true,ValueFromPipelineByPropertyName = $true)]$Attachments,
[Parameter(Mandatory = $False) ][string]$OutDirectory = ".",
[Parameter(Mandatory = $False)][Hashtable]$cloudHeaders = ${global:cloudHeaders},
[Parameter(Mandatory = $False)][Boolean]$ShowCount = $False
)
Begin {
$count = 0
}
Process {
# for each item from List-Attachments-On-Issue
$OutFile = "$($OutDirectory)\$($_.filename)" -Replace "\\\\","\"
# Assumes that directory already exists.
#Write-Host "Save $($_.content) as file $($OutFile)"
If ($PsCmdlet.ShouldProcess("$($_.content)")) {
Invoke-WebRequest -Headers $cloudHeaders -uri $_.content -OutFile $OutFile -Verbose:$false
$count += 1
}
}
End {
If ($ShowCount) { Write-Verbose "Saved $count items" }
}
}
Function Retrieve-Attachments-To-Subdir {
[CmdletBinding(SupportsShouldProcess)]
Param(
[Parameter(Mandatory = $False)][string]$Server = "example.atlassian.net",
[Parameter(Mandatory = $True) ][string]$Issue,
[Parameter(Mandatory = $False)][string]$ParentDirectory = ".",
[Parameter(Mandatory = $False)][Hashtable]$cloudHeaders = ${global:cloudHeaders},
[Parameter(Mandatory = $False)][switch]$LongForm = $False
)
Process {
$OutDir = "$($ParentDirectory)\$($Issue)" -Replace "\\\\","\"
If ($LongForm) {
$Name = ($Issue -Split "-")[0]
$Number = ($Issue -Split "-")[-1]
# the "{0:d4}" -f $Number syntax did not work when in a script for some reason.
# but this does: https://devblogs.microsoft.com/scripting/understanding-powershell-and-basic-string-formatting/
# using floor https://stackoverflow.com/questions/5863772/powershell-round-down-to-nearest-whole-number/5864061#5864061
$n5 = [string]::Format("{0:d5}",[int]$Number)
$n3 = [string]::Format("{0:d5}",[int]([math]::floor([decimal]($n5/100)))*100)
$n2 = [string]::Format("{0:d5}",[int]([math]::floor([decimal]($n5/1000)))*1000)
$n1 = [string]::Format("{0:d5}",[int]([math]::floor([decimal]($n5/10000)))*10000)
$OutDir = "${Name}\${n1}\${n2}\${n3}\${n5}"
}
If ($ParentDirectory -ne ".") {
$Prompt = "Save $($Issue) to $($ParentDirectory)\$($OutDir)"
} Else {
$Prompt = "Save $($Issue) to $($OutDir)"
}
If ($PsCmdlet.ShouldProcess($Prompt)) {
If (!(Test-Path "$($ParentDirectory)\$($OutDir)")) { New-Item -ItemType Directory -Path "$($ParentDirectory)\$($OutDir)" | Out-Null ; }
List-Attachments-On-Issue -Server $Server -Issue $Issue -cloudHeaders $cloudHeaders -Verbose:$False | Download-Attachments -OutDirectory "$($ParentDirectory)\$($OutDir)" -cloudHeaders $cloudHeaders -Confirm:$False -ShowCount $True
# and now clean up any empty dirs
# from https://stackoverflow.com/questions/28631419/how-to-recursively-remove-all-empty-folders-in-powershell/28631669#28631669
Do {
$dirs = Get-ChildItem $ParentDirectory -Directory -Recurse | ? { (Get-ChildItem $_.fullName -Force).count -eq 0 } | Select -ExpandProperty FullName
$dirs | Foreach-Object { Remove-Item $_ -Confirm:$false -Verbose:$False }
} While ($dirs.count -gt 0)
}
}
}
# This is the main function for pulling all attachments for tickets listed in a csv in one column, named nothing in particular
# Import-CSV "tickets.csv" | Retrieve-All-Attachments -ParentDirectory "C:\Output"
Function Retrieve-All-Attachments {
[CmdletBinding(SupportsShouldProcess)]
Param(
[Parameter(Mandatory = $False)][string]$Server = "example.atlassian.net",
[Parameter(Mandatory = $False,ValueFromPipeLine = $true,ValueFromPipelineByPropertyName = $true)]$Issues,
[Parameter(Mandatory = $False)][string]$ParentDirectory = ".",
[Parameter(Mandatory = $False)][Hashtable]$cloudHeaders = ${global:cloudHeaders}
)
Process {
# CSV only needs one column, so a plaintext file would do, if Import-Csv works.
# learn column name
$ColumnName = ($_ | gm -Type NoteProperty).Name
$_ | % {
$Ticket = "$($_.$($ColumnName))"
#Write-Host "Do something with $($Ticket)"
#Write-Host "Retrieve-Attachments-To-Subdir -Server $Server -Issue $Ticket -ParentDirectory $ParentDirectory -LongForm -cloudHeaders $cloudHeaders"
Retrieve-Attachments-To-Subdir -Server $Server -Issue $Ticket -ParentDirectory $ParentDirectory -LongForm -cloudHeaders $cloudHeaders -Verbose
}
}
}
I was writing a process to download Jira issue attachments and upload them to Sharepoint in a directory structure.
Comments