I'm using the JiraPS module and I have already raised a bug for this issue, however I'm trying to work around it. I am using Jira Cloud and have found some gaps between how Jira Server and Jira Cloud operate (namely on things like using username for server but userid for cloud). When I try to call the JiraPS function Add-JiraGroupMember
it errors out throwing a 401 (the same $credential is being passed for adding user, which doesn't fail).
However I took that function and did some tweaking to it to try to make it work:
function Add-JiraGroupMemberCloud {
[CmdletBinding( SupportsShouldProcess )]
param(
[Parameter( Mandatory, ValueFromPipeline )]
[Alias('GroupName')]
[ValidateNotNullOrEmpty()]
[Object[]]
$Group,
[Parameter( Mandatory )]
[ValidateNotNullOrEmpty()]
[Object[]]
$User,
[Parameter()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential,
[Switch]
$PassThru
)
Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
$server = Get-JiraConfigServer -ErrorAction Stop
$resourceURi = "$server/rest/api/2/group/user?groupId={0}"
foreach ($_group in $Group) {
Write-Verbose "[$($MyInvocation.MyCommand.Name)] Processing [$_group]"
Write-Debug "[$($MyInvocation.MyCommand.Name)] Processing `$_group [$_group]"
$groupObj = Get-JiraGroup -GroupName $_group -Credential $Credential -ErrorAction Stop
$groupMembers = (Get-JiraGroupMember -Group $_group -Credential $Credential -ErrorAction Stop).AccountId
if ($groupMembers -notcontains $user.AccountId) {
Write-Debug -Message "[$($MyInvocation.MyCommand.Name)] User [$($user.EmailAddress)] is not already in group [$_group]. Adding user."
$parameter = @{
URI = $resourceURi -f ($groupObj.RestURL -split ("groupID="))[1]
Method = "POST"
headers = @{'Accept'='application/json'; 'Content-Type'='application/json'}
Body = ConvertTo-Json -InputObject @{ 'accountId' = $user.AccountId }
Credential = $Credential
}
# echo "curl --request POST \`n --url $($parameter.URI) \`n --user ""$($credential.GetNetworkCredential().Username):$($credential.GetNetworkCredential().password)"" \`n --header 'Accept: application/json' \`n --header 'Content-Type: application/json' \`n --data '$($parameter.Body)'"
Write-Debug -Message "[$($MyInvocation.MyCommand.Name)] Invoking JiraMethod with `$parameter"
if ($PSCmdlet.ShouldProcess($GroupName, "Adding user '$($user.AccountId)'.")) {
Try{
$result = Invoke-RestMethod @parameter
}
Catch{
return $_
}
}
}
else {
Write-Warning -Message "User [$($user.EmailAddress)] is already a member of group [$_group]"
}
}
if ($PassThru) {
Write-Output (ConvertTo-JiraGroup -InputObject $result)
}
}
When it hits the invoke-restmethod
it does bomb out and return an error:
Invoke-RestMethod : The remote server returned an error: (401) Unauthorized.
so I added a step in there that basically builds out the call using cURL (based on the structure example in the Jira REST API docs). When I put a breakpoint in at the invoke-restmethod
, and I run the echo to get the cURL command and run it in ubuntu, it works without any issues. I cannot seem to figure out what the issue with the invoke-restmethod call is, or why it would work in cURL, but I assuming I'm doing something stupid that I'm hoping someone here can see better than I can.
By default, Invoke-RestMethod
does not perform authentication. Solutions based on your PowerShell version:
You can use the -Authentication
parameter to define an authentication method:
-Authentication
Specifies the explicit authentication type to use for the request. The default is None. The Authentication parameter can't be used with the UseDefaultCredentials parameter.
Available Authentication Options:
None
: This is the default option when Authentication is not supplied. No explicit authentication will be used.Basic
: Requires Credential. The credentials will be used to send an RFC 7617 Basic AuthenticationAuthorization: Basic
header in the format ofbase64(user:password)
.Bearer
: Requires the Token parameter. Sends an RFC 6750Authorization: Bearer
header with the supplied token.OAuth
: Requires the Token parameter. Sends an RFC 6750Authorization: Bearer
header with the supplied token.Supplying Authentication overrides any
Authorization
headers supplied to Headers or included in WebSession.This feature was added in PowerShell 6.0.0.
You have to do perform your authentication manually through the headers. Example for Basic Authentication
:
$base64Creds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Credential.UserName):$($Credential.GetNetworkCredential().Password)"))
# And then add the following key-value-pair to your headers hash table:
headers = @{Authorization="Basic $base64Creds";...