Migrate Jira tickets to Visual Studio Online - api

I am currently investigating how to migrate our helpdesk ticket data from JIRA to Visual Studio Online. As a test I used the workflow described below to do an initial import:
Migrate backlog items from ScrumWise to Visual Studio Online?
Unfortunately this does not allow me to change fields like the CreatedDate.
The REST API documentation has a section on how to use the bypassRules parameter that is supposed to enable me to force an update. Below is a simple PowerShell script that I used to try this parameter. Unfortunately it does not seem to work for me.
$username = "<username>"
$password = "<password>"
$basicAuth = ("{0}:{1}" -f $username,$password)
$basicAuth = [System.Text.Encoding]::UTF8.GetBytes($basicAuth)
$basicAuth = [System.Convert]::ToBase64String($basicAuth)
$headers = #{Authorization=("Basic {0}" -f $basicAuth)}
$Endpoint = "https://<domain>.visualstudio.com/defaultcollection/_apis/wit/workitems/12?api-version=1.0&bypassRules=true"
$Body = '[{"op": "add", "path": "/fields/System.CreatedDate", "value":"2007-01-01T00:00:00Z"}]'
$ContentType = "application/json-patch+json"
Invoke-RestMethod -Uri $Endpoint -headers $headers -Method Patch -Body $Body -ContentType $ContentType
The request completes with a success return code but the fields are not updated.
I double checked and am certain that I'm added to the "Project Collection Services Account" group.
Update: the bypassRules parameter works when I create a new work item instead of updating one.
Is there anybody that has had a similar issue and managed to get things working for work item updates?

Related

Google Vision API Invalid operation ID format

I've been using the Google Vision API for a while now to extract text from documents (PDFs) but just came across an issue. I have created a long running job and now I need to check the job status. According to the documentation the GET request should be;
GET https://vision.googleapis.com/v1/operations/operation-id
However when trying that I get a response;
{ "error": { "code": 400, "message": "Invalid operation id format. Valid format is either projects/*/operations/* or projects/*/locations/*/operations/*", "status": "INVALID_ARGUMENT" } }
Ok, no problem, so I look through the docs and according to the message I should be able to do the following;
https://vision.googleapis.com/v1/projects/project-id/operations/1efec2285bd442df
Or;
https://vision.googleapis.com/v1/projects/project-id/locations/location-id/operations/1efec2285bd442df
My final code is a GET request using PHP Curl like so;
$url = "https://vision.googleapis.com/v1/projects/myproject-id/operations/longrunningjobid";
// create a curl request
$ch = curl_init($url);
// define the parameters
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization:Bearer $token", "Content-Type: application/json; charset=utf-8"));
// execute the request
$result = curl_exec($ch);
// close the connection
curl_close($ch);
echo $result;
I have tried several combinations of the url to try and get this to work. My gcp project id is correct and the job number is correct but I feel the url is not right. Any ideas?
The implementation was correct, however I was using regex earlier in the code and didn't realize that in PHP the \n character is escaped differently than in javascript.
So in javascript I was using \\n to escape it but in PHP I needed to use \\\n.
This was causing the longrunningjobid to have one too many characters.

Issues getting multiple user details from a person or group column in a SharePoint list with Powershell Invoke-WebRequest

I have been using PowerShell to get some site and admin details out of a SharePoint list by using Invoke-WebRequest. In the list there are 3 person or group columns, two are for the primary and secondary admins where the last is for the sites admin group and lists its members.
The issue I'm encountering is while I can expand the primary and secondary admin fields to get there names/email addresses etc. If I use the exact same thing for the admin group it comes back with a 400 error. I suspect this is due to the admin column having its allow multiple selection ticked and so I'm not expanding it correctly.
This is the Uri that works for the 2 admin columns:
site url etc./_api/web/lists(guid''siteGUID'')/items?$select=*,Secondary_x0020_Contact/EMail,Secondary_x0020_Contact/FirstName,Secondary_x0020_Contact/LastName,Primary_x0020_Contact/EMail,Primary_x0020_Contact/FirstName,Primary_x0020_Contact/LastName&$expand=Primary_x0020_Contact,Secondary_x0020_Contact
This one returns the error when I add the 3rd person column to be expanded:
site url etc./_api/web/lists(guid''siteGUID'')/items?$select=*,Secondary_x0020_Contact/EMail,Secondary_x0020_Contact/FirstName,Secondary_x0020_Contact/LastName,Primary_x0020_Contact/EMail,Primary_x0020_Contact/FirstName,Primary_x0020_Contact/LastName,Admin_x0020_Group/EMail,Admin_x0020_Group/FirstName,Admin_x0020_Group/LastName&$expand=Primary_x0020_Contact,Secondary_x0020_Contact,Admin_x0020_Group
I have also tried to just expand the admin group with out the others with this uri but it also gave the same error:
site url etc./_api/web/lists(guid''siteGUID'')/items?$select=Admin_x0020_Group/EMail,Admin_x0020_Group/FirstName,Admin_x0020_Group/LastName&$expand=Admin_x0020_Group'
As for the header etc. I'm using the following:
$headers = #{accept = "application/json;odata=verbose"}
$response = Invoke-WebRequest -Uri $uri -Headers $headers -UseDefaultCredentials
Any advice on how to get this working would be greatly appreciated.
Something you could try also is the following. Since there are several ways of using SharePoint Online. One of my favorite ways is by installing the SharePoint Online SDK. This comes with dll files which you can then add to your script. See below example script which creates a query on a certain subsite and then loops through all the results and writing out the 'Employees'-tab.
Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.UserProfiles.dll"
$UserName = "admin#yoursite.onmicrosoft.com"
$Password = "yourpassword"
$Url = "https://yoursite.sharepoint.com/subSite"
$SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force
$context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)
$listTitle = "Title of the list containing the items you want to query"
$list = $Context.Web.Lists.GetByTitle($listTitle)
$fields = $list.Fields
$qry = [Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery(10000,'ID','Created','Modified','Title','Employees')
$items = $list.GetItems($qry)
$Context.Load($fields)
$Context.Load($items)
$Context.ExecuteQuery()
foreach($item in $items){
$item.FieldValues['Employees']
}
What you see above is an example script which is able to query items from a list. In the foreach-loop I loop through all items found on the List and write out the employees tab. In my CreateAllItemsQuery I give the command to get the 'ID' the 'Title' etc. All of these values I can address after this.
Another way of querying your SharePoint Online environment is by using the webrequest:
Example to query permission information for a specific folder on a specific list which I generated by recreating this exact url when opening the folder sharing permissions:
$baseUri = "https://yoursite.sharepoint.com"
$clientId = 'YourClientId'
$clientSecret = 'YourclientSecret'
$resource = '00000002-0000-0fe2-ce00-000000000000/yoursite.sharepoint.com#7b60bad-9ab2-45d0-a2ac-c2c4ght4f7e'
$body = #{
grant_type = 'client_credentials'
client_id = $ClientId
client_secret = $ClientSecret
resource = $Resource
}
$result = Invoke-WebRequest -Method Post -Uri 'https://accounts.accesscontrol.windows.net/7b40dcad-9fe2-44d0-a0cc-c2d32f008f7e/tokens/OAuth/2' -ContentType 'application/x-www-form-urlencoded' -Body $body
$accessToken = ($result.content | ConvertFrom-Json).access_token
$headers = #{
accept = 'application/json;odata=verbose'
authorization = "Bearer $accessToken"
}
$listId = "2BD249F3-1847-4972-835S-99266DC415"
$itemId = "2"
$uri = $baseUri + "/Lists(#a1)/GetItemById(#a2)/GetSharingInformation?#a1='{$listId}'" + "&#a2='$itemId'" + '&$Expand=permissionsInformation,pickerSettings'
$result = Invoke-WebRequest -Method Post -Uri $uri -Headers $headers
($result.content | ConvertFrom-Json).d.permissionsInformation.links.results.linkDetails.Invitations.results
As you can see there are multiple ways to interact with SharePoint Online. And basically the last option is mainly looking into the requests in Developer Tools (F12) and find the exact query SharePoint does itself and replicate that URL. The first one is with the help of dll files which requires additional installation.
As you can see there are loads of options. If you aren't able to find the correct url to perform a webrequest, the first option might be interesting. It takes a lot of trial and error but I hope this helps you.

TFS API - minTime filter not working

Is there an API version level that is required for the minTime parameter to work?
GET https://{accountName}.visualstudio.com/{project}/_apis/build/builds?api-version=3.1&minTime=?????
We run TFS api ver 3.1 on premise and minTime does not seem to work for us.
It would be great to know what parameters are available for what api version.
The documentation says that 4.1 supports this parameter:
maxTime query
string
date-time
If specified, filters to builds that finished/started/queued before this date based on the queryOrder specified.
minTime query
string
date-time
If specified, filters to builds that finished/started/queued after this date based on the queryOrder specified.
Yes the minTime and maxTime parameters are supported since api-version=4.1.
Please see the REST API : Builds - List for details. It mentions all the available URI Parameters with the api-version=4.1.
In your scenario, TFS 2017 does not support the api-version=4.1. It only supports api ver 3.xx and earlier versions (1.0, 2.0). Please see REST API Versioning-Supported versions for details.
So, if you want to use the minTime and maxTime parameters you can upgrade to TFS 2018 or migrate to VSTS.
Alternately you can use other tools to filter builds by date, for example you can filter in PowerShell with calling the REST API.
Param(
[string]$baseurl = "http://server:8080/tfs/DefaultCollection",
[string]$projectName = "ProjectName",
[string]$user = "username",
[string]$token = "password"
)
# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
$uri = "$baseurl/$($projectName)/_apis/build/builds"
$result = Invoke-RestMethod -Uri $uri -Method GET -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
$builds = $result.value | Where {$_.finishTime -ge '2018-05-24' -and $_.finishTime -le '2018-05-29'} # Filter builds by finish time between '2018-05-24' and '2018-05-29'

Solarwinds API Poll Now

In the SolarWinds user interface, there is a button you can click within a switch or interface view to "Poll Now", instead of waiting for the regularly scheduled poll. I have been trying to figure out a way to recreate this functionality using the SolarWinds API. I've looked through this page, and it seems like I will need to use either the 'invoke' or 'update' operations, but there is almost no information on the actual usage. I have also tried examining the Javascript in the user interface, and can't make heads or tails of it.
I'm wondering if someone can point me towards some useful documentation as to what operations are actually available in the API (the 'invoke' operation requires you to give a 'verb' as an argument, but I can't find any kind of list or documentation as to what verbs are available). Does anyone know of any resources?
If you look at Orion.Nodes SWIS Entity you can see in the bottom "PollNow" SWIS Verb. Unfortunatelly it is not so well documented what parameters it actually has (it can be seen in SWQL Studio though). But you should be able to do it this way using Powershell:
$orionHost = "<hostname where orion is installed>"
$orionUsername = "Admin" # fill login username to orion
$orionPassword = "Pass" # fill login password to orion, this example counts that this is not empty string
$nodeIdToPoll = 1; # put id of the node
$Entity = "Orion.Nodes"
$Verb = "PollNow"
$Data = #($nodeIdToPoll)
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
$credentials = new-object PSCredential ($orionUsername , (ConvertTo-SecureString $orionPassword -AsPlainText -Force))
Invoke-RestMethod "https://$($orionHost):17778/SolarWinds/InformationService/v3/Json/Invoke/$Entity/$Verb" `
-Method POST `
-Body (ConvertTo-Json -InputObject $Data) `
-Credential $credentials `
-ContentType "application/json"

Powershell WCF Response (Headers and Cookies)

Using Powershell, how do I connect to a WCF web service using New-WebServiceProxy, and retrieve the response header information including cookie data? I have scoured the net and can't find any relevant information, other than stepping away from use of New-WebServiceProxy.
My current PS script looks like...
$authSvc = New-WebServiceProxy –Uri ‘http://myserver/Services/AuthenticationService.svc?WSDL’
$LoginResults = $true
$authSvc.Login('user1', 'abc123', $null, $true, $true, [ref] $LoginResults, [ref] $null)
... Seems there must be additional hooks into the New-WebServiceProxy that expose the header data, but I can't seem to identify it. Using C# (just a test console app), I have been able to invoke this web service and retrieve cookie data, so I know the service is functioning correctly.
Thoughts?
OK - I think I have an answer to my own question. Placing here for others trying the same thing.
The trick is to use the CookieContainer object which is intrinsic to the New-WebServiceProxy object. The CookieContainer has a CookieCollection in it. This collection can be enumerated. Elaborating on my example in the question, I show how to expose cookie information returned from the web service call...
$authSvc = New-WebServiceProxy –Uri ‘http://myserver/Services/AuthenticationService.svc?WSDL’
$authSvc.CookieContainer = New-Object System.Net.CookieContainer
$LoginResults = $true
$authSvc.Login('user1', 'abc123', $null, $true, $true, [ref] $LoginResults, [ref] $null)
$CookieCollection = $authSvc.CookieContainer.GetCookies(‘http://myserver/Services/AuthenticationService.svc?WSDL’)
foreach($cookie in $CookieCollection)
{
echo $cookie.Name
echo $cookie.Value
}
If I use the Get-Member method of the service...
$authSvc | Get-Member
... I then can see all the exposed methods the service allows. The CookieContainer happens to be one of these. Other relevant properties exposed are (but not limited to)...
ClientCertificates
Credentials
RequestEncoding
SoapVersion
Url
UserAgent