Public/New-MondayBoardItem.ps1
Function New-MondayBoardItem { <# .SYNOPSIS Create a new item (row) in a Monday.com board .DESCRIPTION This function creates a new item in a Monday.com board using the Monday.com API. You can specify the item name and optionally set initial column values when creating the item. The function supports all Monday.com column types and provides smart data formatting. .PARAMETER BoardId The ID of the board where the item will be created .PARAMETER ItemName The name/title of the new item .PARAMETER GroupId Optional group ID within the board where the item should be created. If not specified, the item will be created in the first group. .PARAMETER ColumnValues Hashtable of initial column values to set when creating the item. 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 initial column values. 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 ReturnFullItem Return the complete created item object with all details including column values .EXAMPLE New-MondayBoardItem -BoardId 1234567890 -ItemName "New Task" Creates a new item with just a name .EXAMPLE New-MondayBoardItem -BoardId 1234567890 -ItemName "Project Task" -ColumnValues @{ "status" = "Working on it" "text" = "Task description" "date" = "2025-07-15" "numbers" = 42 } Creates a new item with initial column values .EXAMPLE New-MondayBoardItem -BoardId 1234567890 -ItemName "Urgent Task" -GroupId "group123" -ReturnFullItem Creates a new item in a specific group and returns the complete item object .EXAMPLE 1..5 | ForEach-Object { New-MondayBoardItem -BoardId 1234567890 -ItemName "Test Item $_" -ColumnValues @{ "status" = "Not Started" "text" = "Dummy data for testing" } } Creates multiple test items with dummy data .INPUTS System.Int64 .OUTPUTS Monday.Item .NOTES This function requires 'boards:write' scope in your API token. Column value formats vary by column type - refer to Get-MondayBoardColumn -IncludeExamples for formatting help. Common column formats: - Text: Simple string value - Status: String with label name - Date: ISO date string (YYYY-MM-DD) - Numbers: Numeric value - Person: User ID or array of user IDs .LINK https://developer.monday.com/api-reference/reference/items#create-item .LINK https://developer.monday.com/api-reference/reference/column-types-reference #> [CmdletBinding(DefaultParameterSetName = 'Hashtable')] Param( [Parameter(Mandatory=$true)] [Int64]$BoardId, [Parameter(Mandatory=$true)] [String]$ItemName, [Parameter(Mandatory=$false)] [String]$GroupId, [Parameter(Mandatory=$false, ParameterSetName = 'Hashtable')] [Hashtable]$ColumnValues = @{}, [Parameter(Mandatory=$false, ParameterSetName = 'Json')] [String]$ColumnValuesJson, [Parameter(Mandatory=$false)] [Switch]$CreateLabelsIfMissing, [Parameter(Mandatory=$false)] [Switch]$ReturnFullItem ) Begin { Write-Verbose -Message "Starting $($MyInvocation.InvocationName)..." } Process { try { Write-Verbose -Message "Creating new item '$ItemName' in board $BoardId" # Build the mutation arguments $mutationArgs = @( "board_id: $BoardId" "item_name: `"$($ItemName -replace '"', '\"')`"" ) if ($GroupId) { $mutationArgs += "group_id: `"$GroupId`"" Write-Verbose -Message "Creating in group: $GroupId" } # Handle column values if provided if ($PSCmdlet.ParameterSetName -eq 'Hashtable' -and $ColumnValues.Count -gt 0) { # Convert hashtable to JSON using the same logic as Set-MondayBoardItem Write-Verbose -Message "Converting hashtable to JSON for $($ColumnValues.Keys.Count) columns" $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) # Escape the JSON string for GraphQL $escapedJson = $columnValuesString -replace '\\', '\\\\' -replace '"', '\"' $mutationArgs += "column_values: `"$escapedJson`"" Write-Verbose -Message "Column values JSON: $columnValuesString" } elseif ($PSCmdlet.ParameterSetName -eq 'Json' -and $ColumnValuesJson) { # Use the provided JSON string $escapedJson = $ColumnValuesJson -replace '\\', '\\\\' -replace '"', '\"' $mutationArgs += "column_values: `"$escapedJson`"" Write-Verbose -Message "Using provided JSON string" } if ($CreateLabelsIfMissing) { $mutationArgs += "create_labels_if_missing: true" Write-Verbose -Message "Will create missing labels if needed" } # Build the response fields $responseFields = @( 'id', 'name', 'state', 'created_at', 'updated_at', 'creator { id name email }', 'board { id name }' ) if ($ReturnFullItem) { # Include more fields when returning the full item $responseFields += @( 'group { id title }', 'column_values { id text value type column { id title type } }', 'subitems { id name }' ) Write-Verbose -Message "Will return full item details" } $fieldString = $responseFields -join ' ' $argumentString = $mutationArgs -join ', ' # Build the complete mutation $mutation = "mutation { create_item ($argumentString) { $fieldString } }" Write-Verbose -Message "GraphQL Mutation: $mutation" # Execute the mutation $response = Invoke-MondayApi -Query $mutation if ($response.create_item) { $newItem = $response.create_item # Add type information $newItem.PSObject.TypeNames.Insert(0, 'Monday.Item') Write-Verbose -Message "Successfully created item $($newItem.id) ('$($newItem.name)')" return $newItem } else { Write-Error -Message "Failed to create item - no response received from API" } } catch { $errorMessage = "Error creating item '$ItemName' in board ${BoardId}: $($_.Exception.Message)" Write-Error -Message $errorMessage throw $_ } } End { Write-Verbose -Message "Ending $($MyInvocation.InvocationName)..." } } |