Remove-AzTableItem.ps1

Function Remove-AzTableItem
{
    <#
    .SYNOPSIS
        Remove an item from Azure Table.

    .PARAMETER odataVersion
        Specifies the OData version to use in the request. Valid values are "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 SkipIfMatchValidation
        If specified, the If-Match header will be set to "*" to skip checking for the ETag of the entity. This can be useful if you want to delete an entity without knowing its current ETag.

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

        Remove-AzTableItem -StorageAccountName "<StorageAccountName>" -TableName "<TableName>" -AccessToken $Token.AccessToken -PartitionKey "<PartitionKey>" -RowKey "<RowKey>" -Verbose

    .NOTES
        Author: Michal Gajda

    .LINK
        https://learn.microsoft.com/en-us/rest/api/storageservices/delete-entity1
#>


    [CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact="Medium")]
    Param(
        [ValidateSet("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()]
        [Switch]$SkipIfMatchValidation
    )

    Begin
    {
        $Results = @()
    }

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

        if(-not $SkipIfMatchValidation)
        {
            #Get ETag
            $Uri = "https://$($StorageAccountName).table.core.windows.net/$($TableName)(PartitionKey='$($PartitionKey)',RowKey='$($RowKey)')"

            Write-Verbose $Uri
            $Results += Invoke-RestMethod -Uri $Uri -Headers $Headers -Method GET -ResponseHeadersVariable ResponseHeaders

            $Headers["If-Match"] = $Response.'odata.etag'
        } else {
            #Skip ETag
            $Headers["If-Match"] = "*"
        }
        Write-Verbose "Headers: $($Headers | Select-Object -exclude "Authorization" | Convertto-Json -Compress)"

        If ($PSCmdlet.ShouldProcess($StorageAccountName,"Remove item with PartitionKey:'$($PartitionKey)' and RowKey:'$($RowKey)' from table $TableName"))
        {
            #Remove Item
            $Response = Invoke-RestMethod -Uri $Uri -Headers $Headers -Method DELETE -ResponseHeadersVariable ResponseHeaders
            Write-Verbose "ResponseHeaders: $($ResponseHeaders | Convertto-Json -Compress)"
        }
    }

    End
    {
        Return $Results
    }
}