It's easy to use Excel add-ins or extensions from marketplace to export the work items, right? Then why build a script in PowerShell?
To answer this in short, I manage multiple instances for multiple projects so I use PowerShell, which is a quick way for me to explore work items in one go!
Comments
  1. <#
  2. .SYNOPSIS
  3. A PowerShell function to export Visual Studio Team Servies work items.
  4. .DESCRIPTION
  5. A PowerShell function to export Visual Studio Team Servies work items.
  6. .EXAMPLE
  7. PS C:\> Export-VSTSWorkItem -Instance "Fabrikam" -Token "PAT -WorkItemType Bug
  8. Yields all the bugs in from the work items table.
  9. .EXAMPLE
  10. PS C:\> Export-VSTSWorkItem -Instance "Fabrikam" -Token "PAT" -WorkItemType Task
  11. Yields all the task in from the work items table.
  12. .EXAMPLE
  13. PS C:\> Export-VSTSWorkItem -Instance "Fabrikam" -Token "PAT" -WorkItemType Epic
  14. Yields all the epic in from the work items table.
  15. .EXAMPLE
  16. PS C:\> Export-VSTSWorkItem -Instance "Fabrikam" -Token "PAT" -WorkItemType Epic -ExportAs Csv
  17. Exports information as csv
  18. .EXAMPLE
  19. PS C:\> Export-VSTSWorkItem -Instance "Fabrikam" -Token "PAT" -WorkItemType Epic -ExportAs FancyHtml
  20. Exports information as a fancy html
  21. .NOTES
  22. @ChendrayanV
  23. #>
Parameters are my best friend as always,
  1. param (
  2. # Visual Studio Team Services Account Name
  3. [Parameter(Mandatory)]
  4. $Instance,
  5. # Create a Personal Access Token
  6. [Parameter(Mandatory)]
  7. $Token,
  8. # Opt the Work Items Type. (Modify as required)
  9. [Parameter(Mandatory)]
  10. [ValidateSet('Bug', 'Task', 'Epic', 'Feature')]
  11. $WorkItemType,
  12. # Export in your favorite format.
  13. [Parameter()]
  14. [ValidateSet('Csv', 'HTML', 'FancyHTML')]
  15. $ExportAs
  16. )
We use a personal access token so it's a must to convert the token to base 64 string. As a system admin, it took some time for me to understand but the below snippet makes it happen.
  1. $Authentication = (":$Token")
  2. $Authentication = [System.Text.Encoding]::ASCII.GetBytes($Authentication)
  3. $Authentication = [System.Convert]::ToBase64String($Authentication)
Using switch statement, modify the WIQL as illustrated below.
  1. switch ($WorkItemType)
  2. {
  3. "Bug"
  4. {
  5. $Body = @{
  6. Query = "Select * from WorkItems WHERE [System.WorkItemType] = '$WorkItemType'"
  7. } | ConvertTo-Json
  8. }
  9. "Task"
  10. {
  11. $Body = @{
  12. Query = "Select * from WorkItems WHERE [System.WorkItemType] = '$WorkItemType'"
  13. } | ConvertTo-Json
  14. }
  15. "Epic"
  16. {
  17. $Body = @{
  18. Query = "Select * from WorkItems WHERE [System.WorkItemType] = '$WorkItemType'"
  19. } | ConvertTo-Json
  20. }
  21. "Feature"
  22. {
  23. $Body = @{
  24. Query = "Select * from WorkItems WHERE [System.WorkItemType] = '$WorkItemType'"
  25. } | ConvertTo-Json
  26. }
  27. }
Simply, we are converting the hash table to JSON using ConvertTo-Json cmdlet and with no more theory, below is the full script!
  1. function Export-VSTSWorkItem
  2. {
  3. <#
  4. .SYNOPSIS
  5. A PowerShell function to export Visual Studio Team Servies work items.
  6. .DESCRIPTION
  7. A PowerShell function to export Visual Studio Team Servies work items.
  8. .EXAMPLE
  9. PS C:\> Export-VSTSWorkItem -Instance 'Fabrikam' -Token "PAT" -WorkItemType Bug
  10. Yields all the bugs in from the work items table.
  11. .EXAMPLE
  12. PS C:\> Export-VSTSWorkItem -Instance 'Fabrikam' -Token "PAT" -WorkItemType Task
  13. Yields all the task in from the work items table.
  14. .EXAMPLE
  15. PS C:\> Export-VSTSWorkItem -Instance 'Fabrikam' -Token "PAT" -WorkItemType Epic
  16. Yields all the epic in from the work items table.
  17. .EXAMPLE
  18. PS C:\> Export-VSTSWorkItem -Instance 'Fabrikam' -Token "PAT" -WorkItemType Epic -ExportAs Csv
  19. Exports information as csv
  20. .EXAMPLE
  21. PS C:\> Export-VSTSWorkItem -Instance 'Fabrikam' -Token "PAT" -WorkItemType Epic -ExportAs FancyHtml
  22. Exports information as a fancy html
  23. .NOTES
  24. @ChendrayanV
  25. #>
  26. [CmdletBinding()]
  27. param (
  28. # Visual Studio Team Services Account Name
  29. [Parameter(Mandatory)]
  30. $Instance,
  31. # Create a Personal Access Token
  32. [Parameter(Mandatory)]
  33. $Token,
  34. # Opt the Work Items Type. (Modify as required)
  35. [Parameter(Mandatory)]
  36. [ValidateSet('Bug', 'Task', 'Epic', 'Feature')]
  37. $WorkItemType,
  38. # Export in your favorite format.
  39. [Parameter()]
  40. [ValidateSet('Csv', 'HTML', 'FancyHTML')]
  41. $ExportAs
  42. )
  43. begin
  44. {
  45. }
  46. process
  47. {
  48. $Authentication = (":$Token")
  49. $Authentication = [System.Text.Encoding]::ASCII.GetBytes($Authentication)
  50. $Authentication = [System.Convert]::ToBase64String($Authentication)
  51. switch ($WorkItemType)
  52. {
  53. "Bug"
  54. {
  55. $Body = @{
  56. Query = "Select * from WorkItems WHERE [System.WorkItemType] = '$WorkItemType'"
  57. } | ConvertTo-Json
  58. }
  59. "Task"
  60. {
  61. $Body = @{
  62. Query = "Select * from WorkItems WHERE [System.WorkItemType] = '$WorkItemType'"
  63. } | ConvertTo-Json
  64. }
  65. "Epic"
  66. {
  67. $Body = @{
  68. Query = "Select * from WorkItems WHERE [System.WorkItemType] = '$WorkItemType'"
  69. } | ConvertTo-Json
  70. }
  71. "Feature"
  72. {
  73. $Body = @{
  74. Query = "Select * from WorkItems WHERE [System.WorkItemType] = '$WorkItemType'"
  75. } | ConvertTo-Json
  76. }
  77. }
  78. $RestParams = @{
  79. Uri = "https://$Instance.visualstudio.com/DefaultCollection/_apis/wit/wiql?api-version=1.0"
  80. Method = "Post"
  81. ContentType = "application/json"
  82. Headers = @{
  83. Authorization = ("Basic {0}" -f $Authentication)
  84. }
  85. Body = $Body
  86. }
  87. try
  88. {
  89. $Id = (Invoke-RestMethod @RestParams).workitems.id -join ","
  90. if ($Id -ne $null)
  91. {
  92. $Fields = @('System.Id', 'System.Title', 'System.AssignedTo',
  93. 'System.State', 'System.CreatedBy', 'System.WorkItemType') -join ","
  94. $RestParams["Uri"] = "https://$Instance.visualstudio.com/DefaultCollection/_apis/wit/WorkItems?ids=$Id&fields=$Fields&api-version=1"
  95. $RestParams["Method"] = "Get"
  96. $RestParams.Remove("Body")
  97. $Result = Invoke-RestMethod @RestParams
  98. if (! $PSBoundParameters['ExportAs'])
  99. {
  100. ($Result.value.fields)
  101. }
  102. }
  103. else
  104. {
  105. Write-Warning "No Items are available in $WorkItemType"
  106. }
  107. switch ($ExportAs)
  108. {
  109. 'csv'
  110. {
  111. $Result.value.fields | Export-Csv .\WITReport.csv -NoTypeInformation
  112. }
  113. 'HTML'
  114. {
  115. $Result.value.fields | Export-Csv .\WITReport.html -NoTypeInformation
  116. }
  117. 'FancyHTML'
  118. {
  119. Add-Content ".\style.CSS" -Value " body {
  120. font-family:Calibri;
  121. font-size:10pt;
  122. }
  123. th {
  124. background-color:black;
  125. color:white;
  126. }
  127. td {
  128. background-color:#19fff0;
  129. color:black;}"
  130. $Result.value.fields | ConvertTo-Html -CssUri .\Style.css | Out-File .\Report.html
  131. }
  132. }
  133. }
  134. catch
  135. {
  136. $_.Exception.Message
  137. }
  138. }
  139. end
  140. {
  141. }
  142. }
Enjoy PowerShell!
Soon I will connect with you all with a series of detailed blog posts under the umbrella of "Work with Visual Studio Team Services using REST API in PowerShell".