Last active
September 29, 2025 19:30
-
-
Save RylandDeGregory/c65563d0b090fc32115be7025d1ce722 to your computer and use it in GitHub Desktop.
Azure Table Storage REST operations using PowerShell.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $StorageAccount = '' | |
| $Table = '' | |
| $PartitionKey = '' | |
| $RowKey = '' | |
| # Set Azure Table Storage request headers | |
| $Date = [DateTime]::UtcNow.ToString('R') | |
| $AzTableHeaders = @{ | |
| 'Accept' = 'application/json;odata=nometadata' | |
| 'x-ms-version' = '2020-08-04' | |
| 'x-ms-date' = $Date | |
| } | |
| #region OAuth | |
| # Operations require the calling Principal being assigned the | |
| # "Storage Table Data Contributor" Azure RBAC Role on (at least) the Storage Account scope | |
| # Connect to Azure | |
| Connect-AzAccount | |
| $AZStorageToken = Get-AzAccessToken -ResourceTypeName Storage | |
| $AzTableHeaders += @{'Authorization' = "$($AzStorageToken.Type) $($AzStorageToken.Token)"} | |
| #endregion OAuth | |
| #region AccessKey | |
| $AccessKey = '' | |
| # SigningString will differ depending on the API operation being performed | |
| $SigningString = "$Date`n/$StorageAccount/$Table(PartitionKey='$PartitionKey',RowKey='$RowKey')" | |
| $HmacSha = [System.Security.Cryptography.HMACSHA256]@{Key = [Convert]::FromBase64String($AccessKey)} | |
| $Signature = [Convert]::ToBase64String($HmacSha.ComputeHash([Text.Encoding]::UTF8.GetBytes($SigningString))) | |
| $AzTableHeaders += @{'Authorization' = "SharedKeyLite $StorageAccount`:$Signature"} | |
| #endregion AccessKey | |
| #region Operations | |
| # Get all Records in Table | |
| $TableRecords = @() | |
| $TableResponse = Invoke-WebRequest -Method Get -Uri "https://$StorageAccount.table.core.windows.net/$Table()" -Headers $AzTableHeaders | |
| $TableRecords += $TableResponse | Select-Object -ExpandProperty Content | ConvertFrom-Json | Select-Object -ExpandProperty value | |
| $TableRecords += while($TableResponse.Headers.'x-ms-continuation-NextPartitionKey') { | |
| $TableResponse = Invoke-WebRequest -Method Get -Uri "https://$StorageAccount.table.core.windows.net/$Table()?NextPartitionKey=$($TableResponse.Headers.'x-ms-continuation-NextPartitionKey')&NextRowKey=$($TableResponse.Headers.'x-ms-continuation-NextRowKey')" -Headers $AzTableHeaders | |
| $TableResponse | Select-Object -ExpandProperty Content | ConvertFrom-Json | Select-Object -ExpandProperty value | |
| } | |
| # Get all Records by PartitionKey | |
| Invoke-RestMethod -Method Get -Uri "https://$StorageAccount.table.core.windows.net/$Table()?`$filter=PartitionKey eq '$PartitionKey'" -Headers $AzTableHeaders | Select-Object -ExpandProperty value | |
| # Get Record by RowKey | |
| Invoke-RestMethod -Method Get -Uri "https://$StorageAccount.table.core.windows.net/$Table(PartitionKey='$PartitionKey',RowKey='$RowKey')" -Headers $AzTableHeaders | |
| # Insert Record | |
| $InsertBody = @{ | |
| PartitionKey = $PartitionKey | |
| RowKey = $RowKey.ToString() | |
| } | ConvertTo-Json | |
| Invoke-RestMethod -Method Post -Uri "https://$StorageAccount.table.core.windows.net/$Table" -Body $InsertBody -Headers $AzTableHeaders -ContentType 'application/json' | |
| # Update Record | |
| $UpdateBody = @{ | |
| Name = 'NewName' | |
| } | ConvertTo-Json | |
| Invoke-RestMethod -Method Put -Uri "https://$StorageAccount.table.core.windows.net/$Table(PartitionKey='$PartitionKey',RowKey='$RowKey')" -Body $UpdateBody -Headers $AzTableHeaders -ContentType 'application/json' | |
| # Delete Record | |
| $DeleteHeaders = $AzTableHeaders += @{'If-Match' = '*'} | |
| Invoke-RestMethod -Method Delete -Uri "https://$StorageAccount.table.core.windows.net/$Table(PartitionKey='$PartitionKey',RowKey='$RowKey')" -Headers $DeleteHeaders | |
| #endregion Operations |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This and the related blog post (link) have really helped me! All the other blogs and tips I've found have used SAS keys which is lazy, old and insecure! π π―
Just wanted to, in some way, say thanks! This was the only way to reach out to you without paying for LinkedIn π