Creating an Azure DevOps User Story with Powershell
09:44 04 Nov 2025

I am looping through an Azure DevOps query to essentially create copies of work items into a new iteration. The problem I'm having is with the final Invoke-RestMethod call at then end of the script. It returns this: Invoke-RestMethod : {"$id":"1","innerException":null,"message":"Value cannot be null.","typeName":"Microsoft.VisualStudio.Services.Common.VssPropertyValidationException, Microsoft.VisualStudio.Services.Common","typeKey":"VssPropertyValidationException","errorCode":0,"eventId":3000}

Any ideas where I went wrong?

$organization = "mycompany"
$project = "MyProject"
$pat = "myPAT"
$headers = @{Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat"))}

$newIterationPath = "IT Main\Production Support\2025\2025.4.3"  

# Encode PAT for Authorization header
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat"))

# 1. Run WIQL query to get work item IDs
$wiqlUrl = "https://dev.azure.com/$organization/$project/_apis/wit/wiql/798dee4f-b063-4f4f-a710-415c590a4dcc?api-version=7.0"
$response = Invoke-RestMethod -Uri $wiqlUrl -Method Get -Headers $headers

$workItemIds = $response.workItems.id

# 2. Get details of each work item
foreach ($id in $workItemIds) {
    $workItemUrl = "https://dev.azure.com/$organization/$project/_apis/wit/workitems/$($id)?api-version=7.0"
    $workItem = Invoke-RestMethod -Uri $workItemUrl -Headers $headers

    # Prepare fields for new work item
    $fields = @(
        @{ "op" = "add"; "path" = "/fields/System.Title"; "value" = $workItem.fields.'System.Title' },
        @{ "op" = "add"; "path" = "/fields/System.Description"; "value" = $workItem.fields.'System.Description' },
        @{ "op" = "add"; "path" = "/fields/System.AreaPath"; "value" = $workItem.fields.'System.AreaPath' },
        @{ "op" = "add"; "path" = "/fields/System.IterationPath"; "value" = $newIterationPath },
        @{ "op" = "add"; "path" = "/fields/System.AssignedTo"; "value" = $workItem.fields.'System.AssignedTo'}
    )

    $body = (ConvertTo-JSON $fields)

    # 3. Create new work item in target iteration
    $createUrl = "https://dev.azure.com/$organization/$project/_apis/wit/workitems/$" + $workItem.fields.'System.WorkItemType' +"?api-version=7.0"
    $newWorkItem = Invoke-RestMethod -Uri $createUrl -Method POST -Headers $headers -contentType "application/json-patch+json" -Body $body

    Write-Host "Created new work item: $($newWorkItem.id)"
}
powershell azure-devops-rest-api