├── .gitignore ├── docs ├── media │ ├── guid.png │ ├── cmdlets.png │ ├── image388.png │ ├── image389.png │ ├── image390.png │ ├── image392.png │ ├── image393.png │ ├── image394.png │ ├── image395.png │ ├── image396.png │ ├── image397.png │ ├── image398.png │ ├── image404.png │ ├── image405.png │ ├── image406.png │ ├── psobject.png │ ├── table_details.png │ └── dynamicTableEntity.png ├── Get-AzTableRowAll.md ├── Get-AzTableRowByPartitionKey.md ├── Update-AzTableRow.md ├── Get-AzTableRowByPartitionKeyRowKey.md ├── Get-AzTableTable.md ├── Get-AzTableRowByCustomFilter.md ├── Add-AzTableRow.md ├── Remove-AzTableRow.md ├── Get-AzTableRowByColumnName.md ├── Get-AzTableRow.md └── README.md ├── AzureRmStorageTable-Pester.gif ├── .github └── ISSUE_TEMPLATE │ └── bug_report.md ├── LICENSE ├── .vscode └── launch.json ├── AzTable.psd1 ├── AzureRmStorageTable.psd1 ├── azure-pipelines.yml ├── README.md ├── ReleaseNotes.md ├── Tests └── AzureRmStorageTable.Tests.ps1 └── AzureRmStorageTableCoreHelper.psm1 /.gitignore: -------------------------------------------------------------------------------- 1 | local/* 2 | local/*.* 3 | local/ -------------------------------------------------------------------------------- /docs/media/guid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/guid.png -------------------------------------------------------------------------------- /docs/media/cmdlets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/cmdlets.png -------------------------------------------------------------------------------- /docs/media/image388.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/image388.png -------------------------------------------------------------------------------- /docs/media/image389.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/image389.png -------------------------------------------------------------------------------- /docs/media/image390.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/image390.png -------------------------------------------------------------------------------- /docs/media/image392.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/image392.png -------------------------------------------------------------------------------- /docs/media/image393.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/image393.png -------------------------------------------------------------------------------- /docs/media/image394.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/image394.png -------------------------------------------------------------------------------- /docs/media/image395.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/image395.png -------------------------------------------------------------------------------- /docs/media/image396.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/image396.png -------------------------------------------------------------------------------- /docs/media/image397.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/image397.png -------------------------------------------------------------------------------- /docs/media/image398.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/image398.png -------------------------------------------------------------------------------- /docs/media/image404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/image404.png -------------------------------------------------------------------------------- /docs/media/image405.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/image405.png -------------------------------------------------------------------------------- /docs/media/image406.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/image406.png -------------------------------------------------------------------------------- /docs/media/psobject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/psobject.png -------------------------------------------------------------------------------- /docs/media/table_details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/table_details.png -------------------------------------------------------------------------------- /AzureRmStorageTable-Pester.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/AzureRmStorageTable-Pester.gif -------------------------------------------------------------------------------- /docs/media/dynamicTableEntity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulomarquesc/AzureRmStorageTable/HEAD/docs/media/dynamicTableEntity.png -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: paulomarquesc, sakash279, paulcheng 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Error Message** 14 | Add here the complete error message. 15 | 16 | **PowerShell Version** 17 | Include here the full output of the following command line: 18 | ```powershell 19 | $PSVersionTable 20 | ``` 21 | 22 | **Complete list of Azure related Powershell modules** 23 | Paste here the complete output of `Get-Module *az* -ListAvailable` 24 | 25 | **Code Snippet** 26 | Paste here the code, from how you get the table reference up to the time you get the error 27 | 28 | **More information** 29 | - OS: [e.g. Windows 10, Centos 7.6] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Paulo Marques 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/Get-AzTableRowAll.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: AzureRmStorageTableCoreHelper-help.xml 3 | Module Name: azurermstoragetable 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-AzTableRowAll 9 | 10 | ## SYNOPSIS 11 | Returns all rows/entities from a storage table - no Filtering 12 | 13 | ## SYNTAX 14 | 15 | ```powershell 16 | Get-AzTableRowAll [-Table] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | Returns all rows/entities from a storage table - no Filtering 21 | 22 | ## EXAMPLES 23 | 24 | ### EXAMPLE 1 25 | ```powershell 26 | # Getting all rows 27 | Get-AzTableRowAll -Table $Table 28 | ``` 29 | 30 | ## PARAMETERS 31 | 32 | ### -Table 33 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable to retrieve entities 34 | 35 | ```yaml 36 | Type: Object 37 | Parameter Sets: (All) 38 | Aliases: 39 | 40 | Required: True 41 | Position: 1 42 | Default value: None 43 | Accept pipeline input: False 44 | Accept wildcard characters: False 45 | ``` 46 | 47 | ### CommonParameters 48 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). 49 | 50 | ## INPUTS 51 | 52 | ## OUTPUTS 53 | 54 | ## NOTES 55 | 56 | ## RELATED LINKS 57 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "PowerShell Launch Current File", 9 | "type": "PowerShell", 10 | "request": "launch", 11 | "script": "${file}", 12 | "args": [], 13 | "cwd": "${file}" 14 | }, 15 | { 16 | "name": "PowerShell Launch Current File in Temporary Console", 17 | "type": "PowerShell", 18 | "request": "launch", 19 | "script": "${file}", 20 | "args": [], 21 | "cwd": "${file}", 22 | "createTemporaryIntegratedConsole": true 23 | }, 24 | { 25 | "name": "PowerShell Launch Current File w/Args Prompt", 26 | "type": "PowerShell", 27 | "request": "launch", 28 | "script": "${file}", 29 | "args": [ 30 | "${command:SpecifyScriptArgs}" 31 | ], 32 | "cwd": "${file}" 33 | }, 34 | { 35 | "name": "PowerShell Attach to Host Process", 36 | "type": "PowerShell", 37 | "request": "attach" 38 | }, 39 | { 40 | "name": "PowerShell Interactive Session", 41 | "type": "PowerShell", 42 | "request": "launch", 43 | "cwd": "" 44 | }, 45 | { 46 | "name": "PowerShell Attach Interactive Session Runspace", 47 | "type": "PowerShell", 48 | "request": "attach", 49 | "processId": "current" 50 | } 51 | ] 52 | } -------------------------------------------------------------------------------- /AzTable.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | 3 | # ID used to uniquely identify this module 4 | GUID = '0ed51f07-bcc5-429d-9322-0477168a0926' 5 | 6 | # Author of this module 7 | Author = 'Paulo Marques (MSFT)' 8 | 9 | # Company or vendor of this module 10 | CompanyName = 'Microsoft Corporation' 11 | 12 | # Copyright statement for this module 13 | Copyright = '© Microsoft Corporation. All rights reserved.' 14 | 15 | # Description of the functionality provided by this module 16 | Description = 'Sample functions to add/retrieve/update entities on Azure Storage Tables from PowerShell (This is the same as AzureRmStorageTable module but with a new module name). It requires latest PowerShell Az module installed. Instructions at https://docs.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-1.6.0. For documentation, please visit https://paulomarquesc.github.io/working-with-azure-storage-tables-from-powershell/.' 17 | 18 | # HelpInfo URI of this module 19 | HelpInfoUri = 'https://github.com/paulomarquesc/AzureRmStorageTable/tree/master/docs' 20 | 21 | # Version number of this module 22 | ModuleVersion = '2.1.0' 23 | 24 | # Minimum version of the Windows PowerShell engine required by this module 25 | PowerShellVersion = '4.0' 26 | 27 | # Minimum version of the common language runtime (CLR) required by this module 28 | CLRVersion = '2.0' 29 | 30 | # Script module or binary module file associated with this manifest 31 | #ModuleToProcess = '' 32 | 33 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 34 | NestedModules = @('AzureRmStorageTableCoreHelper.psm1') 35 | 36 | FunctionsToExport = @( 'Add-AzTableRow', 37 | 'Get-AzTableRow', 38 | 'Get-AzTableRowAll', 39 | 'Get-AzTableRowByPartitionKeyRowKey', 40 | 'Get-AzTableRowByPartitionKey', 41 | 'Get-AzTableRowByColumnName', 42 | 'Get-AzTableRowByCustomFilter', 43 | 'Update-AzTableRow', 44 | 'Remove-AzTableRow', 45 | 'Get-AzTableTable' 46 | ) 47 | 48 | VariablesToExport = '' 49 | 50 | AliasesToExport = '*' 51 | 52 | } 53 | -------------------------------------------------------------------------------- /docs/Get-AzTableRowByPartitionKey.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: AzureRmStorageTableCoreHelper-help.xml 3 | Module Name: azurermstoragetable 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-AzTableRowByPartitionKey 9 | 10 | ## SYNOPSIS 11 | Returns one or more rows/entities based on Partition Key 12 | 13 | ## SYNTAX 14 | 15 | ```powershell 16 | Get-AzTableRowByPartitionKey [-Table] [-PartitionKey] [[-Top] ] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | Returns one or more rows/entities based on Partition Key 21 | 22 | ## EXAMPLES 23 | 24 | ### EXAMPLE 1 25 | ```powershell 26 | # Getting rows by partition Key 27 | Get-AzTableRowByPartitionKey -Table $Table -PartitionKey "mypartitionkey" 28 | ``` 29 | 30 | ### EXAMPLE 2 31 | ```powershell 32 | # Getting rows by partition key with a maximum number returned 33 | Get-AzTableRowByPartitionKey -Table $Table -PartitionKey "mypartitionkey" -Top 10 34 | ``` 35 | 36 | ## PARAMETERS 37 | 38 | ### -Table 39 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable to retrieve entities 40 | 41 | ```yaml 42 | Type: Object 43 | Parameter Sets: (All) 44 | Aliases: 45 | 46 | Required: True 47 | Position: 1 48 | Default value: None 49 | Accept pipeline input: False 50 | Accept wildcard characters: False 51 | ``` 52 | 53 | ### -PartitionKey 54 | Identifies the table partition 55 | 56 | ```yaml 57 | Type: String 58 | Parameter Sets: (All) 59 | Aliases: 60 | 61 | Required: True 62 | Position: 2 63 | Default value: None 64 | Accept pipeline input: False 65 | Accept wildcard characters: False 66 | ``` 67 | 68 | ### -Top 69 | Return only the first n rows from the query 70 | 71 | ```yaml 72 | Type: Int32 73 | Parameter Sets: (All) 74 | Aliases: 75 | 76 | Required: False 77 | Position: 3 78 | Default value: None 79 | Accept pipeline input: False 80 | Accept wildcard characters: False 81 | ``` 82 | 83 | ### CommonParameters 84 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). 85 | 86 | ## INPUTS 87 | 88 | ## OUTPUTS 89 | 90 | ## NOTES 91 | 92 | ## RELATED LINKS 93 | -------------------------------------------------------------------------------- /AzureRmStorageTable.psd1: -------------------------------------------------------------------------------- 1 | @{ 2 | 3 | # ID used to uniquely identify this module 4 | GUID = '0ed51f07-bcc5-429d-9322-0477168a0926' 5 | 6 | # Author of this module 7 | Author = 'Paulo Marques (MSFT)' 8 | 9 | # Company or vendor of this module 10 | CompanyName = 'Microsoft Corporation' 11 | 12 | # Copyright statement for this module 13 | Copyright = '© Microsoft Corporation. All rights reserved.' 14 | 15 | # Description of the functionality provided by this module 16 | Description = 'Sample functions to add/retrieve/update entities on Azure Storage Tables from PowerShell (This is the same as AzureRmStorageTable module but with a new module name). It requires latest PowerShell Az module installed. Instructions at https://docs.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-1.6.0. For documentation, please visit https://paulomarquesc.github.io/working-with-azure-storage-tables-from-powershell/.' 17 | 18 | # HelpInfo URI of this module 19 | HelpInfoUri = 'https://github.com/paulomarquesc/AzureRmStorageTable/tree/master/docs' 20 | 21 | # Version number of this module 22 | ModuleVersion = '2.1.0' 23 | 24 | # Minimum version of the Windows PowerShell engine required by this module 25 | PowerShellVersion = '4.0' 26 | 27 | # Minimum version of the common language runtime (CLR) required by this module 28 | CLRVersion = '2.0' 29 | 30 | # Script module or binary module file associated with this manifest 31 | #ModuleToProcess = '' 32 | 33 | # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 34 | NestedModules = @('AzureRmStorageTableCoreHelper.psm1') 35 | 36 | FunctionsToExport = @( 'Add-AzTableRow', 37 | 'Get-AzTableRow', 38 | 'Get-AzTableRowAll', 39 | 'Get-AzTableRowByPartitionKeyRowKey', 40 | 'Get-AzTableRowByPartitionKey', 41 | 'Get-AzTableRowByColumnName', 42 | 'Get-AzTableRowByCustomFilter', 43 | 'Update-AzTableRow', 44 | 'Remove-AzTableRow', 45 | 'Get-AzTableTable' 46 | ) 47 | 48 | VariablesToExport = '' 49 | 50 | AliasesToExport = '*' 51 | 52 | } 53 | -------------------------------------------------------------------------------- /docs/Update-AzTableRow.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: AzureRmStorageTableCoreHelper-help.xml 3 | Module Name: azurermstoragetable 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Update-AzTableRow 9 | 10 | ## SYNOPSIS 11 | Updates a table entity 12 | 13 | ## SYNTAX 14 | 15 | ```powershell 16 | Update-AzTableRow [-Table] [-entity] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | Updates a table entity. 21 | To work with this cmdlet, you need first retrieve an entity with one of the Get-AzTableRow cmdlets available and store in an object, change the necessary properties and then perform the update passing this modified entity back, through Pipeline or as argument. Notice that this cmdlet accepts only one entity per execution. This cmdlet cannot update Partition Key and/or RowKey because it uses those two values to locate the entity to update it, if this operation is required please delete the old entity and add the new one with the updated values instead. 22 | 23 | ## EXAMPLES 24 | 25 | ### EXAMPLE 1 26 | ```powershell 27 | # Updating an entity 28 | 29 | [string]$Filter = [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition("firstName",[Microsoft.Azure.Cosmos.Table.QueryComparisons]::Equal,"User1") 30 | $person = Get-AzTableRowByCustomFilter -Table $Table -CustomFilter $Filter 31 | $person.lastName = "New Last Name" 32 | $person | Update-AzTableRow -Table $Table 33 | ``` 34 | 35 | ## PARAMETERS 36 | 37 | ### -Table 38 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable where the entity exists 39 | 40 | ```yaml 41 | Type: Object 42 | Parameter Sets: (All) 43 | Aliases: 44 | 45 | Required: True 46 | Position: 1 47 | Default value: None 48 | Accept pipeline input: False 49 | Accept wildcard characters: False 50 | ``` 51 | 52 | ### -entity 53 | The entity/row with new values to perform the update. 54 | 55 | ```yaml 56 | Type: Object 57 | Parameter Sets: (All) 58 | Aliases: 59 | 60 | Required: True 61 | Position: 2 62 | Default value: None 63 | Accept pipeline input: True (ByValue) 64 | Accept wildcard characters: False 65 | ``` 66 | 67 | ### CommonParameters 68 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). 69 | 70 | ## INPUTS 71 | 72 | ## OUTPUTS 73 | 74 | ## NOTES 75 | 76 | ## RELATED LINKS 77 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | 3 | - task: PowerShell@1 4 | displayName: "Run pester" 5 | inputs: 6 | failOnStandardError: true 7 | scriptType: inlineScript 8 | inlineScript: | 9 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 10 | 11 | Write-Verbose -Verbose "Getting pipeline variables" 12 | $Location = "$(Parameters.Location)" 13 | 14 | Write-Verbose -Verbose "Installing modules" 15 | Install-Module -Name Pester -MaximumVersion 4.10.0 -AllowClobber -Force -Scope CurrentUser 16 | Install-Module Az.Accounts -MinimumVersion 2.2.5 -AllowClobber -Force -Scope CurrentUser 17 | Install-Module Az.Storage -MinimumVersion 3.3.0 -AllowClobber -Force -Scope CurrentUser 18 | Install-Module Az.Resources -MinimumVersion 3.2.1 -AllowClobber -Force -Scope CurrentUser 19 | Install-Module Az.ManagedServiceIdentity -MinimumVersion 0.7.3 -AllowClobber -Force -Scope CurrentUser 20 | 21 | Write-Verbose -Verbose "Importing modules" 22 | Import-Module Pester -RequiredVersion 4.10.0 23 | Import-Module Az.Accounts 24 | Import-Module Az.Storage 25 | Import-Module Az.Resources 26 | Import-Module Az.ManagedServiceIdentity 27 | 28 | Write-Verbose -Verbose "Authenticating" 29 | Connect-AzAccount -Identity 30 | 31 | $SubscriptionId = (Get-AzContext).Subscription.id 32 | Write-Verbose -Verbose "Subscription-> $SubscriptionId" 33 | 34 | Set-Location "$(Build.Repository.LocalPath)" 35 | $outputFile = ".\TEST-RESULTS.xml" 36 | Invoke-Pester -OutputFile $outputFile -OutputFormat NUnitXml @{Path="./Tests";Parameters=@{SubscriptionId=$SubscriptionId;Location=$Location}} 37 | 38 | # Clean up .Azure folder 39 | Remove-Item C:\windows\ServiceProfiles\NetworkService\.Azure -Recurse -Force 40 | 41 | # Checking results to fail build if necessary 42 | [xml]$result = Get-Content .\TEST-RESULTS.xml 43 | if ($result.'test-results'.'test-suite'.result -ieq "failure") 44 | { 45 | throw "Pester has finished with failed tests" 46 | } 47 | 48 | - task: PublishTestResults@1 49 | displayName: Publish Test Results 50 | inputs: 51 | testRunTitle: Test Results for Pester 52 | buildPlatform: Windows 53 | testRunner: NUnit 54 | testResultsFiles: ./TEST-RESULTS.xml 55 | failTaskOnFailedTests: true 56 | condition: succeededOrFailed() 57 | 58 | - task: PowerShell@1 59 | displayName: "Remove result file" 60 | inputs: 61 | failOnStandardError: true 62 | scriptType: inlineScript 63 | inlineScript: | 64 | $outputFile = ".\TEST-RESULTS.xml" 65 | Remove-Item $outputFile 66 | -------------------------------------------------------------------------------- /docs/Get-AzTableRowByPartitionKeyRowKey.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: AzureRmStorageTableCoreHelper-help.xml 3 | Module Name: azurermstoragetable 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-AzTableRowByPartitionKeyRowKey 9 | 10 | ## SYNOPSIS 11 | Returns one entity based on Partition Key and RowKey 12 | 13 | ## SYNTAX 14 | 15 | ```powershell 16 | Get-AzTableRowByPartitionKeyRowKey [-Table] [-PartitionKey] [-RowKey] 17 | [[-Top] ] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | Returns one entity based on Partition Key and RowKey 22 | 23 | ## EXAMPLES 24 | 25 | ### EXAMPLE 1 26 | ```powershell 27 | # Getting rows by Partition Key and Row Key 28 | Get-AzStorageTableRowByPartitionKeyRowKey -Table $Table -PartitionKey "partition1" -RowKey "id12345" 29 | ``` 30 | 31 | ### EXAMPLE 2 32 | ```powershell 33 | # Getting rows by Partition Key and Row Key, with a maximum number returned 34 | Get-AzStorageTableRowByPartitionKeyRowKey -Table $Table -PartitionKey "partition1" -RowKey "id12345" -Top 10 35 | ``` 36 | 37 | ## PARAMETERS 38 | 39 | ### -Table 40 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable to retrieve entities 41 | 42 | ```yaml 43 | Type: Object 44 | Parameter Sets: (All) 45 | Aliases: 46 | 47 | Required: True 48 | Position: 1 49 | Default value: None 50 | Accept pipeline input: False 51 | Accept wildcard characters: False 52 | ``` 53 | 54 | ### -PartitionKey 55 | Identifies the table partition 56 | 57 | ```yaml 58 | Type: String 59 | Parameter Sets: (All) 60 | Aliases: 61 | 62 | Required: True 63 | Position: 2 64 | Default value: None 65 | Accept pipeline input: False 66 | Accept wildcard characters: False 67 | ``` 68 | 69 | ### -RowKey 70 | Identifies the row key in the partition 71 | 72 | ```yaml 73 | Type: String 74 | Parameter Sets: (All) 75 | Aliases: 76 | 77 | Required: True 78 | Position: 3 79 | Default value: None 80 | Accept pipeline input: False 81 | Accept wildcard characters: False 82 | ``` 83 | 84 | ### -Top 85 | Return only the first n rows from the query 86 | 87 | ```yaml 88 | Type: Int32 89 | Parameter Sets: (All) 90 | Aliases: 91 | 92 | Required: False 93 | Position: 4 94 | Default value: None 95 | Accept pipeline input: False 96 | Accept wildcard characters: False 97 | ``` 98 | 99 | ### CommonParameters 100 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). 101 | 102 | ## INPUTS 103 | 104 | ## OUTPUTS 105 | 106 | ## NOTES 107 | 108 | ## RELATED LINKS 109 | -------------------------------------------------------------------------------- /docs/Get-AzTableTable.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: AzureRmStorageTableCoreHelper-help.xml 3 | Module Name: azurermstoragetable 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-AzTableTable 9 | 10 | ## SYNOPSIS 11 | Gets a Table object to be used in all other cmdlets. 12 | 13 | ## SYNTAX 14 | 15 | ### AzTableStorage 16 | ```powershell 17 | Get-AzTableTable -resourceGroup -TableName -storageAccountName [] 18 | ``` 19 | 20 | ### AzStorageEmulator 21 | ```powershell 22 | Get-AzTableTable -TableName [-UseStorageEmulator] [] 23 | ``` 24 | 25 | ## DESCRIPTION 26 | Gets a Table object to be used in all other cmdlets. 27 | 28 | ## EXAMPLES 29 | 30 | ### EXAMPLE 1 31 | ```powershell 32 | # Getting storage table object 33 | $resourceGroup = "myResourceGroup" 34 | $storageAccount = "myStorageAccountName" 35 | $TableName = "table01" 36 | $Table = Get-AzTabletable -resourceGroup $resourceGroup -tableName $TableName -storageAccountName $storageAccount 37 | ``` 38 | 39 | ## PARAMETERS 40 | 41 | ### -resourceGroup 42 | Resource Group where the Azure Storage Account is located 43 | 44 | ```yaml 45 | Type: String 46 | Parameter Sets: AzTableStorage 47 | Aliases: 48 | 49 | Required: True 50 | Position: Named 51 | Default value: None 52 | Accept pipeline input: False 53 | Accept wildcard characters: False 54 | ``` 55 | 56 | ### -TableName 57 | Name of the table to retrieve 58 | 59 | ```yaml 60 | Type: String 61 | Parameter Sets: (All) 62 | Aliases: 63 | 64 | Required: True 65 | Position: Named 66 | Default value: None 67 | Accept pipeline input: False 68 | Accept wildcard characters: False 69 | ``` 70 | 71 | ### -storageAccountName 72 | Storage Account name where the table lives 73 | 74 | ```yaml 75 | Type: String 76 | Parameter Sets: AzTableStorage 77 | Aliases: 78 | 79 | Required: True 80 | Position: Named 81 | Default value: None 82 | Accept pipeline input: False 83 | Accept wildcard characters: False 84 | ``` 85 | 86 | ### -UseStorageEmulator 87 | {{ Fill UseStorageEmulator Description }} 88 | 89 | ```yaml 90 | Type: SwitchParameter 91 | Parameter Sets: AzStorageEmulator 92 | Aliases: 93 | 94 | Required: True 95 | Position: Named 96 | Default value: False 97 | Accept pipeline input: False 98 | Accept wildcard characters: False 99 | ``` 100 | 101 | ### CommonParameters 102 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). 103 | 104 | ## INPUTS 105 | 106 | ## OUTPUTS 107 | 108 | ## NOTES 109 | 110 | ## RELATED LINKS 111 | -------------------------------------------------------------------------------- /docs/Get-AzTableRowByCustomFilter.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: AzureRmStorageTableCoreHelper-help.xml 3 | Module Name: azurermstoragetable 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-AzTableRowByCustomFilter 9 | 10 | ## SYNOPSIS 11 | Returns one or more rows/entities based on custom Filter. 12 | 13 | ## SYNTAX 14 | 15 | ```powershell 16 | Get-AzTableRowByCustomFilter [-Table] [-CustomFilter] [[-Top] ] [] 17 | ``` 18 | 19 | ## DESCRIPTION 20 | Returns one or more rows/entities based on custom Filter. 21 | This custom Filter can be 22 | built using the Microsoft.Azure.Cosmos.Table.TableQuery class or direct text. 23 | 24 | ## EXAMPLES 25 | 26 | ### EXAMPLE 1 27 | ```powershell 28 | # Getting row by firstname by using the class Microsoft.Azure.Cosmos.Table.TableQuery 29 | $MyFilter = "(firstName eq 'User1')" 30 | Get-AzTableRowByCustomFilter -Table $Table -CustomFilter $MyFilter 31 | ``` 32 | 33 | ### EXAMPLE 2 34 | ```powershell 35 | # Getting row by firstname by using text Filter directly (oData Filter format) 36 | Get-AzTableRowByCustomFilter -Table $Table -CustomFilter "(firstName eq 'User1') and (lastName eq 'LastName1')" 37 | ``` 38 | 39 | ### EXAMPLE 3 40 | ```powershell 41 | # Getting row by firstname with a maximum number of rows returned 42 | Get-AzTableRowByColumnName -Table $Table -ColumnName "firstName" -value "Paulo" -Operator Equal -Top 10 43 | ``` 44 | 45 | ## PARAMETERS 46 | 47 | ### -Table 48 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable to retrieve entities 49 | 50 | ```yaml 51 | Type: Object 52 | Parameter Sets: (All) 53 | Aliases: 54 | 55 | Required: True 56 | Position: 1 57 | Default value: None 58 | Accept pipeline input: False 59 | Accept wildcard characters: False 60 | ``` 61 | 62 | ### -CustomFilter 63 | Custom Filter string. 64 | 65 | ```yaml 66 | Type: String 67 | Parameter Sets: (All) 68 | Aliases: 69 | 70 | Required: True 71 | Position: 2 72 | Default value: None 73 | Accept pipeline input: False 74 | Accept wildcard characters: False 75 | ``` 76 | 77 | ### -Top 78 | Return only the first n rows from the query 79 | 80 | ```yaml 81 | Type: Int32 82 | Parameter Sets: (All) 83 | Aliases: 84 | 85 | Required: False 86 | Position: 3 87 | Default value: None 88 | Accept pipeline input: False 89 | Accept wildcard characters: False 90 | ``` 91 | 92 | ### CommonParameters 93 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). 94 | 95 | ## INPUTS 96 | 97 | ## OUTPUTS 98 | 99 | ## NOTES 100 | 101 | ## RELATED LINKS 102 | -------------------------------------------------------------------------------- /docs/Add-AzTableRow.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: AzureRmStorageTableCoreHelper-help.xml 3 | Module Name: azurermstoragetable 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Add-AzTableRow 9 | 10 | ## SYNOPSIS 11 | Adds a row/entity to a specified table 12 | 13 | ## SYNTAX 14 | 15 | ```powershell 16 | Add-AzTableRow [-Table] [-PartitionKey] [-RowKey] [[-property] ] 17 | [-UpdateExisting] [] 18 | ``` 19 | 20 | ## DESCRIPTION 21 | Adds a row/entity to a specified table 22 | 23 | ## EXAMPLES 24 | 25 | ### EXAMPLE 1 26 | ```powershell 27 | # Adding a row 28 | Add-AzTableRow -Table $Table -PartitionKey $PartitionKey -RowKey ([guid]::NewGuid().tostring()) -property @{"firstName"="Paulo";"lastName"="Costa";"role"="presenter"} 29 | ``` 30 | 31 | ## PARAMETERS 32 | 33 | ### -Table 34 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable where the entity will be added 35 | 36 | ```yaml 37 | Type: Object 38 | Parameter Sets: (All) 39 | Aliases: 40 | 41 | Required: True 42 | Position: 1 43 | Default value: None 44 | Accept pipeline input: False 45 | Accept wildcard characters: False 46 | ``` 47 | 48 | ### -PartitionKey 49 | Identifies the table partition 50 | 51 | ```yaml 52 | Type: String 53 | Parameter Sets: (All) 54 | Aliases: 55 | 56 | Required: True 57 | Position: 2 58 | Default value: None 59 | Accept pipeline input: False 60 | Accept wildcard characters: False 61 | ``` 62 | 63 | ### -RowKey 64 | Identifies a row within a partition 65 | 66 | ```yaml 67 | Type: String 68 | Parameter Sets: (All) 69 | Aliases: 70 | 71 | Required: True 72 | Position: 3 73 | Default value: None 74 | Accept pipeline input: False 75 | Accept wildcard characters: False 76 | ``` 77 | 78 | ### -property 79 | Hashtable with the columns that will be part of the entity. E.g. `@{"firstName"="Paulo";"lastName"="Marques"}` 80 | 81 | ```yaml 82 | Type: Hashtable 83 | Parameter Sets: (All) 84 | Aliases: 85 | 86 | Required: False 87 | Position: 4 88 | Default value: None 89 | Accept pipeline input: False 90 | Accept wildcard characters: False 91 | ``` 92 | 93 | ### -UpdateExisting 94 | Signalizes that command should update existing row, if such found by PartitionKey and RowKey. 95 | If not found, new row is added. 96 | 97 | ```yaml 98 | Type: SwitchParameter 99 | Parameter Sets: (All) 100 | Aliases: 101 | 102 | Required: False 103 | Position: Named 104 | Default value: False 105 | Accept pipeline input: False 106 | Accept wildcard characters: False 107 | ``` 108 | 109 | ### CommonParameters 110 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). 111 | 112 | ## INPUTS 113 | 114 | ## OUTPUTS 115 | 116 | ## NOTES 117 | 118 | ## RELATED LINKS 119 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # AzureRmStorageTable 3 | Repository for a sample module to manipulate Azure Storage Table rows/entities. 4 | For a complete documentation with examples, troubleshooting guide, etc. , please refer to [this](./docs/README.md) link. 5 | 6 | ## Build Status per Branch 7 | 8 | ### staging 9 | [![Build Status](https://dev.azure.com/paulomarquesc/AzureRmStorage/_apis/build/status/paulomarquesc.AzureRmStorageTable?branchName=staging)](https://dev.azure.com/paulomarquesc/AzureRmStorage/_build/latest?definitionId=4&branchName=staging) 10 | 11 | ### master 12 | [![Build Status](https://dev.azure.com/paulomarquesc/AzureRmStorage/_apis/build/status/paulomarquesc.AzureRmStorageTable?branchName=staging)](https://dev.azure.com/paulomarquesc/AzureRmStorage/_build/latest?definitionId=4&branchName=master) 13 | 14 | This module supports only *Azure Storage Tables*. 15 | 16 | This module now works with PS 5.1, and PS 6 (core) on Windows and Linux. 17 | 18 | ## Requirements 19 | 20 | Minimum requirements are (these are covered if you install the full Az module version 1.6 or greater): 21 | 22 | * Az.Storage - 1.1.0 or greater 23 | * Az.Resources - 1.2.0 or greater 24 | 25 | > Note: The previous PowerShell module (AzureRM) is not supported on this newer version. 26 | 27 | ## Quick Setup 28 | 1. In a Windows Server 2016/Windows 10 execute the following cmdlets in order to install required modules 29 | ```powershell 30 | Install-Module Az.Resources -AllowClobber -Force 31 | Install-Module Az.Storage -AllowClobber -Force 32 | ``` 33 | 34 | 2. Install AzureRmStorageTable 35 | ```powershell 36 | Install-Module AzureRmStorageTable 37 | ``` 38 | 39 | Below you will get the help content of every function that is exposed through the AzureRmStorageTable module: 40 | 41 | * [Add-AzTableRow](docs/Add-AzTableRow.md) 42 | * [Get-AzTableRow](docs/Get-AzTableRow.md) 43 | * [Get-AzTableRowAll](docs/Get-AzTableRowAll.md) 44 | * [Get-AzTableRowByColumnName](docs/Get-AzTableRowByColumnName.md) 45 | * [Get-AzTableRowByCustomFilter](docs/Get-AzTableRowByCustomFilter.md) 46 | * [Get-AzTableRowByPartitionKey](docs/Get-AzTableRowByPartitionKey.md) 47 | * [Get-AzTableRowByPartitionKeyRowKey](docs/Get-AzTableRowByPartitionKeyRowKey.md) 48 | * [Get-AzTableTable](docs/Get-AzTableTable.md) 49 | * [Remove-AzTableRow](docs/Remove-AzTableRow.md) 50 | * [Update-AzTableRow](docs/Update-AzTableRow.md) 51 | 52 | > Note: Cmdlets Get-AzTableRowAll, Get-AzTableRowByColumnName, Get-AzTableRowByCustomFilter, Get-AzTableRowByPartitionKey, Get-AzTableRowByPartitionKeyRowKey, Get-AzTableRowByPartitionKeyRowKey are deprecated and **Get-AzTableRow** should be used instead, these will all be removed in a future release of this module. 53 | 54 | # Running automated tests 55 | 56 | ## Prerequisites 57 | 58 | * [Pester](https://github.com/pester/Pester) - PowerShell BDD style testing framework 59 | * [Azure Storage Emulator](https://docs.microsoft.com/en-us/azure/storage/storage-use-emulator) or [Azure Subscription](https://azure.microsoft.com/en-us/free/) 60 | * [Azure Power Shell](https://docs.microsoft.com/en-us/powershell/azure/overview) 61 | 62 | ## How to run automated tests 63 | 64 | ### Before you run 65 | 66 | Please make sure that your Azure Storage Emulator is up and running if you want to run all tests against it. 67 | 68 | ### Run 69 | 70 | ``` 71 | PS> Invoke-Pester 72 | ``` 73 | 74 | To test on Azure instead of Storage Emmulator, use: 75 | 76 | ``` 77 | PS> Invoke-Pester @{Path="./Tests";Parameters=@{SubscriptionId='';Location=''}} 78 | ``` 79 | 80 | ![Invoke-Pester](AzureRmStorageTable-Pester.gif) 81 | -------------------------------------------------------------------------------- /docs/Remove-AzTableRow.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: AzureRmStorageTableCoreHelper-help.xml 3 | Module Name: azurermstoragetable 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Remove-AzTableRow 9 | 10 | ## SYNOPSIS 11 | Remove-AzTableRow - Removes a specified table row 12 | 13 | ## SYNTAX 14 | 15 | ### byEntityPSObjectObject 16 | ```powershell 17 | Remove-AzTableRow -Table -entity [] 18 | ``` 19 | 20 | ### byPartitionandRowKeys 21 | ```powershell 22 | Remove-AzTableRow -Table -PartitionKey -RowKey [] 23 | ``` 24 | 25 | ## DESCRIPTION 26 | Remove-AzTableRow - Removes a specified table row. 27 | It accepts multiple deletions through the Pipeline when passing entities returned from the Get-AzTableRow available cmdlets. It also can delete a row/entity using Partition and Row Key properties directly. 28 | 29 | ## EXAMPLES 30 | 31 | ### EXAMPLE 1 32 | ```powershell 33 | # Deleting an entry by entity PS Object 34 | [string]$Filter1 = [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition("firstName",[Microsoft.Azure.Cosmos.Table.QueryComparisons]::Equal,"Paulo") 35 | [string]$Filter2 = [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition("lastName",[Microsoft.Azure.Cosmos.Table.QueryComparisons]::Equal,"Marques") 36 | [string]$finalFilter = [Microsoft.Azure.Cosmos.Table.TableQuery]::CombineFilters($Filter1,"and",$Filter2) 37 | $personToDelete = Get-AzTableRowByCustomFilter -Table $Table -CustomFilter $finalFilter 38 | $personToDelete | Remove-AzTableRow -Table $Table 39 | ``` 40 | 41 | ### EXAMPLE 2 42 | ```powershell 43 | # Deleting an entry by using PartitionKey and row key directly 44 | Remove-AzTableRow -Table $Table -PartitionKey "TableEntityDemoFullList" -RowKey "399b58af-4f26-48b4-9b40-e28a8b03e867" 45 | ``` 46 | 47 | ### EXAMPLE 3 48 | ```powershell 49 | # Deleting everything 50 | Get-AzTableRowAll -Table $Table | Remove-AzTableRow -Table $Table 51 | ``` 52 | 53 | ## PARAMETERS 54 | 55 | ### -Table 56 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable where the entity exists 57 | 58 | ```yaml 59 | Type: Object 60 | Parameter Sets: (All) 61 | Aliases: 62 | 63 | Required: True 64 | Position: Named 65 | Default value: None 66 | Accept pipeline input: False 67 | Accept wildcard characters: False 68 | ``` 69 | 70 | ### -entity 71 | {{ Fill entity Description }} 72 | 73 | ```yaml 74 | Type: Object 75 | Parameter Sets: byEntityPSObjectObject 76 | Aliases: 77 | 78 | Required: True 79 | Position: Named 80 | Default value: None 81 | Accept pipeline input: True (ByValue) 82 | Accept wildcard characters: False 83 | ``` 84 | 85 | ### -PartitionKey 86 | {{ Fill PartitionKey Description }} 87 | 88 | ```yaml 89 | Type: String 90 | Parameter Sets: byPartitionandRowKeys 91 | Aliases: 92 | 93 | Required: True 94 | Position: Named 95 | Default value: None 96 | Accept pipeline input: False 97 | Accept wildcard characters: False 98 | ``` 99 | 100 | ### -RowKey 101 | {{ Fill RowKey Description }} 102 | 103 | ```yaml 104 | Type: String 105 | Parameter Sets: byPartitionandRowKeys 106 | Aliases: 107 | 108 | Required: True 109 | Position: Named 110 | Default value: None 111 | Accept pipeline input: False 112 | Accept wildcard characters: False 113 | ``` 114 | 115 | ### CommonParameters 116 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). 117 | 118 | ## INPUTS 119 | 120 | ## OUTPUTS 121 | 122 | ## NOTES 123 | 124 | ## RELATED LINKS 125 | -------------------------------------------------------------------------------- /docs/Get-AzTableRowByColumnName.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: AzureRmStorageTableCoreHelper-help.xml 3 | Module Name: azurermstoragetable 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-AzTableRowByColumnName 9 | 10 | ## SYNOPSIS 11 | Returns one or more rows/entities based on a specified column and its value 12 | 13 | ## SYNTAX 14 | 15 | ### byString 16 | ```powershell 17 | Get-AzTableRowByColumnName -Table -ColumnName -Value -Operator 18 | [-Top ] [] 19 | ``` 20 | 21 | ### byGuid 22 | ```powershell 23 | Get-AzTableRowByColumnName -Table -ColumnName -GuidValue -Operator 24 | [-Top ] [] 25 | ``` 26 | 27 | ## DESCRIPTION 28 | Returns one or more rows/entities based on a specified column and its value 29 | 30 | ## EXAMPLES 31 | 32 | ### EXAMPLE 1 33 | ```powershell 34 | # Getting row by firstname 35 | Get-AzTableRowByColumnName -Table $Table -ColumnName "firstName" -value "Paulo" -Operator Equal 36 | ``` 37 | 38 | ### EXAMPLE 2 39 | ```powershell 40 | # Getting row by firstname with a maximum number of rows returned 41 | Get-AzTableRowByColumnName -Table $Table -ColumnName "firstName" -value "Paulo" -Operator Equal -Top 10 42 | ``` 43 | 44 | ## PARAMETERS 45 | 46 | ### -Table 47 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable to retrieve entities 48 | 49 | ```yaml 50 | Type: Object 51 | Parameter Sets: (All) 52 | Aliases: 53 | 54 | Required: True 55 | Position: Named 56 | Default value: None 57 | Accept pipeline input: False 58 | Accept wildcard characters: False 59 | ``` 60 | 61 | ### -ColumnName 62 | Column name to compare the value to 63 | 64 | ```yaml 65 | Type: String 66 | Parameter Sets: (All) 67 | Aliases: 68 | 69 | Required: True 70 | Position: Named 71 | Default value: None 72 | Accept pipeline input: False 73 | Accept wildcard characters: False 74 | ``` 75 | 76 | ### -Value 77 | Value that will be looked for in the defined column 78 | 79 | ```yaml 80 | Type: String 81 | Parameter Sets: byString 82 | Aliases: 83 | 84 | Required: True 85 | Position: Named 86 | Default value: None 87 | Accept pipeline input: False 88 | Accept wildcard characters: False 89 | ``` 90 | 91 | ### -GuidValue 92 | Value that will be looked for in the defined column as Guid 93 | 94 | ```yaml 95 | Type: Guid 96 | Parameter Sets: byGuid 97 | Aliases: 98 | 99 | Required: True 100 | Position: Named 101 | Default value: None 102 | Accept pipeline input: False 103 | Accept wildcard characters: False 104 | ``` 105 | 106 | ### -Operator 107 | Supported comparison Operator. 108 | Valid values are "Equal","GreaterThan","GreaterThanOrEqual","LessThan" ,"LessThanOrEqual" ,"NotEqual" 109 | 110 | ```yaml 111 | Type: String 112 | Parameter Sets: (All) 113 | Aliases: 114 | 115 | Required: True 116 | Position: Named 117 | Default value: None 118 | Accept pipeline input: False 119 | Accept wildcard characters: False 120 | ``` 121 | 122 | ### -Top 123 | Return only the first n rows from the query 124 | 125 | ```yaml 126 | Type: Int32 127 | Parameter Sets: (All) 128 | Aliases: 129 | 130 | Required: False 131 | Position: Named 132 | Default value: None 133 | Accept pipeline input: False 134 | Accept wildcard characters: False 135 | ``` 136 | 137 | ### CommonParameters 138 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). 139 | 140 | ## INPUTS 141 | 142 | ## OUTPUTS 143 | 144 | ## NOTES 145 | 146 | ## RELATED LINKS 147 | -------------------------------------------------------------------------------- /ReleaseNotes.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | 3 | ## Version 2.1.0 4 | * Get-AzTableRow now supports two new optional parameters, `-top` and `-SelectColumn`, many thanks to @backerman and @StephenFerrero for these contributions 5 | 6 | ## Version 2.0.4 7 | * Fixed issue #59, bug related to wrong null checking while deleting a row. 8 | 9 | ## Version 2.0.3 10 | * Fixed issues with continuation token. 11 | 12 | ## Version 2.0.2 13 | * Implemented ContinuationToken logic while using ExecuteQuerySegmentedAsync to get more than 1000 rows. 14 | 15 | ## Version 2.0.1 16 | * This module now depends on Az.Storage, Az.Authentication and Az.Resources Powershell modules, this version of the module will not work anymore with AzureRM. 17 | * A major change happened on SDK side and assembly Microsoft.WindowsAzure.Storage is now replaced by Microsoft.Azure.Cosmos assembly. 18 | * Moved from sync to async methods to perform query operations. Kudos to [jakedenyer](https://github.com/jakedenyer) for his contributions in this space. 19 | * Noun "AzureStorageTable" got replaced by "AzTable" but aliases are being provided for compatibility. Notice that for automatic module load, you need to use the new noun, for the old noun, you must import the module before using a cmdlet. 20 | * All Get cmdlets got deprecated and Get-AzTableRow must be used moving forward, they are still available but they are calling Get-AzTableRow behind the scenes and will be removed in a future release. 21 | 22 | ## Version 1.0.0.23 23 | * Added parameter UpdateExisting to Add-StorageTableRow so if a row already exists you can update its content in a single operation 24 | 25 | ## Version 1.0.0.22 26 | * Removed support for Cosmos DB Tables since it will have its own module 27 | 28 | ## Version 1.0.0.21 29 | * Azure Storage Table automatic Timestamp system column is now renamed to TableTimestamp in order to avoid conflict with a possible (very possible) existence of Timestamp included by applications as an entity's property. 30 | * Cmdlet Add-StorageTableRow now has the property parameter as an optional parameter 31 | * Get-AzureStorageTableRowByColumnName cmdlet now supports guid values throught the guidValue parameter 32 | 33 | ## Version 1.0.0.20 34 | * Implemented some measures in order to avoid conflicts between different assembly versions, more specifically Microsoft.WindowsAzure.Storage.Dll. 35 | 36 | ## Version 1.0.0.19 37 | * Very minor update, changed a variable name on Get-AzureStorageTableTable function 38 | 39 | ## Version 1.0.0.18 40 | * Renamed the parameter -databasename to -cosmosDBAccount on Get-AzureStorageTableTable, -databasename is an alias to maintain compatibility 41 | 42 | ## Version 1.0.0.17 43 | * Fixed a bug with the Get-AzureStorageTableTable function where it was returning two objects, a boolean and the cloudtable when using Cosmos DB. 44 | 45 | ## Version 1.0.0.16 46 | * Fixed an issue with the parameter set for the Cosmos DB, it was missing the resource group parameter on it and therefore causing an error saying that the parameterset could not be identified. 47 | 48 | ## Version 1.0.0.15 49 | * Included etag on returned PSObject entities 50 | * Removed extra query to the table when updating an entity in order to be able to make optimistic locking work (it will trigger error 412 if someone else changed the entity), for locking mechanism, please refer to https://azure.microsoft.com/en-us/blog/managing-concurrency-in-microsoft-azure-storage-2/ 51 | 52 | ## Version 1.0.0.11 53 | * Fixed issue with Add-AzureStorageTableRow cmdlet related to a reference to inexisting object. 54 | 55 | ## Version 1.0.0.10 56 | * Included new cmdlet called Get-AzureStorageTableTable. 57 | * Included preview support for Azure Cosmos DB Table API. 58 | * Created a script called Install-CosmosDbInstallPreReqs.ps1 that adds the necessary assemblies for Cosmos DB. 59 | 60 | ### Version 1.0.0.9 61 | * Allowed empty strings on Partition and Row keys. 62 | * Included Pester test cases script. 63 | 64 | ### Version 1.0.0.8 65 | * Returned entities as PS Objects now include a Timestamp attribute. 66 | 67 | ### Previous versions 68 | * General bug fixes. 69 | * Inclusion of #Requires statement for required modules. 70 | * Initial publication of the module. 71 | -------------------------------------------------------------------------------- /docs/Get-AzTableRow.md: -------------------------------------------------------------------------------- 1 | --- 2 | external help file: AzureRmStorageTableCoreHelper-help.xml 3 | Module Name: azurermstoragetable 4 | online version: 5 | schema: 2.0.0 6 | --- 7 | 8 | # Get-AzTableRow 9 | 10 | ## SYNOPSIS 11 | Returns all rows/entities from a storage table - no Filtering 12 | 13 | ## SYNTAX 14 | 15 | ### byCustomFilter 16 | ```powershell 17 | Get-AzTableRow [-Table ] [-SelectColumn ] 18 | -CustomFilter [-Top ] [] 19 | ``` 20 | 21 | ### byColummnGuid 22 | ```powershell 23 | Get-AzTableRow [-Table ] [-SelectColumn ] 24 | [-ColumnName ] -GuidValue [-Operator ] [-Top ] [] 25 | ``` 26 | 27 | ### byColummnString 28 | ```powershell 29 | Get-AzTableRow [-Table ] [-SelectColumn ] 30 | -ColumnName -Value -Operator [-Top ] [] 31 | ``` 32 | 33 | ### byPartRowKeys 34 | ```powershell 35 | Get-AzTableRow [-Table ] [-SelectColumn ] 36 | [-PartitionKey ] -RowKey [-Top ] [] 37 | ``` 38 | 39 | ### byPartitionKey 40 | ```powershell 41 | Get-AzTableRow [-Table ] [-SelectColumn ] 42 | -PartitionKey [-Top ] [] 43 | ``` 44 | 45 | ### GetAll 46 | ```powershell 47 | Get-AzTableRow -Table [-SelectColumn ] 48 | [-Top ] [] 49 | ``` 50 | 51 | ### SelectColumn 52 | ```powershell 53 | Get-AzTableRow -Table [] -SelectColumn [] 54 | ``` 55 | 56 | ## DESCRIPTION 57 | Used to return entities from a table with several options, this replaces all other Get-AzTable cmdlets. 58 | 59 | ## EXAMPLES 60 | 61 | ### EXAMPLE 1 62 | ```powershell 63 | # Getting all rows 64 | Get-AzTableRow -Table $Table 65 | 66 | # Getting rows by partition key 67 | Get-AzTableRow -Table $table -partitionKey NewYorkSite 68 | 69 | # Getting specific columns 70 | Get-AzTableRow -Table $table -partitionKey NewYorkSite -SelectColumn @('computerName', 'osVersion') 71 | 72 | # Getting rows by partition and row key 73 | Get-AzTableRow -Table $table -partitionKey NewYorkSite -rowKey "afc04476-bda0-47ea-a9e9-7c739c633815" 74 | 75 | # Getting rows by Columnm Name using Guid columns in table 76 | Get-AzTableRow -Table $Table -ColumnName "id" -guidvalue ([guid]"5fda3053-4444-4d23-b8c2-b26e946338b6") -operator Equal 77 | 78 | # Getting rows by Columnm Name using string columns in table 79 | Get-AzTableRow -Table $Table -ColumnName "osVersion" -value "Windows NT 4" -operator Equal 80 | 81 | # Getting rows using Custom Filter 82 | Get-AzTableRow -Table $Table -CustomFilter "(osVersion eq 'Windows NT 4') and (computerName eq 'COMP07')" 83 | 84 | # Querying with a maximum number of rows returned 85 | Get-AzTableRow -Table $Table -partitionKey NewYorkSite -Top 10 86 | 87 | ``` 88 | 89 | ## PARAMETERS 90 | 91 | ### -Table 92 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable to retrieve entities (common to all parameter sets) 93 | 94 | ```yaml 95 | Type: Object 96 | Parameter Sets: byCustomFilter, byColummnGuid, byColummnString, byPartRowKeys, byPartitionKey 97 | Aliases: 98 | 99 | Required: False 100 | Position: Named 101 | Default value: None 102 | Accept pipeline input: False 103 | Accept wildcard characters: False 104 | ``` 105 | 106 | ```yaml 107 | Type: Object 108 | Parameter Sets: GetAll 109 | Aliases: 110 | 111 | Required: True 112 | Position: Named 113 | Default value: None 114 | Accept pipeline input: False 115 | Accept wildcard characters: False 116 | ``` 117 | 118 | ### -SelectColumn 119 | Columns to be fetched by the query 120 | 121 | ```yaml 122 | Type: System.Collections.Generic.List`1[System.String] 123 | Parameter Sets: (All) 124 | Aliases: 125 | 126 | Required: False 127 | Position: Named 128 | Default value: None 129 | Accept pipeline input: False 130 | Accept wildcard characters: False 131 | ``` 132 | 133 | ### -PartitionKey 134 | Identifies the table partition (byPartitionKey and byPartRowKeys parameter sets) 135 | 136 | ```yaml 137 | Type: String 138 | Parameter Sets: byPartRowKeys 139 | Aliases: 140 | 141 | Required: False 142 | Position: Named 143 | Default value: None 144 | Accept pipeline input: False 145 | Accept wildcard characters: False 146 | ``` 147 | 148 | ```yaml 149 | Type: String 150 | Parameter Sets: byPartitionKey 151 | Aliases: 152 | 153 | Required: True 154 | Position: Named 155 | Default value: None 156 | Accept pipeline input: False 157 | Accept wildcard characters: False 158 | ``` 159 | 160 | ### -RowKey 161 | Identifies the row key in the partition (byPartRowKeys parameter set) 162 | 163 | ```yaml 164 | Type: String 165 | Parameter Sets: byPartRowKeys 166 | Aliases: 167 | 168 | Required: True 169 | Position: Named 170 | Default value: None 171 | Accept pipeline input: False 172 | Accept wildcard characters: False 173 | ``` 174 | 175 | ### -ColumnName 176 | Column name to compare the value to (byColummnString and byColummnGuid parameter sets) 177 | 178 | ```yaml 179 | Type: String 180 | Parameter Sets: byColummnGuid 181 | Aliases: 182 | 183 | Required: False 184 | Position: Named 185 | Default value: None 186 | Accept pipeline input: False 187 | Accept wildcard characters: False 188 | ``` 189 | 190 | ```yaml 191 | Type: String 192 | Parameter Sets: byColummnString 193 | Aliases: 194 | 195 | Required: True 196 | Position: Named 197 | Default value: None 198 | Accept pipeline input: False 199 | Accept wildcard characters: False 200 | ``` 201 | 202 | ### -Value 203 | Value that will be looked for in the defined column (byColummnString parameter set) 204 | 205 | ```yaml 206 | Type: String 207 | Parameter Sets: byColummnString 208 | Aliases: 209 | 210 | Required: True 211 | Position: Named 212 | Default value: None 213 | Accept pipeline input: False 214 | Accept wildcard characters: False 215 | ``` 216 | 217 | ### -GuidValue 218 | Value that will be looked for in the defined column as Guid (byColummnGuid parameter set) 219 | 220 | ```yaml 221 | Type: Guid 222 | Parameter Sets: byColummnGuid 223 | Aliases: 224 | 225 | Required: True 226 | Position: Named 227 | Default value: None 228 | Accept pipeline input: False 229 | Accept wildcard characters: False 230 | ``` 231 | 232 | ### -Operator 233 | Supported comparison Operator. 234 | Valid values are "Equal","GreaterThan","GreaterThanOrEqual","LessThan" ,"LessThanOrEqual" ,"NotEqual" (byColummnString and byColummnGuid parameter sets) 235 | 236 | ```yaml 237 | Type: String 238 | Parameter Sets: byColummnGuid 239 | Aliases: 240 | 241 | Required: False 242 | Position: Named 243 | Default value: None 244 | Accept pipeline input: False 245 | Accept wildcard characters: False 246 | ``` 247 | 248 | ```yaml 249 | Type: String 250 | Parameter Sets: byColummnString 251 | Aliases: 252 | 253 | Required: True 254 | Position: Named 255 | Default value: None 256 | Accept pipeline input: False 257 | Accept wildcard characters: False 258 | ``` 259 | 260 | ### -CustomFilter 261 | Custom Filter string (byCustomFilter parameter set) 262 | 263 | ```yaml 264 | Type: String 265 | Parameter Sets: byCustomFilter 266 | Aliases: 267 | 268 | Required: True 269 | Position: Named 270 | Default value: None 271 | Accept pipeline input: False 272 | Accept wildcard characters: False 273 | ``` 274 | 275 | ### -Top 276 | Return only the first n rows from the query (all parameter sets) 277 | 278 | ```yaml 279 | Type: Int32 280 | Parameter Sets: (All) 281 | Aliases: 282 | 283 | Required: False 284 | Position: Named 285 | Default value: None 286 | Accept pipeline input: False 287 | Accept wildcard characters: False 288 | ``` 289 | 290 | ### CommonParameters 291 | This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216). 292 | 293 | ## INPUTS 294 | 295 | ## OUTPUTS 296 | 297 | ## NOTES 298 | 299 | ## RELATED LINKS 300 | -------------------------------------------------------------------------------- /Tests/AzureRmStorageTable.Tests.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param 3 | ( 4 | [Parameter(Mandatory=$false,ParameterSetName="AzureStorage")] 5 | [string]$Location="westus", 6 | 7 | [Parameter(Mandatory=$false,ParameterSetName="AzureStorage")] 8 | [string]$SubscriptionId 9 | ) 10 | 11 | Import-Module .\AzTable.psd1 -Force 12 | 13 | #$uniqueString = Get-Date -UFormat "PsTest%Y%m%dT%H%M%S" 14 | $uniqueString = [string]::Format("s{0}{1}",("{0:X}" -f (([guid]::NewGuid()).Guid.ToString().GetHashCode())).ToLower(), (Get-Date -UFormat "%Y%m%dT%H%M%S").ToString().ToLower()) 15 | $resourceGroup = "$uniqueString-rg" 16 | 17 | $GetAzTableTableCmdtTableName = "TestTable" 18 | 19 | Describe "AzureRmStorageTable" { 20 | BeforeAll { 21 | if ($PSCmdlet.ParameterSetName -ne "AzureStorage") 22 | { 23 | # Storage Emulator 24 | $context = Az.Storage\New-AzStorageContext -Local 25 | } 26 | else 27 | { 28 | # Storage Account 29 | Select-AzSubscription -SubscriptionId $SubscriptionId 30 | New-AzResourceGroup -Name $resourceGroup -Location $Location 31 | New-AzStorageAccount -Name $uniqueString -ResourceGroupName $resourceGroup -Location $Location -SkuName Standard_LRS -Kind StorageV2 32 | $context = (Get-AzStorageAccount -Name $uniqueString -ResourceGroupName $resourceGroup).Context 33 | } 34 | 35 | $GetTableCommand=@{$true = "-UseStorageEmulator"; $false = "-ResourceGroup `$resourceGroup -StorageAccountName `$uniqueString"}[($PSCmdlet.ParameterSetName -ne "AzureStorage")] 36 | 37 | $tables = [System.Collections.ArrayList]@() 38 | $tableNames = @("table$($uniqueString)insert", "table$($uniqueString)delete") 39 | foreach ($tableName in $tableNames) 40 | { 41 | Write-Host -for DarkGreen " Creating Storage Table $($tableName)" 42 | $Table = Invoke-Expression("Get-AzTableTable -table `$tableName $GetTableCommand") 43 | 44 | Write-Host -for Green " Created Table $($table | out-string)" 45 | $tables.Add($table) 46 | } 47 | } 48 | 49 | Context "Get-AzTableTable" { 50 | 51 | $GetTableCommand=@{$true = "-UseStorageEmulator"; $false = "-ResourceGroup `$resourceGroup -StorageAccountName `$uniqueString"}[($PSCmdlet.ParameterSetName -ne "AzureStorage")] 52 | 53 | It "Can create a new table" { 54 | $Table = Invoke-Expression("Get-AzTableTable -table `$GetAzTableTableCmdtTableName $GetTableCommand") 55 | $Table | Should not be $null 56 | } 57 | 58 | It "Can open an existing table" { 59 | $Table = Invoke-Expression("Get-AzTableTable -table `$GetAzTableTableCmdtTableName $GetTableCommand") 60 | $Table | Should not be $null 61 | } 62 | } 63 | 64 | Context "Add-AzTableRow" { 65 | BeforeAll { 66 | $tableInsert = $tables | Where-Object -Property Name -eq "table$($uniqueString)insert" 67 | } 68 | 69 | It "Can add entity" { 70 | $entity = $null 71 | $expectedPK = [guid]::NewGuid().Guid 72 | $expectedRK = [guid]::NewGuid().Guid 73 | 74 | Add-AzTableRow -table $tableInsert -partitionKey $expectedPK -rowKey $expectedRK -property @{} 75 | 76 | $entity = Get-AzTableRow -table $tableInsert 77 | 78 | $entity.PartitionKey | Should be $expectedPK 79 | $entity.RowKey | Should be $expectedRK 80 | } 81 | 82 | It "Can add entity with empty partition key" { 83 | $entity = $null 84 | $expectedPK = "" 85 | $expectedRK = [guid]::NewGuid().Guid 86 | 87 | Add-AzTableRow -table $tableInsert -partitionKey $expectedPK -rowKey $expectedRK -property @{} 88 | 89 | $entity = Get-AzTableRow -table $tableInsert -partitionKey $expectedPK 90 | 91 | $entity.PartitionKey | Should be $expectedPK 92 | $entity.RowKey | Should be $expectedRK 93 | } 94 | 95 | It "Can add entity with empty row key" { 96 | $entity = $null 97 | $expectedPK = [guid]::NewGuid().Guid 98 | $expectedRK = "" 99 | 100 | Add-AzTableRow -table $tableInsert -partitionKey $expectedPK -rowKey $expectedRK -property @{} 101 | 102 | $entity = Get-AzTableRow -table $tableInsert -columnName "RowKey" -value $expectedRK -operator Equal 103 | 104 | $entity.PartitionKey | Should be $expectedPK 105 | $entity.RowKey | Should be $expectedRK 106 | } 107 | 108 | It "Can add entity with empty partition and row keys" { 109 | $entity = $null 110 | $expectedPK = "" 111 | $expectedRK = "" 112 | 113 | Add-AzTableRow -table $tableInsert -partitionKey $expectedPK -rowKey $expectedRK -property @{} 114 | 115 | $entity = Get-AzTableRow -table $tableInsert -customFilter "(PartitionKey eq '$($expectedPK)') and (RowKey eq '$($expectedRK)')" 116 | 117 | $entity.PartitionKey | Should be $expectedPK 118 | $entity.RowKey | Should be $expectedRK 119 | } 120 | 121 | It "Can add entity with properties" { 122 | $entity = $null 123 | $expectedProperty1Content = "COMP01" 124 | $expectedProperty2Content = "Windows 10" 125 | $PK = [guid]::NewGuid().Guid 126 | $RK = [guid]::NewGuid().Guid 127 | 128 | Add-AzTableRow -table $tableInsert -partitionKey $PK -rowKey $RK -property @{"computerName"=$expectedProperty1Content;"osVersion"=$expectedProperty2Content} 129 | 130 | $entity = Get-AzTableRow -table $tableInsert -customFilter "(PartitionKey eq '$($PK)') and (RowKey eq '$($RK)')" 131 | 132 | $entity.computerName | Should be $expectedProperty1Content 133 | $entity.osVersion | Should be $expectedProperty2Content 134 | } 135 | } 136 | 137 | Context "Get-AzTableRow" { 138 | BeforeAll { 139 | $tableInsert = $tables | Where-Object -Property Name -EQ "table$($uniqueString)insert" 140 | $partitionKey = [guid]::NewGuid().tostring() 141 | $rowKey = [guid]::NewGuid().tostring() 142 | 143 | Add-AzTableRow -table $tableInsert -partitionKey $partitionKey -rowKey $rowKey -property @{"computerName"="COMP01";"osVersion"="Windows 10";"status"="OK"} 144 | Add-AzTableRow -table $tableInsert -partitionKey $partitionKey -rowKey ([guid]::NewGuid().tostring()) -property @{"computerName"="COMP02";"osVersion"="Windows 8.1";"status"="NeedsOsUpgrade"} 145 | Add-AzTableRow -table $tableInsert -partitionKey $partitionKey -rowKey ([guid]::NewGuid().tostring()) -property @{"computerName"="COMP03";"osVersion"="Windows 8.1";"status"="NeedsOsUpgrade"} 146 | Add-AzTableRow -table $tableInsert -partitionKey $partitionKey -rowKey ([guid]::NewGuid().tostring()) -property @{"computerName"="COMP04";"osVersion"="Windows XP";"status"="NeedsOsUpgrade"} 147 | } 148 | 149 | It "Can it get all rows" { 150 | $entityList = $null 151 | $expectedRowCount = 9 152 | $entityList = Get-AzTableRow -table $tableInsert 153 | $entityList.Count | Should be $expectedRowCount 154 | } 155 | 156 | It "Can it get specific columns for a specific row" { 157 | $entity = $null 158 | $expectedStringValue = "Windows 10" 159 | $entity = Get-AzTableRow -Table $tableInsert -partitionKey $partitionKey -rowKey $rowKey -SelectColumn @('osVersion', 'computerName') 160 | $entity.osVersion | Should be $expectedStringValue 161 | $entity.status | Should be $null 162 | } 163 | 164 | It "Can it get rows by partition key" { 165 | $entityList = $null 166 | $expectedRowCount = 4 167 | $entityList = Get-AzTableRow -table $tableInsert -partitionKey $partitionKey 168 | $entityList.Count | Should be $expectedRowCount 169 | } 170 | 171 | It "Can it get rows by partition key, limiting the number of results" { 172 | $entityList = $null 173 | $expectedRowCount = 2 174 | $entityList = Get-AzTableRow -table $tableInsert -partitionKey $partitionKey -Top 2 175 | $entityList.Count | Should be $expectedRowCount 176 | } 177 | 178 | It "Can it get row by partition and row key" { 179 | $entityList = $null 180 | $expectedRowCount = 1 181 | $entityList = @(Get-AzTableRow -table $tableInsert -partitionKey $partitionKey -RowKey $rowKey) 182 | $entityList.Count | Should be $expectedRowCount 183 | } 184 | 185 | It "Can it get row by column name using guid value" { 186 | $entity = $null 187 | $expectedGuidValue = [guid]::NewGuid() 188 | Add-AzTableRow -table $tableInsert -partitionKey $partitionKey -rowKey ([guid]::NewGuid().tostring())-property @{"computerName"="COMP05";"osVersion"="Windows 10";"status"="OK";"id"=$expectedGuidValue} 189 | 190 | $entity = Get-AzTableRow -Table $tableInsert -ColumnName "id" -guidvalue $expectedGuidValue -operator Equal 191 | $entity.id | Should be $expectedGuidValue 192 | } 193 | 194 | It "Can it get row by column name using string value" { 195 | $entity = $null 196 | $expectedStringValue = "COMP02" 197 | $entity = Get-AzTableRow -Table $tableInsert -ColumnName "computerName" -value $expectedStringValue -operator Equal 198 | $entity.computerName | Should be $expectedStringValue 199 | } 200 | 201 | It "Can it get row using custom filter" { 202 | $entityList = $null 203 | $expectedRowCount = 1 204 | $entityList = @(Get-AzTableRow -Table $tableInsert -CustomFilter "(osVersion eq 'Windows XP') and (computerName eq 'COMP04')") 205 | $entityList.Count | Should be $expectedRowCount 206 | } 207 | 208 | It "Can limit the number of results" { 209 | $entityList = $null 210 | $expectedRowCount = 5 211 | $entityList = Get-AzTableRow -table $tableInsert -Top 5 212 | $entityList.Count | Should be $expectedRowCount 213 | } 214 | 215 | It "Doesn't break when there are more rows than TakeCount" { 216 | $entityList = $null 217 | $expectedRowCount = 10 218 | $entityList = Get-AzTableRow -table $tableInsert -Top 86 219 | $entityList.Count | Should be $expectedRowCount 220 | } 221 | } 222 | 223 | Context "Remove-AzTableRow" { 224 | BeforeAll { 225 | $tableDelete = $tables | Where-Object -Property Name -eq "table$($uniqueString)delete" 226 | } 227 | 228 | It "Can delete entity" { 229 | $entity = $null 230 | $PK = [guid]::NewGuid().Guid 231 | $RK = [guid]::NewGuid().GUid 232 | 233 | Add-AzTableRow -table $tableDelete -partitionKey $PK -rowKey $RK -property @{} 234 | 235 | $entity = Get-AzTableRow -table $tableDelete 236 | $entity | Should Not Be $null 237 | 238 | Remove-AzTableRow -table $tableDelete -partitionKey $PK -rowKey $RK 239 | 240 | $entity = Get-AzTableRow -table $tableDelete 241 | $entity | Should Be $null 242 | } 243 | 244 | It "Can delete entity with empty partition key" { 245 | $entity = $null 246 | $PK = "" 247 | $RK = [guid]::NewGuid().Guid 248 | 249 | Add-AzTableRow -table $tableDelete -partitionKey $PK -rowKey $RK -property @{} 250 | 251 | $entity = Get-AzTableRow -table $tableDelete -partitionKey $expectedPK 252 | $entity | Should Not Be $null 253 | 254 | Remove-AzTableRow -table $tableDelete -partitionKey $PK -rowKey $RK 255 | 256 | $entity = Get-AzTableRow -table $tableDelete -partitionKey $PK 257 | $entity | Should Be $null 258 | } 259 | 260 | It "Can delete entity with empty row key" { 261 | $entity = $null 262 | $PK = [guid]::NewGuid().Guid 263 | $RK = "" 264 | 265 | Add-AzTableRow -table $tableDelete -partitionKey $PK -rowKey $RK -property @{} 266 | 267 | $entity = Get-AzTableRow -table $tableDelete -columnName "RowKey" -value $RK -operator Equal 268 | $entity | Should Not Be $null 269 | 270 | Remove-AzTableRow -table $tableDelete -partitionKey $PK -rowKey $RK 271 | 272 | $entity = Get-AzTableRow -table $tableDelete -columnName "RowKey" -value $RK -operator Equal 273 | 274 | $entity | Should Be $null 275 | } 276 | 277 | It "Can delete entity with empty partition and row keys" { 278 | $entity = $null 279 | $PK = "" 280 | $RK = "" 281 | 282 | Add-AzTableRow -table $tableDelete -partitionKey $PK -rowKey $RK -property @{} 283 | 284 | $entity = Get-AzTableRow -table $tableDelete -customFilter "(PartitionKey eq '$($PK)') and (RowKey eq '$($RK)')" 285 | $entity | Should Not Be $null 286 | 287 | Remove-AzTableRow -table $tableDelete -partitionKey $PK -rowKey $RK 288 | 289 | $entity = Get-AzTableRow -table $tableDelete -customFilter "(PartitionKey eq '$($PK)') and (RowKey eq '$($RK)')" 290 | $entity | Should Be $null 291 | } 292 | } 293 | 294 | Context "Update-AzTableRow" { 295 | BeforeAll { 296 | $tableInsert = $tables | Where-Object -Property Name -eq "table$($uniqueString)insert" 297 | } 298 | 299 | It "Can it update an entity" { 300 | $expectedValue = "NeedsOsUpgrade" 301 | 302 | [string]$filter = [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition("computerName",[Microsoft.Azure.Cosmos.Table.QueryComparisons]::Equal,"COMP03") 303 | $UpdateEntity = Get-AzTableRow -table $tableInsert -customFilter $filter 304 | $UpdateEntity.status | Should Be $expectedValue 305 | 306 | # Changing values 307 | $UpdateEntity.osVersion = "Windows 10" 308 | $UpdateEntity.status = "OK" 309 | 310 | # Updating the content 311 | $UpdateEntity | Update-AzTableRow -table $tableInsert 312 | 313 | # Getting the entity again to check the changes 314 | $UpdateEntity = Get-AzTableRow -table $tableInsert -customFilter $filter 315 | $UpdateEntity.status | Should Not Be $expectedValue 316 | } 317 | } 318 | 319 | AfterAll { 320 | Write-Host -for DarkGreen "Cleanup in process" 321 | 322 | # Removing Get-AzTableTable test table 323 | Remove-AzStorageTable $GetAzTableTableCmdtTableName -Context $context -Force 324 | 325 | foreach ($tableName in $tableNames) 326 | { 327 | Remove-AzStorageTable -Context $context -Name $tableName -Force 328 | } 329 | 330 | if ($PSCmdlet.ParameterSetName -eq "AzureStorage") 331 | { 332 | Remove-AzStorageAccount -Name $uniqueString -ResourceGroupName $resourceGroup -Force 333 | Remove-AzResourceGroup -Name $resourceGroup -Force 334 | } 335 | 336 | Write-Host -for DarkGreen "Done" 337 | } 338 | } -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Working with Azure Tables from PowerShell - AzureRmStorageTable/AzTable PS Module v2.0 2 | 3 | This document shows how to work with Azure Storage Tables from PowerShell, through a sample PowerShell module that was created for operations like Add, Retrieve, Update and Delete table rows/entities exposed as functions. Now supporting the new Az PowerShell module plus the SDK change from Microsoft.WindowsAzure.Storage to Microsoft.Azure.Cosmos assembly. 4 | 5 | ## In this document 6 | 7 | * [Updates](#updates) 8 | * [Introduction](#intro) 9 | * [Requirements](#requirements) 10 | * [Installation/Source Code](#install) 11 | * [Using Azure Storage Table PowerShell Module](#psstoragetable) 12 | * [Adding Rows/Entities](#adding) 13 | * [Retrieving Rows/Entities](#retrieving) 14 | * [Updating an entity](#updating) 15 | * [Deleting rows/entities](#deleting) 16 | * [Azure Automation](#azureautomation) 17 | * [Troubleshooting](#troubleshooting) 18 | * [References](#references) 19 | 20 | ## Updates 21 | 22 | **Update 03/11/2021**: Included a new example at the [Troubleshooting](#troubleshooting) section provided by the Storage team on how to obtain a table based SAS token and consume it within this module. 23 | 24 | **Update 08/06/2019**: Comments were removed from the original blog post due to efforts to centralize discussions and/or issues into the module repo due to this module ownership being changed. If you have any issues/comments, please file a comment/issue [here](https://github.com/paulomarquesc/AzureRmStorageTable/issues). 25 | 26 | **Update 04/04/2019**: To avoid confusion if this module supports the new Az Powershell module, a new module name was released in the PowerShell Gallery under the name **AzTable**. The old name, **AzureRmStorageTable** will be kept in the gallery for compatibility purposes, both references the same code. This document will reference the new module name only. 27 | 28 | **Update 03/26/2019**: Updates to use the new Az.Storage PowerShell module, which is now the requirement for this module to work since the old Microsoft.WindowsAzure.Storage assembly got replaced by Microsoft.Azure.Cosmos. It also runs on PowerShell core as well, tested on PS 5.1, PS 6.2 and Linux PS. Kudos to [jakedenyer](https://github.com/jakedenyer) for his contributions on async methods. 29 | 30 | **Update 03/08/2018**: Due to a number of conflicts related to assemblies needed on Storage Tables and Cosmos DB, as of this date, Cosmos DB support was removed from this module and I'll be working in a separate module for Cosmos DB and this will be release shortly. 31 | 32 | **Update 12/04/2017**: Due to a large number of customers that have applications that adds a Timestamp entity attribute to the tables, the default Azure Table system attribute called Timestamp got renamed to TableTimeStamp so customers can consume their application’s own Timestamp value and avoid conflicts, this might be a breaking change but it is a necessary change. This change is implemented on version 1.0.0.21. 33 | 34 | **Update 05/22/2017**: Since module version 1.0.0.10 it was added a cmdlet (Get-AzureStorageTableTable) and support for Azure Cosmos DB Tables, for more information please refer to Azure RM Storage Tables PowerShell module now includes support for Cosmos DB Tables blog post. 35 | 36 | **Release Notes**: For more details about updates being done in the module, please refer to its release notes on [GitHub](https://github.com/paulomarquesc/AzureRmStorageTable/blob/master/ReleaseNotes.md). 37 | 38 | ## Introduction 39 | Azure Storage Tables is one of the four Microsoft Azure Storage abstractions available (Blobs, Queues and Azure Files are the other ones) at the time that this blog was written. It is basically a way to store data in a structured way on a non relational database system (meaning, not an RDBMS system) based on key-value pairs. 40 | 41 | Since up to today there are no official cmdlets to support entity/row management inside the tables from Azure PowerShell module, I decided to create this simple module to help IT Pros to leverage this service without having knowledge of .NET framework through some simple cmdlets as follows: 42 | 43 | | **Cmdlet** | **Description** | 44 | | ---------------------------------- | ------------------------------------------------------------------------------------------------------------ | 45 | | Add-AzTableRow | Adds a row/entity to a specified table | 46 | | Get-AzTableRow | Used to return entities from a table with several options, this replaces all other Get-AzTable cmdlets. | 47 | | Get-AzTableRowAll | (Deprecated) Returns all rows/entities from a storage table - no Filtering | 48 | | Get-AzTableRowByColumnName | (Deprecated) Returns one or more rows/entities based on a specified column and its value | 49 | | Get-AzTableRowByCustomFilter | (Deprecated) Returns one or more rows/entities based on custom Filter | 50 | | Get-AzTableRowByPartitionKey | (Deprecated) Returns one or more rows/entities based on Partition Key | 51 | | Get-AzTableRowByPartitionKeyRowKey | (Deprecated) Returns one entity based on Partition Key and RowKey | 52 | | Get-AzTableTable | Gets a Table object to be used in all other cmdlets | 53 | | Remove-AzTableRow | Removes a specified table row | 54 | | Update-AzTableRow | Updates a table entity | 55 | 56 | > Note: For compatibility purposes, aliases were created for the old noun style `AzureStorageTable`. New noun, `AzTable`, is the replacement that will allow you to automatically load the `AzTable`. If you wish to continue to use the old names, make sure you explicitly load the module before using them. 57 | 58 | There are a number of use cases for an IT Pro work with Azure Tables from PowerShell where it becomes a great repository, the ones below are just few examples: 59 | 60 | * Logging for SCCM executed scripts 61 | * Azure Automation for VM expiration, shutdown, startup in classic mode (Azure Service Manager) 62 | * VM Deployment scripts, where it becomes a central location for logs 63 | * Easily extract Performance and Diagnostics data from VMs with Diagnostics enabled 64 | 65 | ## Requirements 66 | PowerShell 5.1 or greater (this is also supported on Linux PowerShell) 67 | This module requires the new [Az Modules](https://docs.microsoft.com/en-us/powershell/azure/new-azureps-module-az?view=azps-1.5.0): 68 | * Az.Storage (1.1.0 or greater) 69 | * Az.Resources (1.2.0 or greater) 70 | 71 | You can get this information by issuing the following command line from PowerShell: 72 | 73 | ```powershell 74 | Get-Module -Name "az*" -ListAvailable 75 | ``` 76 | 77 | ## Installation/Source Code 78 | Since this module is published on [PowerShell Gallery](https://www.powershellgallery.com/packages/AzTable), you can install this module directly from PowerShell 5.1 or greater and Windows 10 / Windows Server 2016 / Linux by executing the following cmdlet in an elevated (Windows) PowerShell command prompt window: 79 | 80 | ```powershell 81 | # Note: Please use one of the options below, not both, they install the same 82 | # cmdlets but the first method gives you the new module name, the old one 83 | # is being kept for compatibility purposes 84 | 85 | # RECOMMENDED: Installing the module under its new name 86 | Install-Module AzTable 87 | 88 | # If you want to keep installing through the old name 89 | Install-Module AzureRmStorageTable 90 | ``` 91 | 92 | As an alternative, you can manually download the module from my GitHub repository [here](https://github.com/paulomarquesc/AzureRmStorageTable) and extract to `C:\Program Files\WindowsPowerShell\Modules` for PowerShell 5.1 or `C:\Program Files\PowerShell\Modules` for PowerShell 6.2 , or greater, and rename the folder to AzureRmStorageTable. Please remember to **unblock** the zip file before extracting it. 93 | 94 | ## Using Azure Storage Table PowerShell Module 95 | The following steps will walk you through loading the module and perform one or more example tasks of the basic operations offered in this module. 96 | 97 | Before you start working with it, you need to authenticate to Azure and select the correct subscription if you have multiple subscriptions: 98 | 99 | ```powershell 100 | Add-AzAccount 101 | Select-AzSubscription -Subscription `` 102 | ``` 103 | 104 | Next, lets import `AzTable` PowerShell module and list the functions available on it: 105 | 106 | ```powershell 107 | # If you are still using the old module name, please replace line below with Import-Module AzureRmStorageTable 108 | Import-Module AzTable 109 | Get-Command -Module AzureRmStorageTable -CommandType Function 110 | ``` 111 | 112 | You should see the following cmdlets: 113 | 114 | ![cmdlets](./media/cmdlets.png) 115 | 116 | For the sake of simplicity, we need to define some variables at this point to make our examples a little bit more clean, please, **make sure you have an storage account already created and that you change the values of the variables below to reflect your environment**. Notice that one of the variables is called **$partitionKey**, in this example we are using only one partition, please refer to the documentation at the end of this blog in order to get a better understanding on partitions. 117 | 118 | ```powershell 119 | $resourceGroup = "Support-rg" 120 | $storageAccount = "pmcstorage07" 121 | $tableName = "mytable01" 122 | $partitionKey = "LondonSite" 123 | ``` 124 | 125 | Get a reference for your table with the following cmdlet: 126 | 127 | ```powershell 128 | $table = Get-AzTableTable -resourceGroup $resourceGroup -TableName $tableName -storageAccountName $storageAccount 129 | ``` 130 | 131 | You can check details of your table by executing typing `$table`: 132 | 133 | ![table details](./media/table_details.png) 134 | 135 | Optionally, you can obtain the table reference by using the Az.Storage cmdlets: 136 | 137 | ```powershell 138 | $SaContext = (Get-AzStorageAccount -ResourceGroupName $resourceGroup -Name $storageAccount).Context 139 | $table = (Get-AzStorageTable -Name $tableName -Context $saContext).CloudTable 140 | ``` 141 | 142 | > Note: With release of Az.Storage 1.1.0, you need to reference the CloudTable property of the table returned from Get-AzStorageTable, that was not needed in the previous versions, ideally you will use Get-AzTableTable cmdlet instead but there might be cases where you need the Get-AzStorageTable. 143 | 144 | Up to this point we just prepared our PowerShell session by authenticating, importing the module, setting up some variables and getting our table, from this point moving forward we will focus on the basic operations exposed through the module. I’m creating a section per function/operation. 145 | 146 | ### Adding Rows/Entities 147 | #### Adding lines one by one 148 | 149 | ```powershell 150 | Add-AzTableRow -table $table -partitionKey $partitionKey -rowKey ([guid]::NewGuid().tostring()) -property @{"computerName"="COMP01";"osVersion"="Windows 10";"status"="OK"} 151 | Add-AzTableRow -table $table -partitionKey $partitionKey -rowKey ([guid]::NewGuid().tostring()) -property @{"computerName"="COMP02";"osVersion"="Windows 8.1";"status"="NeedsOsUpgrade"} 152 | Add-AzTableRow -table $table -partitionKey $partitionKey -rowKey ([guid]::NewGuid().tostring()) -property @{"computerName"="COMP03";"osVersion"="Windows XP";"status"="NeedsOsUpgrade"} 153 | ``` 154 | 155 | Result, notice the 204 HttpsStatusCode, indicating that your operation succeeded. 156 | 157 | ![results](./media/image388.png) 158 | 159 | #### Getting data from a JSON string and using a foreach loop to load the data 160 | 161 | ```powershell 162 | $computerList = '[{"computerName":"COMP04","osVersion":"Windows 7","status":"OK"},{"computerName":"COMP05","osVersion":"Windows 8","status":"OK"},{"computerName":"COMP06","osVersion":"Windows XP","status":"NeedsOsUpgrade"},{"computerName":"COMP07","osVersion":"Windows NT 4","status":"NeedsOsUpgrade"}]' 163 | $newPartitionKey = "NewYorkSite" 164 | foreach ($computer in ($computerList | ConvertFrom-Json) ) 165 | { 166 | Add-AzTableRow -table $table ` 167 | -partitionKey $newPartitionKey ` 168 | -rowKey ([guid]::NewGuid().tostring()) ` 169 | -property @{"computerName"=$computer.computerName;"osVersion"=$computer.osVersion;"status"=$computer.status} 170 | } 171 | ``` 172 | 173 | ![results json](./media/image389.png) 174 | 175 | If we open [Azure Storage Explorer](https://azure.microsoft.com/en-us/features/storage-explorer/) and navigate to the table, we will see all inserted entities. 176 | 177 | ![storage explorer](./media/image390.png) 178 | 179 | ### Retrieving Rows/Entities 180 | 181 | When retrieving rows using the functions described below, they will return a **PSObject** instead of a **DynamicTableEntity** and since they will give you some extra work to manipulate/access the properties I decided to make the Get cmdlets return PSObject instead. 182 | 183 | Example a DynamicTableEntity object: 184 | ![DynamicTableEntity Object](./media/dynamicTableEntity.png) 185 | 186 | Example of PSObject when it is returned from the functions exposed in this module: 187 | ![DynamicTableEntity Object](./media/psobject.png) 188 | 189 | > Note: when working with custom queries, the properties to be used are the ones that are shown in the DynamicTableEntity. If you're bringing more rows and then will be using PowerShell features for filtering (e.g. Where-Object), then you must refer to the PSObject properties instead. 190 | 191 | #### Retrieving all rows/entities 192 | 193 | ```powershell 194 | Get-AzTableRow -Table $table | ft 195 | ``` 196 | 197 | Result 198 | 199 | ![result all](./media/image392.png) 200 | 201 | #### Getting specific columns only 202 | 203 | ```powershell 204 | $Columns = @('computerName','osVersion') 205 | Get-AzTableRow -Table $table -SelectColumn $Columns 206 | ``` 207 | 208 | #### Getting rows/entities by partition key 209 | 210 | ```powershell 211 | Get-AzTableRow -table $table –partitionKey “LondonSite” | ft 212 | ``` 213 | 214 | Result 215 | 216 | ![result by partition key](./media/image393.png) 217 | 218 | #### Getting rows/entities by specific column 219 | 220 | ```powershell 221 | Get-AzTableRow -table $table -columnName "computerName" -value "COMP01" -operator Equal 222 | ``` 223 | 224 | Result 225 | 226 | ![result by column](./media/image394.png) 227 | 228 | Example using a guid entity type: 229 | 230 | ```powershell 231 | # Creating a guid object 232 | $guid = [guid]::NewGuid() 233 | 234 | # Adding a sample row 235 | Add-AzTableRow -table $table -partitionKey "partition01" -rowKey "item1" -property @{"id"=$guid;"computerName"="COMP01";"osVersion"="Windows 10";"status"="OK"} 236 | 237 | # Getting row based on guid value of Id column using the $guid object 238 | Get-AzTableRow -table $table -columnName id -guidValue $guid -operator Equal 239 | 240 | # Getting row based on guid value of Id column by casting a guid string into guid type 241 | Get-AzTableRow -table $table -columnName id -guidValue ([guid]"30cd1759-45b3-4ead-8767-ebeef6c0d206") -operator Equal 242 | ``` 243 | 244 | ![result by column and guid](./media/guid.png) 245 | 246 | #### Queries using custom filters with help of Microsoft.Azure.Cosmos.Table.TableQuery class and direct string text 247 | 248 | The custom filter is an important option since we are not covering all data types from the module, for example datetime types. 249 | 250 | >Note: When working with logical operators (and, or, not), they are case-sensitive and must be used as lower case since the underlying SDK uses OData v3 specification. [Here](http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_LogicalOperators) you can find more information. 251 | 252 | ##### Simple filter 253 | 254 | ```powershell 255 | [string]$filter1 = [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition("computerName",[Microsoft.Azure.Cosmos.Table.QueryComparisons]::Equal,"COMP06") 256 | Get-AzTableRow -table $table -customFilter $filter1 257 | ``` 258 | 259 | Result 260 | 261 | ![simple filter](./media/image395.png) 262 | 263 | ##### Combined filter 264 | 265 | ```powershell 266 | [string]$filter1 = [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition("computerName",[Microsoft.Azure.Cosmos.Table.QueryComparisons]::Equal,"COMP03") 267 | [string]$filter2 = [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition("status",[Microsoft.Azure.Cosmos.Table.QueryComparisons]::Equal,"NeedsOsUpgrade") 268 | [string]$finalFilter = [Microsoft.Azure.Cosmos.Table.TableQuery]::CombineFilters($filter1,"and",$filter2) 269 | Get-AzTableRow -table $table -customFilter $finalFilter 270 | ``` 271 | 272 | Result 273 | 274 | ![combined filter](./media/image396.png) 275 | 276 | ##### String filter 277 | 278 | ```powershell 279 | Get-AzTableRow -table $table -customFilter "(computerName eq 'COMP07') and (status eq 'NeedsOsUpgrade')" 280 | ``` 281 | 282 | Result 283 | 284 | ![string filter](./media/image397.png) 285 | 286 | ### Updating an entity 287 | 288 | This process requires three steps: 289 | 290 | * Retrieve the row/entity to update 291 | * Perform the change on this retrieved item 292 | * Commit the change 293 | 294 | > Note: **Update-AzTableRow** function will accept one entry at a time, don’t pass an array of entities or pipe an array of entities to the function. 295 | 296 | Example: 297 | 298 | ```powershell 299 | # Creating the filter and getting original entity 300 | [string]$filter = [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition("computerName ",[Microsoft.Azure.Cosmos.Table.QueryComparisons]::Equal,"COMP03") 301 | $computer = Get-AzTableRow -table $table -customFilter $filter 302 | 303 | # Changing values 304 | $computer.osVersion = "Windows 10" 305 | $computer.status = "OK" 306 | 307 | # Updating the content 308 | $computer | Update-AzTableRow -table $table 309 | 310 | # Getting the entity again to check the changes 311 | Get-AzTableRow -table $table -customFilter $filter 312 | ``` 313 | 314 | Result 315 | 316 | ![updating](./media/image398.png) 317 | 318 | ### Deleting rows/entities 319 | 320 | Similarly to the update process here we have two steps as follows unless you know the partitionKey and rowKey properties, in this case you can delete directly: 321 | 322 | 1. Retrieve the entity 323 | 2. Delete the entity passing the retrieved one as argument 324 | 325 | #### Deleting a single row/entity by piping the entity 326 | 327 | ```powershell 328 | [string]$filter1 = [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition("computerName",[Microsoft.Azure.Cosmos.Table.QueryComparisons]::Equal,"COMP02") 329 | $computerToDelete = Get-AzTableRow -table $table -customFilter $filter1 330 | 331 | $computerToDelete | Remove-AzTableRow -table $table 332 | 333 | Get-AzTableRow -table $table -customFilter $filter1 # does not return the entity anymore 334 | ``` 335 | 336 | Result 337 | 338 | ![deleting single row by entity piping](./media/image404.png) 339 | 340 | #### Deleting a single row/entity passing entity as argument 341 | 342 | ```powershell 343 | [string]$filter1 = [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition("computerName",[Microsoft.Azure.Cosmos.Table.QueryComparisons]::Equal,"COMP06") 344 | $computerToDelete = Get-AzTableRow -table $table -customFilter $filter1 345 | 346 | Remove-AzTableRow -table $table –entity $computerToDelete 347 | 348 | Get-AzTableRow -table $table -customFilter $filter1 # does not retrieve the entity anymore 349 | ``` 350 | 351 | Result 352 | 353 | ![deleting single row by entity piping](./media/image405.png) 354 | 355 | #### Deleting an entry by using PartitionKey and RowKey directly 356 | 357 | ```powershell 358 | # Adding a sample row 359 | Add-AzTableRow -table $table -partitionKey "PartitionTest-12345" -rowKey "MyItemToBeDeleted" -property @{"computerName"="COMP99";"osVersion"="Windows 10";"status"="OK"} 360 | 361 | # Showing the new entity 362 | Get-AzTableRow -table $table –partitionKey "PartitionTest-12345" | ft 363 | 364 | # Deleting based on partition and row keys 365 | Remove-AzTableRow -table $table -partitionKey "PartitionTest-12345" -rowKey "MyItemToBeDeleted" 366 | 367 | Get-AzTableRow -table $table –partitionKey "PartitionTest-12345" | ft # Nothing returned 368 | ``` 369 | 370 | Result 371 | 372 | ![deleting single row by entity piping](./media/image406.png) 373 | 374 | #### Deleting everything 375 | 376 | ```powershell 377 | Get-AzTableRow -table $table | Remove-AzTableRow -table $table 378 | ``` 379 | 380 | ## Azure Automation 381 | 382 | In order to run this module from within Azure Automation Runbooks, please make sure you follow the steps outlined at [Az module support in Azure Automation](https://docs.microsoft.com/en-us/azure/automation/az-modules). 383 | 384 | ## Troubleshooting/Tips 385 | 386 | This section helps you troubleshoot some of the most common issues: 387 | 388 | * **Method invocation failed because [Microsoft.WindowsAzure.Commands.Common.Storage.ResourceModel.AzureStorageTable] does not contain a method named 'ExecuteQuerySegmentedAsync'**. 389 | 390 | Please refer to [this](https://github.com/paulomarquesc/AzureRmStorageTable/issues/30) issue discussion on Github repo. 391 | 392 | * **New-Object : Cannot find type [Microsoft.Azure.Cosmos.Table.TableQuery]: verify that the assembly containing this type is loaded.At C:\Program Files\WindowsPowerShell\Modules\AzureRmStorageTable\2.0.1\AzureRmStorageTableCoreHelper.psm1** 393 | 394 | Make sure you have Az.Storage (1.1.0 or greater) installed, be aware that in case of duplicated modules installed you also may have the same issue, [this](https://github.com/paulomarquesc/AzureRmStorageTable/issues/30) discussion highlight another way this may happen and how to fix it (solution 2 that I presented). 395 | 396 | * **The term 'Update-AzureStorageTableRow' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.** 397 | 398 | This error can happen with with other cmdlets as well, e.g. Get-AzureStorageTableTable, this happens because all cmdlets got renamed as previously mentioned in this article, aliases were created to keep compatibility but you need to perform an `Import-Module AzureRmStorageTable` or `Import-Module AzTable` in order to load the aliases since the module auto-load only happens for the cmdlets itself and not the aliases. I strongly advise that you rename your cmdlets as soon as possible to avoid future issues. 399 | 400 | * **(TIP) Your custom filtering requires a condition not provided by default** 401 | 402 | If your column data type is not supported directly within the module, custom filtering can help, please refer to [#issue 35](https://github.com/paulomarquesc/AzureRmStorageTable/issues/35) and that shows an example on how to use other filtering options and a link to the SDK with all supported types. 403 | 404 | * **(TIP) How to obtain the CloudTable object from a table based SAS Token** 405 | 406 | This code sample can be used as a basis on how to obtain the CloudTable object from a table SAS token: 407 | 408 | ```powershell 409 | # sample table SAS URI 410 | $tableSASUri = "https://[accountName].table.core.windows.net/[tableName]?sv=2017-07-29&tn=[tableName]&sig=[hidden]&se=2021-03-15T07%3A00%3A09Z&sp=raud" 411 | 412 | # create CloudTable object from the SAS URI 413 | $uri = [System.Uri]$tableSASUri 414 | $CloudTable= New-Object -TypeName Microsoft.Azure.Cosmos.Table.CloudTable $uri 415 | 416 | # Use the CloudTable object to run cmdlets in module AzTable 417 | Get-AzTableRow -Table $CloudTable 418 | ``` 419 | 420 | ## References 421 | 422 | For more information about Azure Storage Tables, please refer to the following documents: 423 | 424 | * [Perform Azure Table storage operations with Azure PowerShell](https://docs.microsoft.com/en-us/azure/storage/tables/table-storage-how-to-use-powershell) 425 | * [Get started with Azure Table storage using .NET](https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-how-to-use-tables) 426 | * [Azure Storage Client Library for .NET](https://msdn.microsoft.com/library/azure/mt347887.aspx) 427 | * [Getting Started with Azure Table Storage in .NET](https://azure.microsoft.com/en-us/resources/samples/storage-table-dotnet-getting-started/) 428 | * [Azure Storage Table Design Guide: Designing Scalable and Performant Tables](https://docs.microsoft.com/en-us/azure/storage/storage-table-design-guide) 429 | 430 | -------------------------------------------------------------------------------- /AzureRmStorageTableCoreHelper.psm1: -------------------------------------------------------------------------------- 1 | 2 | <# 3 | .SYNOPSIS 4 | AzureRmStorageTableCoreHelper.psm1 - PowerShell Module that contains all functions related to manipulating Azure Storage Table rows/entities. 5 | .DESCRIPTION 6 | AzureRmStorageTableCoreHelper.psm1 - PowerShell Module that contains all functions related to manipulating Azure Storage Table rows/entities. 7 | .NOTES 8 | This module depends on Az.Accounts, Az.Resources and Az.Storage PowerShell modules 9 | #> 10 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 11 | 12 | #Requires -modules Az.Storage, Az.Resources 13 | 14 | # Deprecated Message 15 | $DeprecatedMessage = "IMPORTANT: This function is deprecated and will be removed in the next release, please use Get-AzTableRow instead." 16 | 17 | # Module Functions 18 | 19 | function TestAzTableEmptyKeys 20 | { 21 | param 22 | ( 23 | [Parameter(Mandatory=$true)] 24 | $PartitionKey, 25 | 26 | [Parameter(Mandatory=$true)] 27 | $RowKey 28 | ) 29 | 30 | $CosmosEmptyKeysErrorMessage = "Cosmos DB table API does not accept empty partition or row keys when using CloudTable.Execute operation, because of this we are disabling this capability in this module and it will not proceed." 31 | 32 | if ([string]::IsNullOrEmpty($PartitionKey) -or [string]::IsNullOrEmpty($RowKey)) 33 | { 34 | Throw $CosmosEmptyKeysErrorMessage 35 | } 36 | } 37 | 38 | function ExecuteQueryAsync 39 | { 40 | param 41 | ( 42 | [Parameter(Mandatory=$true)] 43 | $Table, 44 | [Parameter(Mandatory=$true)] 45 | $TableQuery 46 | ) 47 | # Internal function 48 | # Executes query in async mode 49 | 50 | if ($TableQuery -ne $null) 51 | { 52 | $token = $null 53 | $AllRows = @() 54 | do 55 | { 56 | $Results = $Table.ExecuteQuerySegmentedAsync($TableQuery, $token) 57 | $token = $Results.Result.ContinuationToken 58 | $AllRows += $Results.Result.Results 59 | # TakeCount controls the number of results returned per page, not 60 | # for the entire query. See e.g. the note in 61 | # https://docs.microsoft.com/azure/cosmos-db/table-storage-design-guide#retrieve-large-numbers-of-entities-from-a-query 62 | if (($null -ne $token) -and ($null -ne $TableQuery.TakeCount)) 63 | { 64 | # If the take count is larger than the number of rows in this 65 | # segment, there are more rows to return. 66 | if ($TableQuery.TakeCount -gt $Results.Result.Results.Count) 67 | { 68 | $TableQuery.TakeCount -= $Results.Result.Results.Count 69 | } 70 | else 71 | { 72 | # No more rows are available in the current page. 73 | break 74 | } 75 | } 76 | } while ($token) 77 | 78 | return $AllRows 79 | } 80 | } 81 | 82 | function GetPSObjectFromEntity($entityList) 83 | { 84 | # Internal function 85 | # Converts entities output from the ExecuteQuery method of table into an array of PowerShell Objects 86 | 87 | $returnObjects = @() 88 | 89 | if (-not [string]::IsNullOrEmpty($entityList)) 90 | { 91 | foreach ($entity in $entityList) 92 | { 93 | $entityNewObj = New-Object -TypeName psobject 94 | $entity.Properties.Keys | ForEach-Object {Add-Member -InputObject $entityNewObj -Name $_ -Value $entity.Properties[$_].PropertyAsObject -MemberType NoteProperty} 95 | 96 | # Adding table entity other attributes 97 | Add-Member -InputObject $entityNewObj -Name "PartitionKey" -Value $entity.PartitionKey -MemberType NoteProperty 98 | Add-Member -InputObject $entityNewObj -Name "RowKey" -Value $entity.RowKey -MemberType NoteProperty 99 | Add-Member -InputObject $entityNewObj -Name "TableTimestamp" -Value $entity.Timestamp -MemberType NoteProperty 100 | Add-Member -InputObject $entityNewObj -Name "Etag" -Value $entity.Etag -MemberType NoteProperty 101 | 102 | $returnObjects += $entityNewObj 103 | } 104 | } 105 | 106 | return $returnObjects 107 | 108 | } 109 | 110 | 111 | function Get-AzTableTable 112 | { 113 | <# 114 | .SYNOPSIS 115 | Gets a Table object to be used in all other cmdlets. 116 | .DESCRIPTION 117 | Gets a Table object to be used in all other cmdlets. 118 | .PARAMETER resourceGroup 119 | Resource Group where the Azure Storage Account is located 120 | .PARAMETER tableName 121 | Name of the table to retrieve 122 | .PARAMETER storageAccountName 123 | Storage Account name where the table lives 124 | .EXAMPLE 125 | # Getting storage table object 126 | $resourceGroup = "myResourceGroup" 127 | $storageAccount = "myStorageAccountName" 128 | $TableName = "table01" 129 | $Table = Get-AzTabletable -resourceGroup $resourceGroup -tableName $TableName -storageAccountName $storageAccount 130 | #> 131 | [CmdletBinding()] 132 | param 133 | ( 134 | [Parameter(ParameterSetName="AzTableStorage",Mandatory=$true)] 135 | [string]$resourceGroup, 136 | 137 | [Parameter(Mandatory=$true)] 138 | [String]$TableName, 139 | 140 | [Parameter(ParameterSetName="AzTableStorage",Mandatory=$true)] 141 | [String]$storageAccountName, 142 | 143 | [Parameter(ParameterSetName="AzStorageEmulator",Mandatory=$true)] 144 | [switch]$UseStorageEmulator 145 | ) 146 | 147 | # Validating name 148 | if ($TableName.Contains("_") -or $TableName.Contains("-")) 149 | { 150 | throw "Invalid table name: $TableName" 151 | } 152 | 153 | $nullTableErrorMessage = [string]::Empty 154 | 155 | if ($PSCmdlet.ParameterSetName -ne "AzStorageEmulator") 156 | { 157 | $keys = Invoke-AzResourceAction -Action listKeys -ResourceType "Microsoft.Storage/storageAccounts" -ApiVersion "2017-10-01" -ResourceGroupName $resourceGroup -Name $storageAccountName -Force 158 | 159 | if ($keys -ne $null) 160 | { 161 | if ($PSCmdlet.ParameterSetName -eq "AzTableStorage" ) 162 | { 163 | $key = $keys.keys[0].value 164 | $endpoint = "https://{0}.table.core.windows.net" 165 | $nullTableErrorMessage = "Table $TableName could not be retrieved from $storageAccountName on resource group $resourceGroupName" 166 | } 167 | else 168 | { 169 | # Future Cosmos implementation 170 | # $key = $keys.primaryMasterKey 171 | # $endpoint = "https://{0}.table.Cosmos.azure.com" 172 | # $nullTableErrorMessage = "Table $TableName could not be retrieved from $<<>> on resource group $resourceGroupName" 173 | } 174 | } 175 | else 176 | { 177 | throw "An error ocurred while obtaining keys from $storageAccountName." 178 | } 179 | 180 | $connString = [string]::Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};TableEndpoint=$endpoint",$storageAccountName,$key) 181 | [Microsoft.Azure.Cosmos.Table.CloudStorageAccount]$storageAccount = [Microsoft.Azure.Cosmos.Table.CloudStorageAccount]::Parse($connString) 182 | [Microsoft.Azure.Cosmos.Table.CloudTableClient]$TableClient = [Microsoft.Azure.Cosmos.Table.CloudTableClient]::new($storageAccount.TableEndpoint,$storageAccount.Credentials) 183 | [Microsoft.Azure.Cosmos.Table.CloudTable]$Table = [Microsoft.Azure.Cosmos.Table.CloudTable]$TableClient.GetTableReference($TableName) 184 | 185 | $Table.CreateIfNotExistsAsync() | Out-Null 186 | } 187 | else 188 | { 189 | # https://docs.microsoft.com/en-us/azure/storage/common/storage-use-emulator 190 | $nullTableErrorMessage = "Table $TableName could not be retrieved from Azure Storage Emulator" 191 | $connString ="DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1" 192 | [Microsoft.Azure.Cosmos.Table.CloudStorageAccount]$storageAccount = [Microsoft.Azure.Cosmos.Table.CloudStorageAccount]::Parse($connString) 193 | [Microsoft.Azure.Cosmos.Table.CloudTableClient]$TableClient = [Microsoft.Azure.Cosmos.Table.CloudTableClient]::new($storageAccount.TableEndpoint,$storageAccount.Credentials) 194 | [Microsoft.Azure.Cosmos.Table.CloudTable]$Table = [Microsoft.Azure.Cosmos.Table.CloudTable]$TableClient.GetTableReference($TableName) 195 | 196 | $Table.CreateIfNotExistsAsync() | Out-Null 197 | } 198 | 199 | # Checking if there a table got returned 200 | if ($Table -eq $null) 201 | { 202 | throw $nullTableErrorMessage 203 | } 204 | 205 | return $Table 206 | } 207 | 208 | function Add-AzTableRow 209 | { 210 | <# 211 | .SYNOPSIS 212 | Adds a row/entity to a specified table 213 | .DESCRIPTION 214 | Adds a row/entity to a specified table 215 | .PARAMETER Table 216 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable where the entity will be added 217 | .PARAMETER PartitionKey 218 | Identifies the table partition 219 | .PARAMETER RowKey 220 | Identifies a row within a partition 221 | .PARAMETER Property 222 | Hashtable with the columns that will be part of the entity. e.g. @{"firstName"="Paulo";"lastName"="Marques"} 223 | .PARAMETER UpdateExisting 224 | Signalizes that command should update existing row, if such found by PartitionKey and RowKey. If not found, new row is added. 225 | .EXAMPLE 226 | # Adding a row 227 | Add-AzTableRow -Table $Table -PartitionKey $PartitionKey -RowKey ([guid]::NewGuid().tostring()) -property @{"firstName"="Paulo";"lastName"="Costa";"role"="presenter"} 228 | #> 229 | [CmdletBinding()] 230 | param 231 | ( 232 | [Parameter(Mandatory=$true)] 233 | $Table, 234 | 235 | [Parameter(Mandatory=$true)] 236 | [AllowEmptyString()] 237 | [String]$PartitionKey, 238 | 239 | [Parameter(Mandatory=$true)] 240 | [AllowEmptyString()] 241 | [String]$RowKey, 242 | 243 | [Parameter(Mandatory=$false)] 244 | [hashtable]$property, 245 | [Switch]$UpdateExisting 246 | ) 247 | 248 | # Creates the table entity with mandatory PartitionKey and RowKey arguments 249 | $entity = New-Object -TypeName "Microsoft.Azure.Cosmos.Table.DynamicTableEntity" -ArgumentList $PartitionKey, $RowKey 250 | 251 | # Adding the additional columns to the table entity 252 | foreach ($prop in $property.Keys) 253 | { 254 | if ($prop -ne "TableTimestamp") 255 | { 256 | $entity.Properties.Add($prop, $property.Item($prop)) 257 | } 258 | } 259 | 260 | if ($UpdateExisting) 261 | { 262 | return ($Table.Execute([Microsoft.Azure.Cosmos.Table.TableOperation]::InsertOrReplace($entity))) 263 | } 264 | else 265 | { 266 | return ($Table.Execute([Microsoft.Azure.Cosmos.Table.TableOperation]::Insert($entity))) 267 | } 268 | } 269 | 270 | function Get-AzTableRowAll 271 | { 272 | <# 273 | .SYNOPSIS 274 | Returns all rows/entities from a storage table - no Filtering 275 | .DESCRIPTION 276 | Returns all rows/entities from a storage table - no Filtering 277 | .PARAMETER Table 278 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable to retrieve entities 279 | .EXAMPLE 280 | # Getting all rows 281 | Get-AzTableRowAll -Table $Table 282 | #> 283 | [CmdletBinding()] 284 | param 285 | ( 286 | [Parameter(Mandatory=$true)] 287 | $Table 288 | ) 289 | 290 | Write-Verbose $DeprecatedMessage -Verbose 291 | 292 | # No Filtering 293 | 294 | $Result = Get-AzTableRow -Table $Table 295 | 296 | if (-not [string]::IsNullOrEmpty($Result)) 297 | { 298 | return $Result 299 | } 300 | 301 | } 302 | 303 | function Get-AzTableRowByPartitionKey 304 | { 305 | <# 306 | .SYNOPSIS 307 | Returns one or more rows/entities based on Partition Key 308 | .DESCRIPTION 309 | Returns one or more rows/entities based on Partition Key 310 | .PARAMETER Table 311 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable to retrieve entities 312 | .PARAMETER PartitionKey 313 | Identifies the table partition 314 | .PARAMETER Top 315 | Return only the first n rows from the query 316 | .EXAMPLE 317 | # Getting rows by partition Key 318 | Get-AzTableRowByPartitionKey -Table $Table -PartitionKey "mypartitionkey" 319 | .EXAMPLE 320 | # Getting rows by partition key with a maximum number returned 321 | Get-AzTableRowByPartitionKey -Table $Table -PartitionKey "mypartitionkey" -Top 10 322 | #> 323 | [CmdletBinding()] 324 | param 325 | ( 326 | [Parameter(Mandatory=$true)] 327 | $Table, 328 | 329 | [Parameter(Mandatory=$true)] 330 | [AllowEmptyString()] 331 | [string]$PartitionKey, 332 | 333 | [Parameter(Mandatory=$false)] 334 | [Nullable[Int32]]$Top = $null 335 | ) 336 | 337 | Write-Verbose $DeprecatedMessage -Verbose 338 | 339 | # Filtering by Partition Key 340 | $Result = Get-AzTableRow -Table $Table -PartitionKey $PartitionKey -Top $Top 341 | 342 | if (-not [string]::IsNullOrEmpty($Result)) 343 | { 344 | return $Result 345 | } 346 | 347 | } 348 | function Get-AzTableRowByPartitionKeyRowKey 349 | { 350 | <# 351 | .SYNOPSIS 352 | Returns one entity based on Partition Key and RowKey 353 | .DESCRIPTION 354 | Returns one entity based on Partition Key and RowKey 355 | .PARAMETER Table 356 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable to retrieve entities 357 | .PARAMETER PartitionKey 358 | Identifies the table partition 359 | .PARAMETER RowKey 360 | Identifies the row key in the partition 361 | .PARAMETER Top 362 | Return only the first n rows from the query 363 | .EXAMPLE 364 | # Getting rows by Partition Key and Row Key 365 | Get-AzStorageTableRowByPartitionKeyRowKey -Table $Table -PartitionKey "partition1" -RowKey "id12345" 366 | .EXAMPLE 367 | # Getting rows by Partition Key and Row Key, with a maximum number returned 368 | Get-AzStorageTableRowByPartitionKeyRowKey -Table $Table -PartitionKey "partition1" -RowKey "id12345" -Top 10 369 | #> 370 | [CmdletBinding()] 371 | param 372 | ( 373 | [Parameter(Mandatory=$true)] 374 | $Table, 375 | 376 | [Parameter(Mandatory=$true)] 377 | [AllowEmptyString()] 378 | [string]$PartitionKey, 379 | 380 | [Parameter(Mandatory=$true)] 381 | [AllowEmptyString()] 382 | [string]$RowKey, 383 | 384 | [Parameter(Mandatory=$false)] 385 | [Nullable[Int32]]$Top = $null 386 | ) 387 | 388 | # Filtering by Partition Key and Row Key 389 | 390 | Write-Verbose $DeprecatedMessage -Verbose 391 | 392 | $Result = Get-AzTableRow -Table $Table -PartitionKey $PartitionKey -RowKey $RowKey -Top $Top 393 | 394 | if (-not [string]::IsNullOrEmpty($Result)) 395 | { 396 | return $Result 397 | } 398 | } 399 | 400 | function Get-AzTableRowByColumnName 401 | { 402 | <# 403 | .SYNOPSIS 404 | Returns one or more rows/entities based on a specified column and its value 405 | .DESCRIPTION 406 | Returns one or more rows/entities based on a specified column and its value 407 | .PARAMETER Table 408 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable to retrieve entities 409 | .PARAMETER ColumnName 410 | Column name to compare the value to 411 | .PARAMETER Value 412 | Value that will be looked for in the defined column 413 | .PARAMETER GuidValue 414 | Value that will be looked for in the defined column as Guid 415 | .PARAMETER Operator 416 | Supported comparison Operator. Valid values are "Equal","GreaterThan","GreaterThanOrEqual","LessThan" ,"LessThanOrEqual" ,"NotEqual" 417 | .PARAMETER Top 418 | Return only the first n rows from the query 419 | .EXAMPLE 420 | # Getting row by firstname 421 | Get-AzTableRowByColumnName -Table $Table -ColumnName "firstName" -value "Paulo" -Operator Equal 422 | .EXAMPLE 423 | # Getting row by firstname with a maximum number of rows returned 424 | Get-AzTableRowByColumnName -Table $Table -ColumnName "firstName" -value "Paulo" -Operator Equal -Top 10 425 | #> 426 | [CmdletBinding()] 427 | param 428 | ( 429 | [Parameter(Mandatory=$true)] 430 | $Table, 431 | 432 | [Parameter(Mandatory=$true)] 433 | [string]$ColumnName, 434 | 435 | [Parameter(ParameterSetName="byString",Mandatory=$true)] 436 | [AllowEmptyString()] 437 | [string]$Value, 438 | 439 | [Parameter(ParameterSetName="byGuid",Mandatory=$true)] 440 | [guid]$GuidValue, 441 | 442 | [Parameter(Mandatory=$true)] 443 | [validateSet("Equal","GreaterThan","GreaterThanOrEqual","LessThan" ,"LessThanOrEqual" ,"NotEqual")] 444 | [string]$Operator, 445 | 446 | [Parameter(Mandatory=$false)] 447 | [Nullable[Int32]]$Top = $null 448 | ) 449 | 450 | Write-Verbose $DeprecatedMessage -Verbose 451 | 452 | # Filtering by Columnn Name 453 | 454 | if ($PSCmdlet.ParameterSetName -eq "byString") 455 | { 456 | Get-AzTableRow -Table $Table -ColumnName $ColumnName -value $Value -Operator $Operator -Top $Top 457 | } 458 | else 459 | { 460 | Get-AzTableRow -Table $Table -ColumnName $ColumnName -GuidValue $GuidValue -Operator $Operator -Top $Top 461 | } 462 | 463 | if (-not [string]::IsNullOrEmpty($Result)) 464 | { 465 | return $Result 466 | } 467 | } 468 | 469 | function Get-AzTableRowByCustomFilter 470 | { 471 | <# 472 | .SYNOPSIS 473 | Returns one or more rows/entities based on custom Filter. 474 | .DESCRIPTION 475 | Returns one or more rows/entities based on custom Filter. This custom Filter can be 476 | built using the Microsoft.Azure.Cosmos.Table.TableQuery class or direct text. 477 | .PARAMETER Table 478 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable to retrieve entities 479 | .PARAMETER CustomFilter 480 | Custom Filter string. 481 | .PARAMETER Top 482 | Return only the first n rows from the query 483 | .EXAMPLE 484 | # Getting row by firstname by using the class Microsoft.Azure.Cosmos.Table.TableQuery 485 | $MyFilter = "(firstName eq 'User1')" 486 | Get-AzTableRowByCustomFilter -Table $Table -CustomFilter $MyFilter 487 | .EXAMPLE 488 | # Getting row by firstname by using text Filter directly (oData Filter format) 489 | Get-AzTableRowByCustomFilter -Table $Table -CustomFilter "(firstName eq 'User1') and (lastName eq 'LastName1')" 490 | .EXAMPLE 491 | # Getting row by firstname by using text Filter directly with a maximum number of rows returned 492 | Get-AzTableRowByCustomFilter -Table $Table -CustomFilter "(firstName eq 'User1') and (lastName eq 'LastName1')" -Top 10 493 | #> 494 | [CmdletBinding()] 495 | param 496 | ( 497 | [Parameter(Mandatory=$true)] 498 | $Table, 499 | 500 | [Parameter(Mandatory=$true)] 501 | [string]$CustomFilter, 502 | 503 | [Parameter(Mandatory=$false)] 504 | [Nullable[Int32]]$Top = $null 505 | ) 506 | 507 | Write-Verbose $DeprecatedMessage -Verbose 508 | 509 | # Custom Filter 510 | 511 | $Result = Get-AzTableRow -Table $Table -CustomFilter $CustomFilter -Top $Top 512 | 513 | if (-not [string]::IsNullOrEmpty($Result)) 514 | { 515 | return $Result 516 | } 517 | } 518 | 519 | function Get-AzTableRow 520 | { 521 | <# 522 | .SYNOPSIS 523 | Used to return entities from a table with several options, this replaces all other Get-AzTable cmdlets. 524 | .DESCRIPTION 525 | Used to return entities from a table with several options, this replaces all other Get-AzTable cmdlets. 526 | .PARAMETER Table 527 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable to retrieve entities (common to all parameter sets) 528 | .PARAMETER PartitionKey 529 | Identifies the table partition (byPartitionKey and byPartRowKeys parameter sets) 530 | .PARAMETER RowKey 531 | Identifies the row key in the partition (byPartRowKeys parameter set) 532 | .PARAMETER SelectColumn 533 | Names of the properties to return for each entity 534 | .PARAMETER ColumnName 535 | Column name to compare the value to (byColummnString and byColummnGuid parameter sets) 536 | .PARAMETER Value 537 | Value that will be looked for in the defined column (byColummnString parameter set) 538 | .PARAMETER GuidValue 539 | Value that will be looked for in the defined column as Guid (byColummnGuid parameter set) 540 | .PARAMETER Operator 541 | Supported comparison Operator. Valid values are "Equal","GreaterThan","GreaterThanOrEqual","LessThan" ,"LessThanOrEqual" ,"NotEqual" (byColummnString and byColummnGuid parameter sets) 542 | .PARAMETER CustomFilter 543 | Custom Filter string (byCustomFilter parameter set) 544 | .PARAMETER Top 545 | Return only the first n rows from the query (all parameter sets) 546 | .EXAMPLE 547 | # Getting all rows 548 | Get-AzTableRow -Table $Table 549 | .EXAMPLE 550 | # Getting specific properties for all rows 551 | $columns = ('osVersion', 'computerName') 552 | Get-AzTableRow -Table $Table -SelectColumn $columns 553 | .EXAMPLE 554 | # Getting rows by partition key 555 | Get-AzTableRow -Table $table -partitionKey NewYorkSite 556 | .EXAMPLE 557 | # Getting rows by partition and row key 558 | Get-AzTableRow -Table $table -partitionKey NewYorkSite -rowKey "afc04476-bda0-47ea-a9e9-7c739c633815" 559 | .EXAMPLE 560 | # Getting rows by Columnm Name using Guid columns in table 561 | Get-AzTableRow -Table $Table -ColumnName "id" -guidvalue "5fda3053-4444-4d23-b8c2-b26e946338b6" -operator Equal 562 | .EXAMPLE 563 | # Getting rows by Columnm Name using string columns in table 564 | Get-AzTableRow -Table $Table -ColumnName "osVersion" -value "Windows NT 4" -operator Equal 565 | .EXAMPLE 566 | # Getting rows using Custom Filter 567 | Get-AzTableRow -Table $Table -CustomFilter "(osVersion eq 'Windows NT 4') and (computerName eq 'COMP07')" 568 | .EXAMPLE 569 | # Querying with a maximum number of rows returned 570 | Get-AzTableRow -Table $Table -partitionKey NewYorkSite -Top 10 571 | #> 572 | [CmdletBinding()] 573 | param 574 | ( 575 | [Parameter(Mandatory=$true,ParameterSetName="GetAll")] 576 | [Parameter(ParameterSetName="byPartitionKey")] 577 | [Parameter(ParameterSetName="byPartRowKeys")] 578 | [Parameter(ParameterSetName="byColummnString")] 579 | [Parameter(ParameterSetName="byColummnGuid")] 580 | [Parameter(ParameterSetName="byCustomFilter")] 581 | $Table, 582 | 583 | [Parameter(ParameterSetName="GetAll")] 584 | [Parameter(ParameterSetName="byPartitionKey")] 585 | [Parameter(ParameterSetName="byPartRowKeys")] 586 | [Parameter(ParameterSetName="byColummnString")] 587 | [Parameter(ParameterSetName="byColummnGuid")] 588 | [Parameter(ParameterSetName="byCustomFilter")] 589 | [System.Collections.Generic.List[string]]$SelectColumn, 590 | 591 | [Parameter(Mandatory=$true,ParameterSetName="byPartitionKey")] 592 | [Parameter(ParameterSetName="byPartRowKeys")] 593 | [AllowEmptyString()] 594 | [string]$PartitionKey, 595 | 596 | [Parameter(Mandatory=$true,ParameterSetName="byPartRowKeys")] 597 | [AllowEmptyString()] 598 | [string]$RowKey, 599 | 600 | [Parameter(Mandatory=$true, ParameterSetName="byColummnString")] 601 | [Parameter(ParameterSetName="byColummnGuid")] 602 | [string]$ColumnName, 603 | 604 | [Parameter(Mandatory=$true, ParameterSetName="byColummnString")] 605 | [AllowEmptyString()] 606 | [string]$Value, 607 | 608 | [Parameter(ParameterSetName="byColummnGuid",Mandatory=$true)] 609 | [guid]$GuidValue, 610 | 611 | [Parameter(Mandatory=$true, ParameterSetName="byColummnString")] 612 | [Parameter(ParameterSetName="byColummnGuid")] 613 | [validateSet("Equal","GreaterThan","GreaterThanOrEqual","LessThan" ,"LessThanOrEqual" ,"NotEqual")] 614 | [string]$Operator, 615 | 616 | [Parameter(Mandatory=$true, ParameterSetName="byCustomFilter")] 617 | [string]$CustomFilter, 618 | 619 | [Parameter(Mandatory=$false)] 620 | [Nullable[Int32]]$Top = $null 621 | ) 622 | 623 | $TableQuery = New-Object -TypeName "Microsoft.Azure.Cosmos.Table.TableQuery" 624 | 625 | # Building filters if any 626 | if ($PSCmdlet.ParameterSetName -eq "byPartitionKey") 627 | { 628 | [string]$Filter = ` 629 | [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition("PartitionKey",` 630 | [Microsoft.Azure.Cosmos.Table.QueryComparisons]::Equal,$PartitionKey) 631 | } 632 | elseif ($PSCmdlet.ParameterSetName -eq "byPartRowKeys") 633 | { 634 | [string]$FilterA = ` 635 | [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition("PartitionKey",` 636 | [Microsoft.Azure.Cosmos.Table.QueryComparisons]::Equal,$PartitionKey) 637 | 638 | [string]$FilterB = ` 639 | [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition("RowKey",` 640 | [Microsoft.Azure.Cosmos.Table.QueryComparisons]::Equal,$RowKey) 641 | 642 | [string]$Filter = [Microsoft.Azure.Cosmos.Table.TableQuery]::CombineFilters($FilterA,"and",$FilterB) 643 | } 644 | elseif ($PSCmdlet.ParameterSetName -eq "byColummnString") 645 | { 646 | [string]$Filter = ` 647 | [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition($ColumnName,[Microsoft.Azure.Cosmos.Table.QueryComparisons]::$Operator,$Value) 648 | } 649 | elseif ($PSCmdlet.ParameterSetName -eq "byColummnGuid") 650 | { 651 | [string]$Filter = ` 652 | [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterConditionForGuid($ColumnName,[Microsoft.Azure.Cosmos.Table.QueryComparisons]::$Operator,$GuidValue) 653 | } 654 | elseif ($PSCmdlet.ParameterSetName -eq "byCustomFilter") 655 | { 656 | [string]$Filter = $CustomFilter 657 | } 658 | else 659 | { 660 | [string]$filter = $null 661 | } 662 | 663 | # Adding filter if not null 664 | if (-not [string]::IsNullOrEmpty($Filter)) 665 | { 666 | $TableQuery.FilterString = $Filter 667 | } 668 | 669 | # Selecting columns if specified 670 | if ($null -ne $SelectColumn){ 671 | $TableQuery.SelectColumns = $SelectColumn 672 | } 673 | 674 | # Set number of rows to return. 675 | if ($null -ne $Top) 676 | { 677 | $TableQuery.TakeCount = $Top 678 | } 679 | 680 | # Getting results 681 | if (($TableQuery.FilterString -ne $null) -or ($PSCmdlet.ParameterSetName -eq "GetAll")) 682 | { 683 | $Result = ExecuteQueryAsync -Table $Table -TableQuery $TableQuery 684 | 685 | # if (-not [string]::IsNullOrEmpty($Result.Result.Results)) 686 | # { 687 | # return (GetPSObjectFromEntity($Result.Result.Results)) 688 | # } 689 | 690 | if (-not [string]::IsNullOrEmpty($Result)) 691 | { 692 | return (GetPSObjectFromEntity($Result)) 693 | } 694 | } 695 | } 696 | function Update-AzTableRow 697 | { 698 | <# 699 | .SYNOPSIS 700 | Updates a table entity 701 | .DESCRIPTION 702 | Updates a table entity. To work with this cmdlet, you need first retrieve an entity with one of the Get-AzTableRow cmdlets available 703 | and store in an object, change the necessary properties and then perform the update passing this modified entity back, through Pipeline or as argument. 704 | Notice that this cmdlet accepts only one entity per execution. 705 | This cmdlet cannot update Partition Key and/or RowKey because it uses those two values to locate the entity to update it, if this operation is required 706 | please delete the old entity and add the new one with the updated values instead. 707 | .PARAMETER Table 708 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable where the entity exists 709 | .PARAMETER Entity 710 | The entity/row with new values to perform the update. 711 | .EXAMPLE 712 | # Updating an entity 713 | 714 | [string]$Filter = [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition("firstName",[Microsoft.Azure.Cosmos.Table.QueryComparisons]::Equal,"User1") 715 | $person = Get-AzTableRowByCustomFilter -Table $Table -CustomFilter $Filter 716 | $person.lastName = "New Last Name" 717 | $person | Update-AzTableRow -Table $Table 718 | #> 719 | [CmdletBinding()] 720 | param 721 | ( 722 | [Parameter(Mandatory=$true)] 723 | $Table, 724 | 725 | [Parameter(Mandatory=$true,ValueFromPipeline=$true)] 726 | $entity 727 | ) 728 | 729 | # Only one entity at a time can be updated 730 | $updatedEntityList = @() 731 | $updatedEntityList += $entity 732 | 733 | if ($updatedEntityList.Count -gt 1) 734 | { 735 | throw "Update operation can happen on only one entity at a time, not in a list/array of entities." 736 | } 737 | 738 | $updatedEntity = New-Object -TypeName "Microsoft.Azure.Cosmos.Table.DynamicTableEntity" -ArgumentList $entity.PartitionKey, $entity.RowKey 739 | 740 | # Iterating over PS Object properties to add to the updated entity 741 | foreach ($prop in $entity.psobject.Properties) 742 | { 743 | if (($prop.name -ne "PartitionKey") -and ($prop.name -ne "RowKey") -and ($prop.name -ne "Timestamp") -and ($prop.name -ne "Etag") -and ($prop.name -ne "TableTimestamp")) 744 | { 745 | $updatedEntity.Properties.Add($prop.name, $prop.Value) 746 | } 747 | } 748 | 749 | $updatedEntity.ETag = $entity.Etag 750 | $updatedEntity.Timestamp = $entity.TableTimestamp 751 | 752 | # Updating the dynamic table entity to the table 753 | # return ($Table.ExecuteAsync([Microsoft.Azure.Cosmos.Table.TableOperation]::InsertOrMerge($updatedEntity))) 754 | return ($Table.Execute([Microsoft.Azure.Cosmos.Table.TableOperation]::InsertOrMerge($updatedEntity))) 755 | } 756 | 757 | function Remove-AzTableRow 758 | { 759 | <# 760 | .SYNOPSIS 761 | Remove-AzTableRow - Removes a specified table row 762 | .DESCRIPTION 763 | Remove-AzTableRow - Removes a specified table row. It accepts multiple deletions through the Pipeline when passing entities returned from the Get-AzTableRow 764 | available cmdlets. It also can delete a row/entity using Partition and Row Key properties directly. 765 | .PARAMETER Table 766 | Table object of type Microsoft.Azure.Cosmos.Table.CloudTable where the entity exists 767 | .PARAMETER Entity (ParameterSetName=byEntityPSObjectObject) 768 | The entity/row with new values to perform the deletion. 769 | .PARAMETER PartitionKey (ParameterSetName=byPartitionandRowKeys) 770 | Partition key where the entity belongs to. 771 | .PARAMETER RowKey (ParameterSetName=byPartitionandRowKeys) 772 | Row key that uniquely identifies the entity within the partition. 773 | .EXAMPLE 774 | # Deleting an entry by entity PS Object 775 | [string]$Filter1 = [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition("firstName",[Microsoft.Azure.Cosmos.Table.QueryComparisons]::Equal,"Paulo") 776 | [string]$Filter2 = [Microsoft.Azure.Cosmos.Table.TableQuery]::GenerateFilterCondition("lastName",[Microsoft.Azure.Cosmos.Table.QueryComparisons]::Equal,"Marques") 777 | [string]$finalFilter = [Microsoft.Azure.Cosmos.Table.TableQuery]::CombineFilters($Filter1,"and",$Filter2) 778 | $personToDelete = Get-AzTableRowByCustomFilter -Table $Table -CustomFilter $finalFilter 779 | $personToDelete | Remove-AzTableRow -Table $Table 780 | .EXAMPLE 781 | # Deleting an entry by using PartitionKey and row key directly 782 | Remove-AzTableRow -Table $Table -PartitionKey "TableEntityDemoFullList" -RowKey "399b58af-4f26-48b4-9b40-e28a8b03e867" 783 | .EXAMPLE 784 | # Deleting everything 785 | Get-AzTableRowAll -Table $Table | Remove-AzTableRow -Table $Table 786 | #> 787 | [CmdletBinding()] 788 | param 789 | ( 790 | [Parameter(Mandatory=$true)] 791 | $Table, 792 | 793 | [Parameter(Mandatory=$true,ValueFromPipeline=$true,ParameterSetName="byEntityPSObjectObject")] 794 | $entity, 795 | 796 | [Parameter(Mandatory=$true,ParameterSetName="byPartitionandRowKeys")] 797 | [AllowEmptyString()] 798 | [string]$PartitionKey, 799 | 800 | [Parameter(Mandatory=$true,ParameterSetName="byPartitionandRowKeys")] 801 | [AllowEmptyString()] 802 | [string]$RowKey 803 | ) 804 | 805 | begin 806 | { 807 | $updatedEntityList = @() 808 | $updatedEntityList += $entity 809 | 810 | if ($updatedEntityList.Count -gt 1) 811 | { 812 | throw "Delete operation cannot happen on an array of entities, altough you can pipe multiple items." 813 | } 814 | 815 | $Results = @() 816 | } 817 | 818 | process 819 | { 820 | if ($PSCmdlet.ParameterSetName -eq "byEntityPSObjectObject") 821 | { 822 | $PartitionKey = $entity.PartitionKey 823 | $RowKey = $entity.RowKey 824 | } 825 | 826 | $TableQuery = New-Object -TypeName "Microsoft.Azure.Cosmos.Table.TableQuery" 827 | [string]$Filter = "(PartitionKey eq '$($PartitionKey)') and (RowKey eq '$($RowKey)')" 828 | $TableQuery.FilterString = $Filter 829 | $itemToDelete = ExecuteQueryAsync -Table $Table -TableQuery $TableQuery 830 | 831 | if ($itemToDelete -ne $null) 832 | { 833 | # Converting DynamicTableEntity to TableEntity for deletion 834 | $entityToDelete = New-Object -TypeName "Microsoft.Azure.Cosmos.Table.TableEntity" 835 | $entityToDelete.ETag = $itemToDelete.Etag 836 | $entityToDelete.PartitionKey = $itemToDelete.PartitionKey 837 | $entityToDelete.RowKey = $itemToDelete.RowKey 838 | 839 | $Results += $Table.Execute([Microsoft.Azure.Cosmos.Table.TableOperation]::Delete($entityToDelete)) 840 | } 841 | } 842 | 843 | end 844 | { 845 | return ,$Results 846 | } 847 | } 848 | 849 | # Aliases 850 | New-Alias -Name Add-StorageTableRow -Value Add-AzTableRow -ErrorAction SilentlyContinue 851 | New-Alias -Name Add-AzureStorageTableRow -Value Add-AzTableRow -ErrorAction SilentlyContinue 852 | New-Alias -Name Get-AzureStorageTableTable -Value Get-AzTableTable -ErrorAction SilentlyContinue 853 | New-Alias -Name Get-AzureStorageTableRowAll -Value Get-AzTableRowAll -ErrorAction SilentlyContinue 854 | New-Alias -Name Get-AzureStorageTableRowByPartitionKey -Value Get-AzTableRowByPartitionKey -ErrorAction SilentlyContinue 855 | New-Alias -Name Get-AzureStorageTableRowByPartitionKeyRowKey -Value Get-AzTableRowByPartitionKeyRowKey -ErrorAction SilentlyContinue 856 | New-Alias -Name Get-AzureStorageTableRowByColumnName -Value Get-AzTableRowByColumnName -ErrorAction SilentlyContinue 857 | New-Alias -Name Get-AzureStorageTableRowByCustomFilter -Value Get-AzTableRowByCustomFilter -ErrorAction SilentlyContinue 858 | New-Alias -Name Get-AzureStorageTableRow -Value Get-AzTableRow -ErrorAction SilentlyContinue 859 | New-Alias -Name Update-AzureStorageTableRow -Value Update-AzTableRow -ErrorAction SilentlyContinue 860 | New-Alias -Name Remove-AzureStorageTableRow -Value Remove-AzTableRow -ErrorAction SilentlyContinue 861 | --------------------------------------------------------------------------------