PowerShell command to trigger Jenkins job throws Authentication error - powershell

$Auth = "admin:password"
$JenkinsURL = "http://$Auth#172.24.235.27:8080/"
$JobName = "TestItem1"
$JobToken = "token"
$FullURL = "$JenkinsURL/job/$JobName/build?token=$JobToken"
Invoke-WebRequest -UseBasicParsing $FullURL
Above is the PowerShell code used for triggering Jenkins job. But while executing this I am facing "Authentication required" error. But the same command from curl is working fine.
I am not sure whether I am missing something in URL or missing some Jenkins plugin to provide access from PowerShell.

The reason you are getting an authentication error is that you will need to convert the authentication to base 64 string. Below is the script that you can use if you have not enabled the CSRF in Jenkins.
$UserName = "admin"
$Password = "password"
$API_URL = "jenkinsservername"
$JobName = "TestItem1"
$JobToken = "token"
$header = #{}
$Params = #{}
$header.Add('Authorization', 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$(${UserName}):$(${Password})")))
$Params['uri'] = "http://jenkinsservername/$JobName/build?token=$JobToken"
$Params['Method'] = 'Post'
$Params['Headers'] = $header
Invoke-RestMethod #Params
But If you have CSRF Enabled in Jenkins then use below script
$UserName = "admin"
$Password = "password"
$API_URL = "jenkinsservername"
$JobName = "TestItem1"
$JobToken = "token"
$header = #{}
$header.Add('Authorization', 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$(${UserName}):$(${Password})")))
$Params = #{uri = "http://${API_URL}:${API_Port}/crumbIssuer/api/json";
Method = 'Get';
Headers = $header;}
$API_Crumb = Invoke-RestMethod #Params
write-host $API_Crumb
$h.Add('Jenkins-Crumb', $API_Crumb.crumb)
$Params['uri'] = "http://jenkinsservername/$JobName/build?token=$JobToken"
$Params['Method'] = 'Post'
$Params['Headers'] = $header
Invoke-RestMethod #Params

#Mike correctly described the instructions for working with the jenkins api when using CSRF. But I would like to add that when creating crumbs, the session and cookies are also taken into account.
The code that works for me is as follows:
$UserName = "admin"
$Password = "password"
$API_URL = "jenkinsservername"
$JobName = "TestItem1"
$JobToken = "token"
$header = #{}
$header.Add('Authorization', 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$(${UserName}):$(${Password})")))
$Params1 = #{uri = "http://${API_URL}:${API_Port}/crumbIssuer/api/json";
Method = 'Get';
SessionVariable = 'Session';
Headers = $header;}
$API_Crumb = Invoke-RestMethod #Params1
write-host $API_Crumb
$header.Add('Jenkins-Crumb', $API_Crumb.crumb)
$Params2 = #{}
$Params2['uri'] = "http://jenkinsservername/$JobName/build?token=$JobToken"
$Params2['Method'] = 'Post'
$Params2['Headers'] = $header
Invoke-RestMethod #Params2 -WebSession $Session
Also consider if the job is in a folder, then the uri will be different.
For example, if MyJob is in MyFolder then the uri will be:
http://jenkinsservername/job/MyFolder/job/MyJob/build?token=JobToken
You can see this path in the place where you assigned the token for the job

Related

Elasticsearch [6.8] REST with PowerShell create snapshot failed to authenticate user

I'm creating PS script to automate creating snapshots of selected indices. This is my code:
# Input variables
$elastic_host = "localhost:9200";
$repo_name = "daily_backup";
$username = "elastic";
$password = "elastic";
$indices = "kibana_sample_*,test";
# Create repo if not exists
$url_put_repo = "http://$elastic_host/_snapshot/$repo_name";
$body_put_repo = #{
"type" = "fs";
"settings" = #{
"location" = "$($repo_name)_location";
"compress" = $True;
"chunk_size" = "100MB";
}
} | ConvertTo-Json;
Write-Host (Invoke-ElasticSearch $url_put_repo $username $password $body_put_repo);
# Create snapshot
$time_stamp = Get-Date -Format "yyyyMMddHHmmss";
$url_put_snapshot = "http://$elastic_host/_snapshot/$repo_name/$($time_stamp)?wait_for_completion=true";
$body_put_snapshot = #{
"indices" = $indices;
"ignore_unavailable" = $True;
"include_global_state" = $False;
} | ConvertTo-Json;
Write-Host (Invoke-ElasticSearch $url_put_snapshot $username $password, $body_put_snapshot);
function Invoke-ElasticSearch([string]$url, [string]$user, [string]$pass, [string]$body) {
$credPair = "$($user):$($pass)";
$encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($credPair));
$headers = #{
"Authorization" = "Basic $encodedCredentials";
"Content-Type" = "application/json";
};
$responseData = Invoke-WebRequest -Uri $url -Method Put -Headers $headers -Body $body -UseBasicParsing -Verbose;
return $responseData;
}
Problem is that first part is working "Create repo if not exists", second part "Create snapshot" is failing:
Invoke-WebRequest : {"error":{"root_cause":[{"type":"security_exception","reason":"failed to authenticate user [elastic]","header":{"WWW-Authenticate":"Basic realm=\"security\" charset=
\"UTF-8\""}}],"type":"security_exception","reason":"failed to authenticate user [elastic]","header":{"WWW-Authenticate":"Basic realm=\"security\" charset=\"UTF-8\""}},"status":401}
When I call Invoke-ElasticSearch with no body it is not failing:
Invoke-ElasticSearch $url_put_snapshot $username $password, $body_put_snapshot
I tried this JSON in Kibana Dev Tools and it is working - I don't know where is problem. Any idea?
It was typo ofcourse...
Before:
Invoke-ElasticSearch $url_put_snapshot $username $password, $body_put_snapshot
After:
Invoke-ElasticSearch $url_put_snapshot $username $password $body_put_snapshot

How to get login status of any website using powershell

i am trying to get login status of any website using passed parameter, My below script is returning always status code = 200 irrespective of wrong username/password.
Can anyone guide me pls?
$url = "{url here}"
$username = "{username here}"
$password = "{password here}"
$b = [System.Text.Encoding]::UTF8.GetBytes($username + ":" + $password)
$p = [System.Convert]::ToBase64String($b)
$creds = "Basic " + $p
$req1 = Invoke-WebRequest -Uri $url -Headers #{"Authorization" = $creds }
$StatusCode = [int] $req1.StatusCode;
$StatusDescription = $req1.StatusDescription;
write-host $StatusCode
write-host $StatusDescription

Unauthorized status while accessing Cosmos Db Collection Documents in power shell

I am trying to access azure cosmos db account collection documents and also each document in collection. I had referred below link and changed all necessary cosmos db values like databaseid,container,itemid master key etc.,
Link:
https://github.com/Azure/azure-cosmos-dotnet-v3/blob/master/Microsoft.Azure.Cosmos.Samples/Usage/PowerShellRestApi/PowerShellScripts/ReadItem.ps1
But i am getting below error while running in Powershell.
Error:
StatusCode: 401
Exception Message: The remote server returned an error: (401) Unauthorized.
System.Net.WebException: The remote server returned an error: (401) Unauthorized.
at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.GetResponse(WebRequest request)
at Microsoft.PowerShell.Commands.WebRequestPSCmdlet.ProcessRecord()
NOTE: When i tried same in postman, i am getting list of documents but when i tried to get specific document . I am getting below error.
Error:
The input authorization token can't serve the request. Please check that the expected payload is built as per the protocol, and check the key being used. Server used the following payload to sign:
FYI: I am contributor role for Cosmodb account in azure portal
Parameters:
$endpoint = "https://testcosmos.documents.azure.com:443/"
$MasterKey = "<Key from Cosmos db account>"
$KeyType = "master"
$TokenVersion = "1.0"
$date = Get-Date
$utcDate = $date.ToUniversalTime()
$xDate = $utcDate.ToString('r',
[System.Globalization.CultureInfo]::InvariantCulture)
$databaseId = "testdb"
$containerId = "containercollection"
$itemResourceType = "docs"
$ItemId="1"
$itemResourceId = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs/"
$itemResourceLink = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs/"
$verbMethod = "GET"
$header = #{
"authorization" = "$authKey";
"x-ms-version" = "2018-12-31";
"Cache-Control" = "no-cache";
"x-ms-date" = "$xDate"
"Accept" = "application/json";
"User-Agent" = "PowerShell-RestApi-Samples";
"x-ms-documentdb-partitionkey" = '["testPK"]'
}
I had tried commenting "Accept","User-Agent", Cache-Control header options but in vain.
I also tried just getting only list of /docs without itemID but that also went in vain.
$result = Invoke-RestMethod -Uri $requestUri -Headers $header -Method $verbMethod -ContentType "application/json"
Write-Host "Read item response = "$result
Updated Code: I finally able to understand why issue is coming. its neither authentication issue nor resourceID. I am passing partition key in headers which is not hard coded as per sample . When i am passing value to partition key, it was not taking correctly hence causing issue. Below is my dynamic Code passing partition key
"x-ms-documentdb-partitionkey" = '["$Partitionkey"]' -- Displaying as
[$Partitionkey] but it must print in headers like ["partitionkeyValue"]
Am trying how to fix that. Many many thanks for your suggestions.
Firstly, i could query my item successfully with github code as same as #Gaurav Mantri. Your error code is 401 auth issue,so I assume that you make some mistakes with generation of MasterKeyAuthorizationSignature,especially the value of $itemResourceId.Please refer to the REST API document.
2 parts:
1.Query a specific item:
$itemId = "1"
$itemResourceType = "docs"
$itemResourceId = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs/"+$ItemId
$itemResourceLink = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs/"+$ItemId
2.List items in a specific colletion:
No #itemId
$itemResourceId = "dbs/"+$databaseId+"/colls/"+$containerId
$itemResourceLink = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs/"
I tried the following code and it worked well for me. I was able to fetch the document details:
Add-Type -AssemblyName System.Web
Function Generate-MasterKeyAuthorizationSignature{
[CmdletBinding()]
param (
[string] $Verb,
[string] $ResourceId,
[string] $ResourceType,
[string] $Date,
[string] $MasterKey,
[String] $KeyType,
[String] $TokenVersion
)
$keyBytes = [System.Convert]::FromBase64String($MasterKey)
$sigCleartext = #($Verb.ToLower() + "`n" + $ResourceType.ToLower() + "`n" + $ResourceId + "`n" + $Date.ToString().ToLower() + "`n" + "" + "`n")
Write-Host "sigCleartext = " $sigCleartext
$bytesSigClear = [Text.Encoding]::UTF8.GetBytes($sigCleartext)
$hmacsha = new-object -TypeName System.Security.Cryptography.HMACSHA256 -ArgumentList (, $keyBytes)
$hash = $hmacsha.ComputeHash($bytesSigClear)
$signature = [System.Convert]::ToBase64String($hash)
$key = [System.Web.HttpUtility]::UrlEncode('type='+$KeyType+'&ver='+$TokenVersion+'&sig=' + $signature)
return $key
}
$endpoint = "https://account-name.documents.azure.com:443/"
$MasterKey = "account-key"
$KeyType = "master"
$TokenVersion = "1.0"
$date = Get-Date
$utcDate = $date.ToUniversalTime()
$xDate = $utcDate.ToString('r', [System.Globalization.CultureInfo]::InvariantCulture)
$databaseId = "MyDatabaseId"
$containerId = "MyContainerId"
$itemId = "TestItem"
$itemResourceType = "docs"
$itemResourceId = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs/"+$ItemId
$itemResourceLink = "dbs/"+$databaseId+"/colls/"+$containerId+"/docs/"+$ItemId
$verbMethod = "GET"
$requestUri = "$endpoint$itemResourceLink"
$authKey = Generate-MasterKeyAuthorizationSignature -Verb $verbMethod -ResourceId $itemResourceId -ResourceType $itemResourceType -Date $xDate -MasterKey $MasterKey -KeyType $KeyType -TokenVersion $TokenVersion
$header = #{
"authorization" = "$authKey";
"x-ms-version" = "2018-12-31";
"Cache-Control" = "no-cache";
"x-ms-date" = "$xDate";
"Accept" = "application/json";
"User-Agent" = "PowerShell-RestApi-Samples";
"x-ms-documentdb-partitionkey" = '["testPk"]'
}
try {
$result = Invoke-RestMethod -Uri $requestUri -Headers $header -Method $verbMethod -ContentType "application/json"
Write-Host "Read item response = "$result
return "ReadItemSuccess";
}
catch {
# Dig into the exception to get the Response details.
# Note that value__ is not a typo.
Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
Write-Host "Exception Message:" $_.Exception.Message
echo $_.Exception|format-list -force
}
UPDATE
Regarding your comment about dynamically specifying the partition key value, try something like the following:
"x-ms-documentdb-partitionkey" = '["' + $Partitionkey + '"]'

Why is PowerShell not able to send proper Crumb?

My PowerShell script:
$Params = #{
uri = "http://${API_URL}:${API_Port}/crumbIssuer/api/json";
Method = 'Get';
Headers = #{
Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$(${API_User}):$(${API_Pass})"));
}
}
$API_Crumb = Invoke-RestMethod #Params
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Jenkins-Crumb", $API_Crumb.Crumb)
$Params = #{
uri = "http://${API_URL}:${API_Port}/job/${API_Job}/build";
Method = 'Post';
Headers = $headers;
}
Invoke-RestMethod #Params
Error:
No valid crumb was included in the request
I modified the code as follows and it worked. Not sure though why previous code was throwing error.
$API_User = "admin"
$API_Pass = "password"
$API_URL = "localhost"
$API_Port = "8080"
$API_Job = "test01"
$h = #{}
$h.Add('Authorization', 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$(${API_User}):$(${API_Pass})")))
$Params = #{uri = "http://${API_URL}:${API_Port}/crumbIssuer/api/json";
Method = 'Get';
Headers = $h;}
$API_Crumb = Invoke-RestMethod #Params
$h.Add('Jenkins-Crumb', $API_Crumb.crumb)
$Params['uri'] = "http://${API_URL}:${API_Port}/job/${API_Job}/build"
$Params['Method'] = 'Post'
$Params['Headers'] = $h
Invoke-RestMethod #Params

Jira user creation via REST results in 401 - This resource requires WebSudo

I'm attempting to write a PowerShell script that will automate the process of adding new user accounts to our Jira instance. I've provided my code but I'm honestly not even getting to that point as I am receiving a 401 error:
This resource requires WebSudo.
I have seen these two posts on the Jira support forum but it's not clear to me how I could adapt the code to get and then apply it to my REST call. I would be fine with changing this to use the .Net WebClient class if that would make all of this easier, but right now I'm at a bit of a loss.
$url = "https://devjira.domain.com/rest/api/2/user"
$user = "admin"
$pass = "super secure password"
$secpasswd = ConvertTo-SecureString $user -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($pass, $secpasswd);
$userObject = #{
name = "rkaucher#domain.net";
emailAddress = "robert_kaucher#domain.com";
displayName = "Bob Kaucher";
notification = $true;
}
$restParameters = #{
Uri = $url;
ContentType = "application/json";
Method = "POST";
Body = (ConvertTo-Json $userObject).ToString();
Credential = $cred;
}
Invoke-RestMethod #restParameters
JSON output
{
"name": "rkaucher#domain.net",
"displayName": "Bob Kaucher",
"emailAddress": "robert_kaucher#domain.com",
"notification": true
}
I changed the authentication component of my script to this:
$cred = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$user`:$pass"))
$headers = #{Authorization=("Basic $cred")}
This was based on the selected answer to the following:
PowerShell's Invoke-RestMethod equivalent of curl -u (Basic Authentication)
The final invocation of the method looks like this:
$restParameters = #{
Uri = $url;
ContentType = "application/json";
Method = "POST";
Body = (ConvertTo-Json $userObject).ToString();
Headers = $headers;
}
$response = Invoke-RestMethod #restParameters