Public/Set-MondayBoardItem.ps1
Function Set-MondayBoardItem { <# .SYNOPSIS Update column values for a Monday.com item .DESCRIPTION This function updates column values for a specific Monday.com item using the Monday.com API. It supports updating any column type by providing column values as a hashtable or JSON string. The function can update a single column or multiple columns in one operation. .PARAMETER ItemId The ID of the item to update .PARAMETER BoardId The ID of the board containing the item (required for some API operations) .PARAMETER ColumnValues Hashtable of column values to update. Keys should be column IDs, values should be the data for that column. The value format depends on the column type (see Monday.com column types documentation). .PARAMETER ColumnValuesJson JSON string containing the column values to update. Use this for complex column types or when you have pre-formatted JSON. This parameter is mutually exclusive with ColumnValues. .PARAMETER CreateLabelsIfMissing Creates status/dropdown labels if they are missing (requires permission to change board structure) .PARAMETER ReturnUpdatedItem Return the updated item object after the update operation .EXAMPLE Set-MondayBoardItem -ItemId 1234567890 -ColumnValues @{ "status" = "Done"; "text" = "Updated text" } Updates the status and text columns for the specified item .EXAMPLE $columnData = @{ "status" = "In Progress" "date" = "2025-07-15" "numbers" = 42 "text" = "Updated via PowerShell" } Set-MondayBoardItem -ItemId 1234567890 -ColumnValues $columnData -ReturnUpdatedItem Updates multiple columns and returns the updated item .EXAMPLE $jsonData = '{"status":{"label":"Done"},"date":"2025-07-15","text":"Updated text"}' Set-MondayBoardItem -ItemId 1234567890 -ColumnValuesJson $jsonData Updates columns using pre-formatted JSON .EXAMPLE Get-MondayItem -BoardIds @(1234567890) | ForEach-Object { Set-MondayBoardItem -ItemId $_.id -ColumnValues @{ "status" = "Reviewed" } } Pipeline example: Updates the status column for all items in a board .INPUTS System.Int64 .OUTPUTS Monday.Item (when ReturnUpdatedItem is specified) System.String (success message when ReturnUpdatedItem is not specified) .NOTES Column value formats vary by column type: - Text: Simple string value - Status: String with label name, or object with label property - Date: ISO date string (YYYY-MM-DD) - Numbers: Numeric value - Person: User ID or array of user IDs - Timeline: Object with from/to dates For complex column types, refer to the Monday.com column types documentation. This function requires 'boards:write' scope in your API token. .LINK https://developer.monday.com/api-reference/reference/column-types-reference .LINK https://developer.monday.com/api-reference/reference/items#change-column-values #> [CmdletBinding(DefaultParameterSetName = 'Hashtable')] Param( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [Alias('Id')] [Int64]$ItemId, [Parameter(Mandatory=$false)] [Int64]$BoardId, [Parameter(Mandatory=$true, ParameterSetName = 'Hashtable')] [Hashtable]$ColumnValues, [Parameter(Mandatory=$true, ParameterSetName = 'Json')] [String]$ColumnValuesJson, [Parameter(Mandatory=$false)] [Switch]$CreateLabelsIfMissing, [Parameter(Mandatory=$false)] [Switch]$ReturnUpdatedItem ) Begin { Write-Verbose -Message "Starting $($MyInvocation.InvocationName)..." Write-Verbose -Message "Parameter Set: $($PSCmdlet.ParameterSetName)" } Process { try { Write-Verbose -Message "Updating item ID: $ItemId" # Build the column values JSON string $columnValuesString = "" if ($PSCmdlet.ParameterSetName -eq 'Hashtable') { # Convert hashtable to JSON Write-Verbose -Message "Converting hashtable to JSON for $($ColumnValues.Keys.Count) columns" # Build a proper JSON object for Monday.com API $jsonObject = @{} foreach ($columnId in $ColumnValues.Keys) { $value = $ColumnValues[$columnId] Write-Verbose -Message "Processing column '$columnId' with value: $value" # Handle different value types appropriately with smart detection if ($value -is [string]) { # For string values, apply smart formatting based on column ID patterns if ($columnId -match "(status|dropdown)") { # For status columns, wrap in label object $jsonObject[$columnId] = @{ "label" = $value } } elseif ($columnId -match "date" -and $value -match "^\d{4}-\d{2}-\d{2}$") { # For date columns with ISO date format, use as-is $jsonObject[$columnId] = $value } else { # For other string columns (text, etc.) $jsonObject[$columnId] = $value } } elseif ($value -is [datetime]) { # Convert DateTime to ISO date string $jsonObject[$columnId] = $value.ToString("yyyy-MM-dd") } elseif ($value -is [int] -or $value -is [long]) { # Handle user IDs for person columns if ($columnId -match "person|people|user") { # Auto-format as person column $jsonObject[$columnId] = @{ "personsAndTeams" = @(@{ "id" = $value; "kind" = "person" }) } } else { # For numbers columns, use as-is $jsonObject[$columnId] = $value } } elseif ($value -is [array] -and $columnId -match "person|people|user") { # Handle multiple user IDs for person columns $personsArray = $value | ForEach-Object { @{ "id" = $_; "kind" = "person" } } $jsonObject[$columnId] = @{ "personsAndTeams" = $personsArray } } elseif ($value -is [hashtable] -or $value -is [PSCustomObject]) { # Use the object as-is for complex column types $jsonObject[$columnId] = $value } else { # For other simple types, use as-is $jsonObject[$columnId] = $value } } $columnValuesString = ($jsonObject | ConvertTo-Json -Compress -Depth 5) } else { # Use the provided JSON string $columnValuesString = $ColumnValuesJson Write-Verbose -Message "Using provided JSON string" } Write-Verbose -Message "Column values JSON: $columnValuesString" # Escape the JSON string for GraphQL $escapedJson = $columnValuesString -replace '\\', '\\\\' -replace '"', '\"' # Build the mutation arguments $mutationArgs = @( "item_id: $ItemId" "column_values: `"$escapedJson`"" ) if ($BoardId) { $mutationArgs += "board_id: $BoardId" Write-Verbose -Message "Including board ID: $BoardId" } if ($CreateLabelsIfMissing) { $mutationArgs += "create_labels_if_missing: true" Write-Verbose -Message "Will create missing labels if needed" } # Determine which mutation to use # Monday.com has both change_column_value (single) and change_multiple_column_values (multiple) # We'll use change_multiple_column_values for flexibility $mutationName = "change_multiple_column_values" $argumentString = $mutationArgs -join ', ' # Build the response fields $responseFields = @( 'id', 'name', 'state', 'updated_at' ) if ($ReturnUpdatedItem) { # Include more fields when returning the updated item $responseFields += @( 'created_at', 'creator { id name email }', 'board { id name }', 'group { id title }', 'column_values { id text value type column { id title type } }' ) Write-Verbose -Message "Will return updated item with full details" } $fieldString = $responseFields -join ' ' # Build the complete mutation $mutation = "mutation { $mutationName ($argumentString) { $fieldString } }" Write-Verbose -Message "GraphQL Mutation: $mutation" # Execute the mutation $response = Invoke-MondayApi -Query $mutation if ($response.$mutationName) { $updatedItem = $response.$mutationName if ($ReturnUpdatedItem) { # Add type information and return the item $updatedItem.PSObject.TypeNames.Insert(0, 'Monday.Item') Write-Verbose -Message "Successfully updated item $ItemId and returning updated object" return $updatedItem } else { # Return success message $message = "Successfully updated item $ItemId" if ($updatedItem.name) { $message += " ('$($updatedItem.name)')" } Write-Verbose -Message $message return $message } } else { throw "No response data received from Monday.com API" } } catch { $errorMessage = "Error updating Monday item ${ItemId}: $($_.Exception.Message)" Write-Error -Message $errorMessage throw $_ } } End { Write-Verbose -Message "Ending $($MyInvocation.InvocationName)..." } } |