REST query through powershell - logging on issue
Hello,
I am trying to use powershell to query REST services for RTC and I want the script to logon by itself with supplied parameters. I have the following basic script, but I cannot seem to pass the password and user name to RTC and logon - any tips appreciated!! The detail returned by the web request does not seem to contain the input fields username and password I need to fill out
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
$webDetail = Invoke-WebRequest "https://server:port/ccm/web"
$webDetail.j_username ="me"
$webDetail.j_password ="pass"
$userId =$webDetail.InputFields.FindById("jazz_app_internal_LoginWidget_0_userId")
$pass = $webDetail.InputFields.FindById("jazz_app_internal_LoginWidget_0_password")
Invoke-RestMethod -Uri "https://server:port/ccm/rpt/repository/scm?fields=scm/workspace/(projectArea/name|name|stream)" -Body $webdetail | Format-Table -Property name, name, stream
5 answers
https://jazz.net/library/article/75
https://jazz.net/library/article/1086
Comments
Thanks, the j_security check technique detailed in the second article helps logon and I can create two urls one to logon and one to get the detail, which if I click on them works perfectly, but if I run the powershell I get some web page javascript rubbish not the big xml docunment I want. This is very frustrating as the same sort of thing works fine when processing JSON for the scm command output and the xml output appears in the web page, how do I avoid the "JavaScript is disabled or not available in your browser" message which seems like a completely bogus message as I can get the xml file through other means
I think you've figured it out but just for future references - the server sends back what is compatible with the "Accept" request header. So if "Accept: text/html", you get a web page, while "Accept: application/xml" will give you XML response. Note that some particular URLs return only one type of content regardless the "Accept" header.
make a request to get the sessionid needed for the seconf call. save returned cookies
if the response is Authentication required
make the correct request
use the JSessionIDSSO cookie from the 1st request
pass j_userid/j_password form variables
here is how that looks using curl
set COOKIES=.\cookies.txt
set USER=uuuu
set PASSWORD=pppppp
set HOST=https://server:port
curl -k -c %cookies% "%host%/jts/authenticated/identity" >nul
curl -k -L -b %COOKIES% -c %COOKIES% -d j_username=%USER% -d j_password=%PASSWORD% %host%/jts/authenticated/j_security_check >nul
rem -- now you are logged on if rc=200
curl -k -L -b %COOKIES% -H "Accept: application/xml" %host%/ccm/oslc/workitems/catalog
Comments
Thanks for the pointer Sam (was going to insert this answer as a comment, but ran out of space), if I am desperate I think I can run something like that within powershell but I would like to do it in a more modern fashion. I am already attempting to follow your sequence, though I expect I am making a silly error somewhere as it stubbornly refuses to work. The -SessionVariable should store the cookies in the login call and the -SessionVariable should use it. Note that you should be able to run my code on any RTC server, just substitute sever:port for something real as well as a real username and password. I think powershell and RTC can be used together very well and it should be more comfortable for most than using perl. code follows: -
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
$myConn = new-object Microsoft.PowerShell.Commands.WebRequestSession
$webDetail = Invoke-WebRequest "https://server:port/ccm/web/j_security_check?j_username=me&j_password=pass" -SessionVariable $myConn -Debug -UseBasicParsing -Method POST
$stuff =Invoke-WebRequest "https://server:port/ccm/rpt/repository/scm?fields=scm/workspace/(projectArea/name|name|stream)" -Debug -UseBasicParsing -WebSession $myConn -Method POST -ContentType "application/xml"
[xml] $thisDoc = ( New-Object System.Net.WebClient).DownloadString("https://server:port/ccm/rpt/repository/scm?fields=scm%2Fworkspace%2F%28projectArea%2Fname%7Cname%7Cstream%29")
I think I'm coming a cropper with browser warnings and security settings, which mean I never get to see the XML output and get stuck at some warning screen, or possibly more likely the initial cookies are not being transferred to the actual REST call, hoping there is someone brighter than me who can see through the issues. I can achieve this sort of thing using java, but powershell is much easier for the kind of support I have in mind here
I have no experience with powershell, so really can't help
Was almost there, just had an extra $ in my session variable and I have removed a few frigs added in desperation ;-) if you remove the occasional syntax hell, powershell is much nicer to use for XML processing than some of the methods talked about in forums and wikis, mind you its taken me a few hours to piece this together!!
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
$myConn = new-object Microsoft.PowerShell.Commands.WebRequestSession
$webDetail = Invoke-WebRequest "https://server:port/ccm/web/j_security_check?j_username=me&j_password=pass" -SessionVariable myConn -UseBasicParsing -Method POST
$stuff =Invoke-RestMethod "https://server:port/ccm/rpt/repository/scm?fields=scm/workspace/(projectArea/name|name|stream)" -WebSession $myConn -Method GET -ContentType "application/xml"
Comments
I think two of my comments has been removed, doesn't matter! If you wish to query streams in a project area and baselines in a component you are best advised to to use a combination of firing the scm command line utility, something like "list baselines..." along with simple scm REST queries. Using this along with powershell seems to be a very nice experience, well it is if you remove the two days of evaluation/ learning and guess work ;-). Note to IBM: I think you guys should write some examples using powershell, using curl and PERL is a little clunky, powershell would appear to be the future, even if you have to mess about with certificates!
I definitely think something is missing here. I do not believe this is the solution? Is it?
Using the above code does not produce the desired effect. Is it complete?
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) {
return true;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
$myConn = new-object Microsoft.PowerShell.Commands.WebRequestSession
$webDetail = Invoke-WebRequest "https://server:port/ccm/web/j_security_check?j_username=$UName&j_password=$UPwd" -SessionVariable myConn -UseBasicParsing -Method POST
$myStuff = Invoke-RestMethod "https://server:port/ccm/rpt/repository/scm?fields=scm/workspace/(projectArea/name|name|stream)" -WebSession $myConn -Method GET -ContentType "application/xml"
I can verify that I get logged into the system by looking at the #webDetail
but when looking at the $myStuff all it shows is the header info that I would see but not any data that would appear below if I put the URI directly into the Webbrowser
PS C:\> $myStuff
xml scm
--- ---
version="1.0" encoding="UTF-8" scm
It appears something is missing
It appears
xml scm
--- ---
version="1.0" encoding="UTF-8" scm
If I use another Invoke-WebRequest I can get the data but it is not formatte
$head = @{"Accept"="application/xml"}
$myStuff = Invoke-WebRequest "https://server:port/ccm/rpt/repository/generic?fields=generic/com.ibm.team.process.ProjectArea/(archived|name|itemId|internalAdmins/(userId|name|emailAddress|archived))&size=1000000" -WebSession $myConn -Method GET -Headers $head -ContentType "application/xml; charset=utf-8"
$myStuff.Content | out-file -filepath c:\scripts\mystuff.xml
Will not bring back the data in XML, it is all text and ugly