Public/Get-SpecAzTableRowUsingSAS.ps1
function Get-SpecAzTableRowUsingSAS { <# .SYNOPSIS Retrieves data from an Azure Table Storage using a Shared Access Signature (SAS) token. .DESCRIPTION This function allows you to retrieve data from an Azure Table Storage using a SAS token for authentication. You can retrieve all data from the table or specify key-value pairs to filter the results. .PARAMETER SAS The Shared Access Signature (SAS) token for authenticating with the Azure Table Storage. .PARAMETER StorageAccount The name of the Azure Storage Account containing the table. .PARAMETER TableName The name of the Azure Table to retrieve data from. .PARAMETER Key (Optional) The key to use for filtering data. .PARAMETER Value (Optional) The value to use for filtering data. .PARAMETER CustomFilter (Optional) An optional custom filter to apply to the URI. .PARAMETER GetAllRows A switch parameter to indicate whether to retrieve all rows in the table. (All table data) .EXAMPLE Retrieve all data from the specified Azure Table using the -GetAllRows switch: Get-SpecAzTableRowUsingSAS -SAS $SasToken -StorageAccount "myaccount" -TableName "mytable" -GetAllRows .EXAMPLE Retrieve row data from the specified Azure Table using the -Key and -Value: Get-SpecAzTableRowUsingSAS -SAS $SasTokenReadToken -StorageAccount $storageAccount -TableName $tableName -Key 'DeviceType' -Value 'HR' Returns the row where 'DeviceType' = 'HR' .EXAMPLE Retrieve row data from the specified Azure Table using a custom filter: $customFilter = "(Last_Logged_On eq 'fred.bloggs') and (Device_Name eq 'mydevice')" try { Get-SpecAzTableRowUsingSAS -SAS $SasTokenReadToken -StorageAccount $storageAccount -TableName $tableName -CustomFilter $customFilter -ea stop write-host "Success" -foregroundcolor darkgreen } catch { write-host "An error occurred. $_" -foregroundcolor darkyellow } Returns the row where 'Last_Logged_On' = 'fred.bloggs' and 'Device_Name' = 'mydevice' .NOTES Author: owen.heaume Version: 1.1 - Initial release 1.1.1 - Now throws on errors so that they can be trapped via try/catch 1.1.2 - retrieves more than 1000 rows if present (previously would only return 1000 rows on large tables 2.0.0 - Now uses 'Write-Error' instead of throw to enable function use elegantly within try / catch #> [cmdletbinding()] param( [parameter (mandatory = $true)] [string]$SasToken, [parameter (mandatory = $true)] [string]$StorageAccount, [parameter (mandatory = $true)] [string]$TableName, [parameter (mandatory = $false, ParameterSetName = 'KeyValue')] [string]$Key, [parameter (mandatory = $false, ParameterSetName = 'KeyValue')] [string]$Value, [parameter (mandatory = $false, ParameterSetName = 'Custom')] [string]$CustomFilter, [parameter (ParameterSetName = 'GetAllRows')] [Switch]$GetAllRows ) begin { $headers = @{ Accept = 'application/json;odata=nometadata' } } process { # Validate key and value parameters if ($key -and [string]::IsNullOrEmpty($value)) { Write-Error 'You have requested to return filtered data but the [value] parameter is missing' } if ($value -and [string]::IsNullOrEmpty($key)) { Write-Error 'You have requested to return filtered data but the [key] parameter is missing' } # Construct the initial URI if ($key -and $value) { Write-Verbose 'Requesting filtered data' $filter = "`$filter=($key eq '$value')" $tableUri = Get-SpecAzTableUri -SAS $SasToken -StorageAccount $StorageAccount -TableName $TableName -Key $key -Value $Value } elseif ($customfilter) { $tableUri = Get-SpecAzTableUri -SAS $SasToken -StorageAccount $StorageAccount -TableName $TableName -CustomFilter $CustomFilter } else { Write-Verbose 'Requesting all data' $tableUri = Get-SpecAzTableUri -SAS $SasToken -StorageAccount $StorageAccount -TableName $TableName -GetAllRows } $allItems = @() $nextPartitionKey = $null $nextRowKey = $null do { try { $uri = $tableUri + "&`$top=1000" if ($nextPartitionKey -and $nextRowKey) { $uri += "&NextPartitionKey=$nextPartitionKey&NextRowKey=$nextRowKey" } Write-Verbose "Making request to URI: $uri" $response = Invoke-WebRequest -Method Get -Uri $uri -Headers $headers -ContentType application/json -ErrorAction Stop -UseBasicParsing $content = $response.Content | ConvertFrom-Json if ($content -and $content.value) { $allItems += $content.value } else { Write-Host 'No data returned in response' -ForegroundColor DarkYellow } Write-Verbose "Response Headers: $($response.Headers | Format-List)" if ($response.Headers['x-ms-continuation-NextPartitionKey'] -and $response.Headers['x-ms-continuation-NextRowKey']) { $nextPartitionKey = $response.Headers['x-ms-continuation-NextPartitionKey'] $nextRowKey = $response.Headers['x-ms-continuation-NextRowKey'] Write-Verbose "Received continuation tokens: NextPartitionKey=$nextPartitionKey, NextRowKey=$nextRowKey" } else { Write-Verbose 'No continuation headers found' $nextPartitionKey = $null $nextRowKey = $null } } catch [System.Net.WebException] { if ($_.Exception.Message -contains 'The remote server returned an error: (404) Not Found.') { Write-Error "Table [$TableName] not found. Please check that the table exists and that you have not made a typo. $_" } elseif ($_.Exception.Message -match 'The remote name could not be resolved') { Write-Error "Storage account [$StorageAccount] not found. Please check that the storage account exists and that you have not made a typo. $_" } else { # Handle other WebExceptions Write-Error "A WebException occurred: $($_.Exception.Message)" } } catch { Write-Error "An error occurred: $_" } } while ($nextPartitionKey -or $nextRowKey) return $allItems } } |