|
11 | 11 | .Link |
12 | 12 | Invoke-ADORestAPI |
13 | 13 | #> |
14 | | - [CmdletBinding(DefaultParameterSetName='ByID',SupportsShouldProcess=$true)] |
| 14 | + [CmdletBinding(DefaultParameterSetName='WorkItem',SupportsShouldProcess=$true)] |
15 | 15 | [OutputType('PSDevOps.WorkItem')] |
16 | 16 | param( |
17 | 17 | # The InputObject |
18 | | - [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] |
| 18 | + [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,ParameterSetName='WorkItem')] |
19 | 19 | [PSObject] |
20 | 20 | $InputObject, |
21 | 21 |
|
22 | 22 | # The type of the work item. |
23 | | - [Parameter(Mandatory, ValueFromPipelineByPropertyName)] |
| 23 | + [Parameter(Mandatory, ParameterSetName='WorkItem',ValueFromPipelineByPropertyName)] |
24 | 24 | [Alias('WorkItemType')] |
25 | 25 | [string] |
26 | 26 | $Type, |
27 | 27 |
|
| 28 | + # If set, will create a shared query for work items. The -InputObject will be passed to the body. |
| 29 | + [Parameter(Mandatory,ParameterSetName='SharedQuery',ValueFromPipelineByPropertyName)] |
| 30 | + [string] |
| 31 | + $QueryName, |
| 32 | + |
| 33 | + # If provided, will create shared queries beneath a given folder. |
| 34 | + [Parameter(ParameterSetName='SharedQuery',ValueFromPipelineByPropertyName)] |
| 35 | + [Parameter(ParameterSetName='SharedQueryFolder',ValueFromPipelineByPropertyName)] |
| 36 | + [string] |
| 37 | + $QueryPath, |
| 38 | + |
| 39 | + # If provided, create a shared query with a given WIQL. |
| 40 | + [Parameter(Mandatory, ParameterSetName='SharedQuery',ValueFromPipelineByPropertyName)] |
| 41 | + [string] |
| 42 | + $WIQL, |
| 43 | + |
| 44 | + # If provided, the shared query created may be hierchical |
| 45 | + [Parameter(ParameterSetName='SharedQuery',ValueFromPipelineByPropertyName)] |
| 46 | + [ValidateSet('Flat','OneHop', 'Tree')] |
| 47 | + [string] |
| 48 | + $QueryType, |
| 49 | + |
| 50 | + # The recursion option for use in a tree query. |
| 51 | + [Parameter(ParameterSetName='SharedQuery',ValueFromPipelineByPropertyName)] |
| 52 | + [ValidateSet('childFirst','parentFirst')] |
| 53 | + [string] |
| 54 | + $QueryRecursiveOption, |
| 55 | + |
| 56 | + # If provided, create a shared query folder. |
| 57 | + [Parameter(Mandatory, ParameterSetName='SharedQueryFolder',ValueFromPipelineByPropertyName)] |
| 58 | + [string] |
| 59 | + $FolderName, |
| 60 | + |
28 | 61 | # The work item ParentID |
29 | | - [Parameter(ValueFromPipelineByPropertyName)] |
| 62 | + [Parameter(ValueFromPipelineByPropertyName,ParameterSetName='WorkItem')] |
30 | 63 | [string] |
31 | 64 | $ParentID, |
32 | 65 |
|
|
42 | 75 | $Project, |
43 | 76 |
|
44 | 77 | # A collection of relationships for the work item. |
45 | | - [Parameter(ValueFromPipelineByPropertyName)] |
| 78 | + [Parameter(ValueFromPipelineByPropertyName,ParameterSetName='WorkItem')] |
46 | 79 | [Alias('Relationships')] |
47 | 80 | [Collections.IDictionary] |
48 | 81 | $Relationship, |
49 | 82 |
|
50 | 83 | # A list of comments to be added to the work item. |
51 | | - [Parameter(ValueFromPipelineByPropertyName)] |
| 84 | + [Parameter(ValueFromPipelineByPropertyName,ParameterSetName='WorkItem')] |
52 | 85 | [PSObject[]] |
53 | 86 | $Comment, |
54 | 87 |
|
|
58 | 91 | $Tag, |
59 | 92 |
|
60 | 93 | # If set, will not validate rules. |
61 | | - [Parameter(ValueFromPipelineByPropertyName)] |
| 94 | + [Parameter(ValueFromPipelineByPropertyName,ParameterSetName='WorkItem')] |
62 | 95 | [Alias('BypassRules','NoRules','NoRule')] |
63 | 96 | [switch] |
64 | 97 | $BypassRule, |
|
70 | 103 | $ValidateOnly, |
71 | 104 |
|
72 | 105 | # If set, will only validate rules, but will not update the work item. |
73 | | - [Parameter(ValueFromPipelineByPropertyName)] |
| 106 | + [Parameter(ValueFromPipelineByPropertyName,ParameterSetName='WorkItem')] |
74 | 107 | [Alias('SuppressNotifications','SkipNotification','SkipNotifications','NoNotify')] |
75 | 108 | [switch] |
76 | 109 | $SupressNotification, |
|
160 | 193 | } |
161 | 194 | } |
162 | 195 | #endregion Output Work Item |
| 196 | + |
| 197 | + |
| 198 | + |
163 | 199 | $q = [Collections.Queue]::new() |
164 | 200 | } |
165 | 201 |
|
|
177 | 213 |
|
178 | 214 | $c++ |
179 | 215 | Write-Progress "Creating" "$type [$c/$t]" -PercentComplete ($c * 100 / $t) -Id $progId |
180 | | - |
| 216 | + $orgAndProject = @{Organization=$Organization;Project=$Project} |
181 | 217 | $validFields = |
182 | 218 | if ($script:ADOFieldCache.$uribase) { |
183 | 219 | $script:ADOFieldCache.$uribase |
184 | 220 | } else { |
185 | | - Get-ADOField -Organization $Organization -Project $Project -Server $Server @invokeParams |
| 221 | + Get-ADOField @orgAndProject -Server $Server @invokeParams |
186 | 222 | } |
187 | 223 |
|
| 224 | + if ($psParameterSet -in 'SharedQuery', 'SharedQueryFolder') { |
| 225 | + if ($Server -ne 'https://dev.azure.com/' -and |
| 226 | + -not $PSBoundParameters.ApiVersion) { |
| 227 | + $ApiVersion = '2.0' |
| 228 | + } |
| 229 | + |
| 230 | + $queryPathParts = @($QueryPath -split '/') |
| 231 | + $sharedQueries = $null |
| 232 | + foreach ($qp in $queryPathParts) { |
| 233 | + if (-not $qp) { continue } |
| 234 | + if (-not ($qp -as [guid])) { |
| 235 | + $sharedQueries = Get-ADOWorkItem -SharedQuery @orgAndProject -Depth 2 |
| 236 | + break |
| 237 | + } |
| 238 | + } |
| 239 | + |
| 240 | + if ($sharedQueries) { |
| 241 | + $queryPathId = $sharedQueries | |
| 242 | + Where-Object Path -eq $QueryPath | |
| 243 | + Select-Object -ExpandProperty ID |
| 244 | + if (-not $queryPathId) { |
| 245 | + Write-Error "Unable to find Query Path '$QueryPath'" |
| 246 | + continue |
| 247 | + } else { |
| 248 | + $QueryPath = $queryPathId |
| 249 | + } |
| 250 | + } |
| 251 | + |
| 252 | + $uri = $uriBase, "_apis/wit/queries", $(if ($QueryPath) { $QueryPath }) -ne '' -join '/' |
| 253 | + $uri = $uri.ToString().TrimEnd('/') |
| 254 | + $uri += '?' + |
| 255 | + (@( |
| 256 | + if ($ApiVersion) { "api-version=$ApiVersion" } |
| 257 | + if ($validateOnly) { "validateWiqlOnly=true" } |
| 258 | + ) -join '&') |
| 259 | + $invokeParams.uri = $uri |
| 260 | + |
| 261 | + $queryObject = @{} |
| 262 | + if ($psParameterSet -eq 'SharedQueryFolder') { |
| 263 | + $queryObject['name'] = $FolderName |
| 264 | + $queryObject['isFolder'] = $true |
| 265 | + if ($QueryType) { |
| 266 | + $queryObject['queryType'] = $QueryType |
| 267 | + } |
| 268 | + if ($queryRecursionOption) { |
| 269 | + $queryObject['queryRecursionOption'] = $queryRecursionOption |
| 270 | + } |
| 271 | + |
| 272 | + } else { |
| 273 | + $queryObject['name'] = $QueryName |
| 274 | + $queryObject['wiql'] = $WIQL |
| 275 | + |
| 276 | + } |
| 277 | + |
| 278 | + $invokeParams.Body = ConvertTo-Json $queryObject -Depth 100 |
| 279 | + $invokeParams.Method = 'POST' |
| 280 | + $invokeParams.ContentType = 'application/json' |
| 281 | + $invokeParams.PSTypeName = @( |
| 282 | + "$Organization.$psParameterSet" |
| 283 | + "$Organization.$project.$psParameterSet" |
| 284 | + "PSDevOps.$psParameterSet" |
| 285 | + ) |
| 286 | + if ($WhatIfPreference) { |
| 287 | + $invokeParams.Remove('PersonalAccessToken') |
| 288 | + $invokeParams |
| 289 | + continue |
| 290 | + } |
| 291 | + |
| 292 | + if (-not $PSCmdlet.ShouldProcess("POST $uri with $($invokeParams.body)")) { continue } |
| 293 | + $restResponse = Invoke-ADORestAPI @invokeParams 2>&1 |
| 294 | + $restResponse |
| 295 | + continue |
| 296 | + } |
| 297 | + |
| 298 | + |
188 | 299 | $validFieldTable = $validFields | Group-Object ReferenceName -AsHashTable |
189 | 300 | $uri = $uriBase, "_apis/wit/workitems", "`$$($Type)?" -join '/' |
190 | 301 | if ($Server -ne 'https://dev.azure.com/' -and |
|
0 commit comments