Create Work Items In Visual Studio Team Services Using PowerShell

Introduction

During a PowerShell session at my workplace, a colleague asked me an interesting question - How can I create work items in VSTS using PowerShell?  This triggered me to share a TechNet wiki article. For me, Visual Studio Team Services was a foreign matter until I tried my hands on it to gain knowledge and experience.
 
Requirement

Team has a source file in CSV, XML, or JSON format and need an interface which connects to team project and create work items.
 
Solution

As a PowerShell enthusiast, I opted to use Visual Studio Team Services REST API with PowerShell to accomplish the task and selected Personal Access Token (PAT) authentication mechanism for demo purpose.
 
Create a Personal Access Token
  1. Sign in to either of your Visual Studio Team Services accounts (https://{youraccount}.visualstudio.com)
  2. From your home page, open your profile (hover on top your profile badge). Go to your security details.
  3. In the left pane, choose Personal Access Token.
  4. Click Add and name your token.
  5. Choose the life span for your token. Default is 90 days.
Convert Personal Access Token to Base64 String

With reference to the document, I developed a nifty PowerShell snippet shared below to convert the Personal Access Token to Base 64 string.  
  1. $Token = "Personal Access Token"  
  2. $Authentication = [Text.Encoding]::ASCII.GetBytes(":$Token")  
  3. $Authentication = [System.Convert]::ToBase64String($Authentication)  
  4. $Headers = @{  
  5. Authorization = ("Basic {0}" -f $Authentication)  
  6. }  
  7. $Headers.Authorization  
  8. 2/4  
  9. # Output(Sample)  
  10. Basic PAT1234ID=  
REST API Endpoint URL
  1. PATCH https://{instance}/DefaultCollection/{project}/_apis/wit/workitems/${workItemTypeName}?api-version={version}  
Sample Code
  1. $values = Import - csv C: \Source\ WIT.csv  
  2. foreach($value in $values) {  
  3.     $RestParams = @ {  
  4.         Uri = "https://{account}/Automation/_apis/wit/workitems/`$product backlog item?apiversion=1.0"  
  5.         ContentType = 'application/json-patch+json'  
  6.         Headers = @ {  
  7.             Authorization = ("Basic {0}" - f $authentication)  
  8.         }  
  9.         Method = "Patch"  
  10.         Body = @(@ {  
  11.                 op = "add"  
  12.                 path = "/fields/System.Title"  
  13.                 value = $value.value  
  14.             }  
  15.             @ {  
  16.                 op = "add"  
  17.                 path = "/fields/System.AreaPath"  
  18.                 value = "Automation\Automation Scrum"  
  19.             }  
  20.             @ {  
  21.                 op = "add"  
  22.                 path = "/fields/System.IterationPath"  
  23.                 value = "Automation\FY18-M01_JULY"  
  24.             }  
  25.             @ {  
  26.                 op = "add"  
  27.                 path = "/fields/System.AssignedTo"  
  28.                 value = $value.technician  
  29.             }) | ConvertTo - Json  
  30.     }  
  31.     try {  
  32.         Invoke - RestMethod @RestParams - Verbose  
  33.     } catch {  
  34.         $_.Exception.Message  
  35.     }  
  36. }