Merge-AzTableItem.ps1

Function Merge-AzTableItem
{
    <#
    .SYNOPSIS
        Merge an item with existing item in Azure Table.

    .PARAMETER odataVersion
        Specifies the OData version to use in the request. Valid values are "nometadata", "minimalmetadata" and "fullmetadata". The default value is "minimalmetadata".

    .PARAMETER StorageAccountName
        Name of the storage account containing the table.

    .PARAMETER TableName
        Name of the table to query.

    .PARAMETER AccessToken
        Access token for authenticating with Azure Table Storage.

    .PARAMETER PartitionKey
        Partition key of the item to retrieve. If specified, RowKey must also be specified

    .PARAMETER RowKey
        Row key of the item to retrieve. If specified, PartitionKey must also be specified

    .PARAMETER Body
        Hashtable containing the properties and values for the item to add or update.

    .EXAMPLE
        #Require RBAC app permissions on storage account: Storage Table Data Contributor

        $Body = @{
            Attribute1 = "Test1"
            Attribute2 = "Test2"
            Attribute3 = "Test3"
        }
        $Item = Add-AzTableItem -StorageAccountName "<StorageAccountName>" -TableName "<TableName>" -AccessToken $Token.AccessToken -PartitionKey "<PartitionKey>" -RowKey "<RowKey>" -Body $Body -Verbose

    .NOTES
        Author: Michal Gajda

    .LINK
        https://learn.microsoft.com/en-us/rest/api/storageservices/insert-or-replace-entity
#>


    [CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact="Medium")]
    Param(
        [ValidateSet("nometadata","minimalmetadata","fullmetadata")]
        [Parameter()]
        [String]$OdataVersion = "minimalmetadata",
        [Parameter(Mandatory = $true)]
        [String]$StorageAccountName,
        [Parameter(Mandatory = $true)]
        [String]$TableName,
        [Parameter(Mandatory = $true)]
        [String]$AccessToken,
        [Parameter(Mandatory = $true,ValueFromPipelineByPropertyName = $true)]
        [String]$PartitionKey,
        [Parameter(Mandatory = $true,ValueFromPipelineByPropertyName = $true)]
        [String]$RowKey,
        [Parameter(Mandatory = $true)]
        [hashtable]$Body
    )

    Begin
    {
        #Build headers
        $Date = [DateTime]::UtcNow.ToString('R')
        $Headers = @{
            "Accept"        = "application/json;odata=$OdataVersion"
            "x-ms-version"  = "2026-06-06"
            "x-ms-date"     = $Date
            "Authorization" = "Bearer $($AccessToken)"
            "Content-Type" = "application/json"
        }

        $Results = @()
    }

    Process
    {
        #Insert or merge item
        $Uri = "https://$($StorageAccountName).table.core.windows.net/$($TableName)(PartitionKey='$($PartitionKey)',RowKey='$($RowKey)')"

        Write-Verbose $Uri
        Write-Verbose "Headers: $($Headers | Select-Object -exclude "Authorization" | Convertto-Json -Compress)"

        If ($PSCmdlet.ShouldProcess($StorageAccountName,"Merge item with PartitionKey:'$($PartitionKey)' and RowKey:'$($RowKey)' from table $TableName"))
        {
            $Results += Invoke-RestMethod -Uri $Uri -Headers $Headers -Method MERGE -Body ($Body | Convertto-Json -Compress) -ResponseHeadersVariable ResponseHeaders
            Write-Verbose "ResponseHeaders: $($ResponseHeaders | Convertto-Json -Compress)"
            Write-Verbose "Items retrieved: $($Result.Count)"
        }
    }

    End
    {
        Return $Results
    }
}