├── .gitignore ├── LICENSE ├── README.md ├── Test-ResourceGraphQueries.ps1 └── queries ├── _sample-contrib-query ├── README.md └── query.txt ├── appServices ├── certificates-expiring-in-90days │ ├── README.md │ └── query.txt ├── sites-with-inbound-outbound-ip-addresses │ ├── README.md │ └── query.txt └── stopped-appServices │ ├── README.md │ └── query.txt ├── applicationGateways └── list-all-ag-and-certificates │ ├── README.md │ └── query.txt ├── generic ├── concat-string-and-split │ ├── README.md │ └── query.txt ├── count-azure-resources │ ├── README.md │ └── query.txt ├── count-by-location-and-subscriptionId │ ├── README.md │ └── query.txt ├── count-by-resource-type │ ├── README.md │ └── query.txt ├── count-by-subscriptionId │ ├── README.md │ └── query.txt ├── join-resourcecontiners-table-subscription-name │ ├── README.md │ └── query.txt └── list-delegated-subscriptions │ ├── README.md │ └── query.txt ├── keyVaults └── list-kv-identity-has-access │ ├── README.md │ └── query.txt ├── networking └── list-all-public-ip-addresses │ ├── README.md │ └── query.txt ├── storageAccounts └── storage-with-http │ ├── README.md │ └── query.txt ├── tags ├── list-all-expired │ ├── README.md │ └── query.txt ├── list-all-resourcegroups-with-missing-tag │ ├── README.md │ └── query.txt ├── list-all-resources-with-missing-tag │ ├── README.md │ └── query.txt ├── list-all-tag-names │ ├── README.md │ └── query.txt └── list-resources-with-specific-tag │ ├── README.md │ └── query.txt └── virtualMachines ├── vm-by-ostype ├── README.md └── query.txt ├── vm-by-sku ├── README.md └── query.txt ├── vm-not-using-managed-disk ├── README.md └── query.txt ├── vm-with-ip-infos ├── README.md └── query.txt ├── vm-without-antimalware-extension ├── README.md └── query.txt └── vm-without-availabilityset ├── README.md └── query.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | 3 | settings.json -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Azure Resource Graph quickstart queries 2 | 3 | This repo contains all currently available Azure Resource Graph queries contributed by ShareGate and the community. 4 | 5 | ## About source code in this repository 6 | * Query code goes under the the right `queries` folder. 7 | * Create a folder for the service it concerns (i.g.: storageAccounts, cdn, virtualNetworks). 8 | * Create a folder for your query (all lower case with dases instead of spaces). 9 | * The query goes in a `query.txt` file. 10 | * Create a README.md file to provide a title/description of what the query does. 11 | * (On Windows) Run `Test-ResourceGraphQueries.ps1` to test the queries before creating a PR. 12 | * You can place your query code in this repository by creating a PR. 13 | 14 | ## Requirements for CI of queries 15 | * PowerShell v5+ 16 | * Azure CLI 17 | * Azure CLI Resource Graph extension (`resource-graph`) 18 | 19 | ## Setup for CI 20 | * [Install Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest) 21 | * Install Azure Resource Graph extension (`az extension add --name resource-graph`) 22 | * az login 23 | 24 | ## Execute CI tests 25 | In a PowerShell session, run `.\Test-ResourceGraphQueries.ps1` for all queries 26 | 27 | or `.\Test-ResourceGraphQueries.ps1 -FolderToTest 'queries\generic\count-azure-resources'` for one in particular 28 | 29 | ## License 30 | 31 | Copyright © 2019, Groupe Sharegate inc. This code is licensed under the Apache License, Version 2.0. You may obtain a copy of this license at https://github.com/gsoft-inc/gsoft-license/blob/master/LICENSE. -------------------------------------------------------------------------------- /Test-ResourceGraphQueries.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param( 3 | [string] 4 | $FolderToTest = $PSScriptRoot 5 | ) 6 | $ErrorActionPreference = 'Stop' 7 | 8 | $settingsFilename = Join-Path $PSScriptRoot 'settings.json' 9 | 10 | if(-not (Test-Path $settingsFilename)) { 11 | az account list --query [0] | ConvertFrom-Json | Select-Object @{Name="subscriptionId";"Expression"={$_.id}} | ConvertTo-Json -Depth 10 | Out-File $settingsFilename 12 | } 13 | $settings = Get-Content -Path $settingsFilename -Raw | ConvertFrom-Json 14 | 15 | $queries = Get-ChildItem -Path $FolderToTest\query.txt -Recurse 16 | 17 | $queries | ForEach-Object { 18 | $query = ((Get-Content -Path $_.FullName -Raw) -replace '\n\d|\n|\r', ' ') -replace '"', '\"' 19 | $queryName = $_.Directory.Name 20 | Write-Host -Message "Processing: $queryName" 21 | Write-Verbose -Message "'$queryName' query: $query" 22 | 23 | $resultSize = if($PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent) { 24 | 100 25 | } else { 26 | 1 27 | } 28 | 29 | $result = az graph query -q "$query" --subscription $settings.subscriptionId 30 | # do not put anything between the graph call and the if statement 31 | if (! $?) { 32 | throw "Error during execution of: $queryName\n\nQuery: $query" 33 | } 34 | Write-Verbose -Message ("'$queryName' output:{0}{1}" -f [Environment]::NewLine, ($result -join [Environment]::NewLine)) 35 | } -------------------------------------------------------------------------------- /queries/_sample-contrib-query/README.md: -------------------------------------------------------------------------------- 1 | # Sample contribution query 2 | 3 | ## Description 4 | This query will return the count of all resources. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "count_": 16 11 | } 12 | ] 13 | ``` -------------------------------------------------------------------------------- /queries/_sample-contrib-query/query.txt: -------------------------------------------------------------------------------- 1 | summarize count() -------------------------------------------------------------------------------- /queries/appServices/certificates-expiring-in-90days/README.md: -------------------------------------------------------------------------------- 1 | # List all App Service certificates that expires within 90 days 2 | 3 | ## Description 4 | This query will return a list of App Services certificates that are already expired or will expires in the next 90 days. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "expirationDate": "2019-11-09T16:49:12.0000000Z", 11 | "friendlyName": "", 12 | "location": "eastus", 13 | "name": "A13BD5BC545E9CAA5A8DEF1E49595AA1D9971F3A-project1-uat-EastUSwebspace", 14 | "resourceGroup": "project1-uat", 15 | "subjectName": "ops.clientassertion.uat", 16 | "subscriptionId": "00000000-0000-0000-0000-000000000000", 17 | "thumbprint": "A13BD5BC545E9CAA5A8DEF1E49595AA1D9971F3A" 18 | } 19 | ] 20 | ``` 21 | -------------------------------------------------------------------------------- /queries/appServices/certificates-expiring-in-90days/query.txt: -------------------------------------------------------------------------------- 1 | where type =~ "Microsoft.Web/certificates" and properties.expirationDate <= now(90d) 2 | | extend expirationDate = tostring(properties.expirationDate) 3 | | project subscriptionId, resourceGroup, name, location, thumbprint = properties.thumbprint, expirationDate , friendlyName = properties.friendlyName, subjectName = properties.subjectName 4 | | sort by expirationDate asc -------------------------------------------------------------------------------- /queries/appServices/sites-with-inbound-outbound-ip-addresses/README.md: -------------------------------------------------------------------------------- 1 | # List all App Service sites including inbound and outbound IP addresses 2 | 3 | ## Description 4 | This query will return a list of App Services sites, including the inbound and outbound IP addresses information. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "inboundIpAddress": "54.212.27.213", 11 | "name": "poc-dev2-as-facade-yabkdmkzeals4", 12 | "outboundIpAddresses": [ 13 | "54.212.27.213", 14 | "54.212.20.147", 15 | "54.212.23.245", 16 | "54.212.16.51", 17 | "54.212.17.233" 18 | ], 19 | "resourceGroup": "poc-dev2-canadaeast", 20 | "subscriptionId": "00000000-0000-0000-0000-000000000000" 21 | } 22 | ] 23 | ``` 24 | -------------------------------------------------------------------------------- /queries/appServices/sites-with-inbound-outbound-ip-addresses/query.txt: -------------------------------------------------------------------------------- 1 | where type =~ 'Microsoft.Web/sites' 2 | | extend inboundIpAddress = properties.inboundIpAddress, outboundIpAddresses = split(properties.outboundIpAddresses, ',') 3 | | project subscriptionId, resourceGroup, name, inboundIpAddress, outboundIpAddresses -------------------------------------------------------------------------------- /queries/appServices/stopped-appServices/README.md: -------------------------------------------------------------------------------- 1 | # Retrieve a list of stopped App Services 2 | 3 | ## Description 4 | This query will return a list of App Services that have a "stopped" state 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "kind": "app", 11 | "name": "WebApp-123", 12 | "state": "Stopped" 13 | }, 14 | { 15 | "kind": "functionapp", 16 | "name": "FunctionApp-123", 17 | "state": "Stopped" 18 | } 19 | ] 20 | ``` 21 | -------------------------------------------------------------------------------- /queries/appServices/stopped-appServices/query.txt: -------------------------------------------------------------------------------- 1 | extend state = aliases['Microsoft.Web/sites/state'] 2 | | where type =~ 'Microsoft.Web/Sites' and state =~ 'Stopped' 3 | | project name, kind, state 4 | -------------------------------------------------------------------------------- /queries/applicationGateways/list-all-ag-and-certificates/README.md: -------------------------------------------------------------------------------- 1 | # List all Application Gateways and their SSL certificates information 2 | 3 | ## Description 4 | This query will return a list of Application Gateways and their SSL certificates. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "name": "poc-nag-default-64mku52k65qdy", 11 | "resourceGroup": "poc-common-canadaeast", 12 | "subscriptionId": "00000000-0000-0000-0000-000000000000", 13 | "sslCertificates": [ 14 | { 15 | "etag": "W/\"b05ce79a-b5ae-4253-a003-edc4424be963\"", 16 | "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/poc-common-canadaeast/providers/Microsoft.Network/applicationGateways/poc-common-nag-default-64mku52k65qdy/sslCertificates/Wildcard_share-gate_com", 17 | "name": "Wildcard_poc_com", 18 | "properties": { 19 | "httpListeners": [ 20 | { 21 | "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/poc-common-canadaeast/providers/Microsoft.Network/applicationGateways/poc-common-nag-default-64mku52k65qdy/httpListeners/Internal-Https", 22 | "resourceGroup": "poc-common-canadaeast" 23 | } 24 | ], 25 | "provisioningState": "Succeeded", 26 | "publicCertData": "Base64.certificate.data=" 27 | }, 28 | "resourceGroup": "poc-common-canadaeast", 29 | "type": "Microsoft.Network/applicationGateways/sslCertificates" 30 | } 31 | ] 32 | } 33 | ] 34 | ``` -------------------------------------------------------------------------------- /queries/applicationGateways/list-all-ag-and-certificates/query.txt: -------------------------------------------------------------------------------- 1 | where type =~ 'Microsoft.Network/applicationGateways' 2 | | project subscriptionId, resourceGroup, name, sslCertificates = properties.sslCertificates -------------------------------------------------------------------------------- /queries/generic/concat-string-and-split/README.md: -------------------------------------------------------------------------------- 1 | # Usage example of functions strcat and split 2 | 3 | ## Description 4 | This query will demonstrate examples for strcat and split functions 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "concatstr": "value1,value2,value3,value4", 11 | "splitstr": [ 12 | "value1", 13 | "value2", 14 | "value3", 15 | "value4" 16 | ] 17 | } 18 | ] 19 | ``` -------------------------------------------------------------------------------- /queries/generic/concat-string-and-split/query.txt: -------------------------------------------------------------------------------- 1 | take 1 2 | | extend concatstr = strcat('value1', ',', 'value2', ',value3,value4' ) 3 | | extend splitstr = split(concatstr, ',') 4 | | project concatstr, splitstr -------------------------------------------------------------------------------- /queries/generic/count-azure-resources/README.md: -------------------------------------------------------------------------------- 1 | # Count of all Azure resources 2 | 3 | ## Description 4 | This query will return the count of all Azure Resources. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "count_": 53 11 | } 12 | ] 13 | ``` -------------------------------------------------------------------------------- /queries/generic/count-azure-resources/query.txt: -------------------------------------------------------------------------------- 1 | summarize count() -------------------------------------------------------------------------------- /queries/generic/count-by-location-and-subscriptionId/README.md: -------------------------------------------------------------------------------- 1 | # Count of resource by location and subscription 2 | 3 | ## Description 4 | This query will return the count of resource by location and subscription. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "subscriptionId": "00000000-0000-0000-0000-000000000000", 11 | "location": "eastus", 12 | "count": 14 13 | }, 14 | { 15 | "subscriptionId": "00000000-0000-0000-0000-000000000000", 16 | "location": "global", 17 | "count": 2 18 | }, 19 | { 20 | "subscriptionId": "00000000-0000-0000-F000-000000000000", 21 | "location": "centralus", 22 | "count": 15 23 | } 24 | ] 25 | ``` -------------------------------------------------------------------------------- /queries/generic/count-by-location-and-subscriptionId/query.txt: -------------------------------------------------------------------------------- 1 | summarize count = count() by subscriptionId, location -------------------------------------------------------------------------------- /queries/generic/count-by-resource-type/README.md: -------------------------------------------------------------------------------- 1 | # Count of resource by type 2 | 3 | ## Description 4 | This query will return the count of resource type by type and subscription. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "count": 14, 11 | "subscriptionId": "00000000-0000-0000-0000-000000000000", 12 | "type": "microsoft.storage/storageaccounts" 13 | }, 14 | { 15 | "count": 8, 16 | "subscriptionId": "00000000-0000-0000-0000-000000000000", 17 | "type": "microsoft.insights/components" 18 | }, 19 | { 20 | "count": 1, 21 | "subscriptionId": "00000000-0000-0000-0000-000000000000", 22 | "type": "microsoft.web/serverfarms" 23 | }, 24 | { 25 | "count": 12, 26 | "subscriptionId": "00000000-0000-0000-0000-F00000000000", 27 | "type": "microsoft.web/sites" 28 | } 29 | ] 30 | ``` -------------------------------------------------------------------------------- /queries/generic/count-by-resource-type/query.txt: -------------------------------------------------------------------------------- 1 | summarize count = count() by type, subscriptionId 2 | | order by subscriptionId, type asc -------------------------------------------------------------------------------- /queries/generic/count-by-subscriptionId/README.md: -------------------------------------------------------------------------------- 1 | # Count of all Azure resources grouped by subscription 2 | 3 | ## Description 4 | This query will return the count of all resources in each subscriptions. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "count_": 47, 11 | "subscriptionId": "00000000-0000-0000-0000-000000000000" 12 | } 13 | ] 14 | ``` -------------------------------------------------------------------------------- /queries/generic/count-by-subscriptionId/query.txt: -------------------------------------------------------------------------------- 1 | summarize count() by subscriptionId -------------------------------------------------------------------------------- /queries/generic/join-resourcecontiners-table-subscription-name/README.md: -------------------------------------------------------------------------------- 1 | # Joins the ResourceContainers table to fetch subscription names 2 | 3 | ## Description 4 | This query will join the ResourceContainers table to include the subscription names to the result set 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "name": "keyVaul1", 11 | "resourceGroup": "app1", 12 | "subscriptionId": "00000000-0000-0000-0000-000000000000", 13 | "subscriptionName": "poc-dev", 14 | "type" : "microsoft.keyvault/vaults" 15 | }, 16 | { 17 | "name": "keyVaul-eastus", 18 | "resourceGroup": "app4", 19 | "subscriptionId": "10000000-0000-0000-0000-000000000000", 20 | "subscriptionName": "poc-prod", 21 | "type" : "microsoft.keyvault/vaults" 22 | } 23 | ] 24 | ``` 25 | -------------------------------------------------------------------------------- /queries/generic/join-resourcecontiners-table-subscription-name/query.txt: -------------------------------------------------------------------------------- 1 | Resources 2 | | join (ResourceContainers | where type=~'Microsoft.Resources/Subscriptions' | project subscriptionName=name, subscriptionId) on subscriptionId 3 | | project subscriptionName, subscriptionId, resourceGroup, type, name -------------------------------------------------------------------------------- /queries/generic/list-delegated-subscriptions/README.md: -------------------------------------------------------------------------------- 1 | # Retrieve a list of all delegated subscriptions 2 | 3 | ## Description 4 | This query will return a list of all subscriptions and tenants that you have delegated access to 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "subscriptionId": ""00000000-0000-0000-0000-000000000000", 11 | "tenantId": "00000000-0000-0000-0000-000000000000" 12 | } 13 | ] 14 | ``` 15 | -------------------------------------------------------------------------------- /queries/generic/list-delegated-subscriptions/query.txt: -------------------------------------------------------------------------------- 1 | distinct(tenantId), subscriptionId 2 | -------------------------------------------------------------------------------- /queries/keyVaults/list-kv-identity-has-access/README.md: -------------------------------------------------------------------------------- 1 | # List all Key Vaults with a specific AAD ObjectId in the access policy 2 | 3 | ## Description 4 | This query will return the resource and resource group names of key vaults that have a particular AAD identity objectId in their access policy. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "name": "keyVaul1", 11 | "resourceGroup": "app1", 12 | "subscriptionId": "00000000-0000-0000-0000-000000000000" 13 | }, 14 | { 15 | "name": "keyVaul-eastus", 16 | "resourceGroup": "app4", 17 | "subscriptionId": "00000000-0000-0000-0000-000000000000" 18 | } 19 | ] 20 | ``` -------------------------------------------------------------------------------- /queries/keyVaults/list-kv-identity-has-access/query.txt: -------------------------------------------------------------------------------- 1 | where type =~ "Microsoft.Keyvault/vaults" 2 | | extend p=todynamic(properties) 3 | | extend policies=todynamic(tostring(p.accessPolicies)) 4 | | mvexpand policy = policies 5 | | where tostring(policy.objectId) == 'b37354d2-a550-4ea9-97ce-d6f1ac26fe63' 6 | | project subscriptionId, resourceGroup, name -------------------------------------------------------------------------------- /queries/networking/list-all-public-ip-addresses/README.md: -------------------------------------------------------------------------------- 1 | # List all Public IP addresses 2 | 3 | ## Description 4 | This query will return all public IP addresses sorted ascending. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "ipAddress": "13.69.95.241" 11 | }, 12 | { 13 | "ipAddress": "137.118.108.230" 14 | }, 15 | { 16 | "ipAddress": "62.52.219.39" 17 | } 18 | ] 19 | ``` -------------------------------------------------------------------------------- /queries/networking/list-all-public-ip-addresses/query.txt: -------------------------------------------------------------------------------- 1 | where type contains 'publicIPAddresses' and isnotempty(properties.ipAddress) 2 | | project ipAddress = tostring(properties.ipAddress) 3 | | order by ipAddress asc -------------------------------------------------------------------------------- /queries/storageAccounts/storage-with-http/README.md: -------------------------------------------------------------------------------- 1 | # Storage accounts with HTTP enabled 2 | 3 | ## Description 4 | This query will return all storage accounts where HTTP is allowed. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "name": "storage1", 11 | "resourceGroup": "app1", 12 | "subscriptionId": "00000000-0000-0000-0000-000000000000" 13 | }, 14 | { 15 | "name": "storage2", 16 | "resourceGroup": "app4", 17 | "subscriptionId": "00000000-0000-0000-0000-000000000000" 18 | } 19 | ] 20 | ``` -------------------------------------------------------------------------------- /queries/storageAccounts/storage-with-http/query.txt: -------------------------------------------------------------------------------- 1 | where type =~ 'Microsoft.Storage/storageAccounts' 2 | | where properties.supportsHttpsTrafficOnly == 'false' 3 | | project subscriptionId, resourceGroup, name -------------------------------------------------------------------------------- /queries/tags/list-all-expired/README.md: -------------------------------------------------------------------------------- 1 | # List all resources and resource groups with an expired 'expiresOn' tag 2 | 3 | ## Description 4 | This query will return all resources & resource groups where a specific tag (i.e.: expiresOn) is present and it's value is expired. Recommended to use dates in ISO 8601 format in tag value. 5 | 6 | More info about supported datetime formats here: https://docs.microsoft.com/en-us/azure/kusto/query/scalar-data-types/datetime 7 | 8 | ## Sample output 9 | ``` 10 | [ 11 | { 12 | "expiresOn": "2019-09-20T00:00:00Z", 13 | "name": "poc-dev-vsts", 14 | "type": "microsoft.resources/subscriptions/resourcegroups" 15 | }, 16 | { 17 | "expiresOn": "2019-09-20T00:00:00Z", 18 | "name": "poc0prod0storage", 19 | "type": "microsoft.storage/storageAccounts" 20 | } 21 | ] 22 | ``` 23 | 24 | ## Note: This query is longer to execute since find() function support is not there yet we we union all without criteria at source. -------------------------------------------------------------------------------- /queries/tags/list-all-expired/query.txt: -------------------------------------------------------------------------------- 1 | Resources 2 | | union kind= inner ResourceContainers 3 | | extend expiresOn = todatetime(tags['expiresOn']) 4 | | where expiresOn <= now() 5 | | project name, type, expiresOn -------------------------------------------------------------------------------- /queries/tags/list-all-resourcegroups-with-missing-tag/README.md: -------------------------------------------------------------------------------- 1 | # List all resource groups where a specific tag is missing 2 | 3 | ## Description 4 | This query will return all resource groups where a specific tag is not present. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "name": "poc-dev-vsts", 11 | "subscriptionId": "00000000-0000-0000-0000-000000000000", 12 | "subscriptionName": "poc-dev", 13 | "tags": "" 14 | }, 15 | { 16 | "name": "poc-prod-vsts", 17 | "subscriptionId": "10000000-0000-0000-0000-000000000000", 18 | "subscriptionName": "poc-prod", 19 | ""tags": { 20 | "costCenter": "teamA", 21 | "owner": "user1@domain.com" 22 | } 23 | } 24 | ] 25 | ``` -------------------------------------------------------------------------------- /queries/tags/list-all-resourcegroups-with-missing-tag/query.txt: -------------------------------------------------------------------------------- 1 | ResourceContainers 2 | | where type=~'Microsoft.Resources/Subscriptions/resourceGroups' and isempty(tags['environment']) 3 | | join kind = inner (ResourceContainers | where type=~'Microsoft.Resources/Subscriptions' | project subscriptionName=name, subscriptionId) on subscriptionId 4 | | project subscriptionId, subscriptionName, name, tags -------------------------------------------------------------------------------- /queries/tags/list-all-resources-with-missing-tag/README.md: -------------------------------------------------------------------------------- 1 | # List all resources where a specific tag is missing 2 | 3 | ## Description 4 | This query will return all resources where a specific tag is not present. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "name": "poc-dev-vsts", 11 | "resourceGroup": "dev-infra", 12 | "subscriptionId": "00000000-0000-0000-0000-000000000000", 13 | "subscriptionName": "poc-dev", 14 | "tags": "" 15 | }, 16 | { 17 | "name": "poc-prod-vsts", 18 | "resourceGroup": "prod-infra", 19 | "subscriptionId": "10000000-0000-0000-0000-000000000000", 20 | "subscriptionName": "poc-prod", 21 | ""tags": { 22 | "costCenter": "teamA", 23 | "owner": "user1@domain.com" 24 | } 25 | } 26 | ] 27 | ``` -------------------------------------------------------------------------------- /queries/tags/list-all-resources-with-missing-tag/query.txt: -------------------------------------------------------------------------------- 1 | Resources 2 | | where isempty(tags['environment']) 3 | | join kind = inner (ResourceContainers | where type=~'Microsoft.Resources/Subscriptions' | project subscriptionName=name, subscriptionId) on subscriptionId 4 | | project subscriptionId, subscriptionName, resourceGroup, name, tags -------------------------------------------------------------------------------- /queries/tags/list-all-tag-names/README.md: -------------------------------------------------------------------------------- 1 | # List all tag names 2 | 3 | ## Description 4 | This query will return all tag key names assigned to resources. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "schema_tags": { 11 | "defaultExperience": "string", 12 | "fqdn": "string", 13 | "owner": "string", 14 | "costCenter": "string", 15 | "ms-resource-usage": "string" 16 | } 17 | } 18 | ] 19 | ``` -------------------------------------------------------------------------------- /queries/tags/list-all-tag-names/query.txt: -------------------------------------------------------------------------------- 1 | project tags 2 | | summarize buildschema(tags) -------------------------------------------------------------------------------- /queries/tags/list-resources-with-specific-tag/README.md: -------------------------------------------------------------------------------- 1 | # List resources with a specific tag value 2 | 3 | ## Description 4 | This query will return resources with a specific tag value. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "name": "poc-prod", 11 | "resourceGroup": "project1-ops-prod", 12 | "subscriptionId": "00000000-0000-0000-0000-000000000000" 13 | }, 14 | { 15 | "name": "project20prod0monitor0dat", 16 | "resourceGroup": "project2-monitoring-eastus", 17 | "subscriptionId": "00000000-0000-0000-0000-000000000000" 18 | }, 19 | { 20 | "name": "2f1776eastus2", 21 | "resourceGroup": "securitydata", 22 | "subscriptionId": "00000000-0000-0000-0000-000000000000" 23 | }, 24 | ] 25 | ``` -------------------------------------------------------------------------------- /queries/tags/list-resources-with-specific-tag/query.txt: -------------------------------------------------------------------------------- 1 | where tags['environment'] =~ 'production' 2 | | project subscriptionId, resourceGroup, name -------------------------------------------------------------------------------- /queries/virtualMachines/vm-by-ostype/README.md: -------------------------------------------------------------------------------- 1 | # Count of virtual machines by osType 2 | 3 | ## Description 4 | This query will return the count of virtual machines by osType. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "count": 43, 11 | "osType": "Linux" 12 | }, 13 | { 14 | "count": 81, 15 | "osType": "Windows" 16 | } 17 | ] 18 | ``` -------------------------------------------------------------------------------- /queries/virtualMachines/vm-by-ostype/query.txt: -------------------------------------------------------------------------------- 1 | where type =~ 'Microsoft.Compute/virtualMachines' 2 | | extend osType = tostring(properties.storageProfile.osDisk.osType) 3 | | summarize count = count() by osType -------------------------------------------------------------------------------- /queries/virtualMachines/vm-by-sku/README.md: -------------------------------------------------------------------------------- 1 | # Count of virtual machines by sku 2 | 3 | ## Description 4 | This query will return the count of virtual machines by sku (vm size). 5 | 6 | ## Sample output 7 | ``` 8 | [ { 9 | "count": 12, 10 | "sku": "Standard_B2s" 11 | }, 12 | { 13 | "count": 7, 14 | "sku": "Standard_B2ms" 15 | }, 16 | { 17 | "count": 17, 18 | "sku": "Standard_DS1_v2" 19 | }, 20 | { 21 | "count": 12, 22 | "sku": "Standard_D2s_v3" 23 | }, 24 | { 25 | "count": 1, 26 | "sku": "Standard_F8s_v2" 27 | } 28 | ] 29 | ``` -------------------------------------------------------------------------------- /queries/virtualMachines/vm-by-sku/query.txt: -------------------------------------------------------------------------------- 1 | where type =~ 'Microsoft.Compute/virtualMachines' 2 | | project sku = tostring(properties.hardwareProfile.vmSize) 3 | | summarize count = count() by sku -------------------------------------------------------------------------------- /queries/virtualMachines/vm-not-using-managed-disk/README.md: -------------------------------------------------------------------------------- 1 | # All virtual machines not using managed disk 2 | 3 | ## Description 4 | This query will return all virtual machines that are not using managed disk. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "name": "vm1", 11 | "resourceGroup": "app1", 12 | "subscriptionId": "00000000-0000-0000-0000-000000000000" 13 | }, 14 | { 15 | "name": "vm2", 16 | "resourceGroup": "app2", 17 | "subscriptionId": "00000000-0000-0000-0000-000000000000" 18 | } 19 | ] 20 | ``` -------------------------------------------------------------------------------- /queries/virtualMachines/vm-not-using-managed-disk/query.txt: -------------------------------------------------------------------------------- 1 | where type =~ 'Microsoft.Compute/virtualMachines' 2 | and isempty(aliases['Microsoft.Compute/virtualMachines/storageProfile.osDisk.managedDisk.id']) 3 | | project subscriptionId, resourceGroup, name -------------------------------------------------------------------------------- /queries/virtualMachines/vm-with-ip-infos/README.md: -------------------------------------------------------------------------------- 1 | # List all virtual machines with primary nic information 2 | 3 | ## Description 4 | This query will return all virtual machines with their primary nic private and public IP addresses. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "nicId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/project1-vm-dev/providers/Microsoft.Network/networkInterfaces/proj1dev-2007f_nic", 11 | "privateIpAddress": "172.18.40.5", 12 | "publicIpAddress": "", 13 | "publicIpId": "", 14 | "vmId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/project1-vm-dev/providers/Microsoft.Compute/virtualMachines/proj1dev-2007f", 15 | "vmName": "proj1dev-2007f", 16 | "vmSize": "Standard_D2s_v3" 17 | }, 18 | { 19 | "nicId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/proj1-dev/providers/Microsoft.Network/networkInterfaces/proj1dev-dc2464", 20 | "privateIpAddress": "172.18.50.5", 21 | "publicIpAddress": "40.86.201.107", 22 | "publicIpId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/proj1-dev/providers/Microsoft.Network/publicIPAddresses/proj1dev-dc2-publicip", 23 | "vmId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/proj1-dev/providers/Microsoft.Compute/virtualMachines/proj1dev-dc2", 24 | "vmName": "proj1dev-dc2", 25 | "vmSize": "Standard_DS2_v2" 26 | } 27 | ] 28 | ``` -------------------------------------------------------------------------------- /queries/virtualMachines/vm-with-ip-infos/query.txt: -------------------------------------------------------------------------------- 1 | Resources 2 | | where type =~ 'microsoft.compute/virtualmachines' 3 | | extend nics=array_length(properties.networkProfile.networkInterfaces) 4 | | mv-expand nic=properties.networkProfile.networkInterfaces 5 | | where nics == 1 or nic.properties.primary =~ 'true' or isempty(nic) 6 | | project vmId = id, vmName = name, vmSize=tostring(properties.hardwareProfile.vmSize), nicId = tostring(nic.id) 7 | | join kind=leftouter ( 8 | Resources 9 | | where type =~ 'microsoft.network/networkinterfaces' 10 | | extend ipConfigsCount=array_length(properties.ipConfigurations) 11 | | mv-expand ipconfig=properties.ipConfigurations 12 | | where ipConfigsCount == 1 or ipconfig.properties.primary =~ 'true' 13 | | project nicId = id, publicIpId = tostring(ipconfig.properties.publicIPAddress.id), privateIpAddress = tostring(ipconfig.properties.privateIPAddress)) 14 | on nicId 15 | | project-away nicId1 16 | | summarize by vmId, vmName, vmSize, nicId, privateIpAddress, publicIpId 17 | | join kind=leftouter ( 18 | Resources 19 | | where type =~ 'microsoft.network/publicipaddresses' 20 | | project publicIpId = id, publicIpAddress = properties.ipAddress) 21 | on publicIpId 22 | | project-away publicIpId1 -------------------------------------------------------------------------------- /queries/virtualMachines/vm-without-antimalware-extension/README.md: -------------------------------------------------------------------------------- 1 | # List all virtual machines without the AntiMalware VM extension 2 | 3 | ## Description 4 | This query will return all virtual machines that do not have the IaaSAntimalware vm extension installed. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "ExtensionTypes": [ 11 | "MicrosoftMonitoringAgent", 12 | "BGInfo" 13 | ], 14 | "OSName": "myserver", 15 | "OSType": "Windows", 16 | "VMSize": "Standard_DS11_v2", 17 | "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/demo-arg/providers/Microsoft.Compute/virtualMachines/myserver", 18 | "resourceGroup": "demo-arg" 19 | }, 20 | { 21 | "ExtensionTypes": [], 22 | "OSName": "myserver2", 23 | "OSType": "Windows", 24 | "VMSize": "Standard_DS11_v2", 25 | "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/demo-arg/providers/Microsoft.Compute/virtualMachines/myserver2", 26 | "resourceGroup": "demo-arg" 27 | } 28 | ] 29 | ``` -------------------------------------------------------------------------------- /queries/virtualMachines/vm-without-antimalware-extension/query.txt: -------------------------------------------------------------------------------- 1 | Resources 2 | | where type == 'microsoft.compute/virtualmachines' 3 | | extend 4 | JoinID = toupper(id), 5 | OSName = tostring(properties.osProfile.computerName), 6 | OSType = tostring(properties.storageProfile.osDisk.osType), 7 | VMSize = tostring(properties.hardwareProfile.vmSize) 8 | | join kind=leftouter( 9 | Resources 10 | | where type == 'microsoft.compute/virtualmachines/extensions' 11 | | extend 12 | VMId = toupper(substring(id, 0, indexof(id, '/extensions'))), 13 | ExtensionType = properties.type, 14 | ExtensionPublisher = properties.publisher, 15 | ExtensionName = name 16 | ) on $left.JoinID == $right.VMId 17 | | summarize ExtensionTypes = make_list(ExtensionType) by id, OSName, OSType, VMSize 18 | | where ExtensionTypes notcontains 'IaaSAntimalware' 19 | | order by tolower(OSName) asc -------------------------------------------------------------------------------- /queries/virtualMachines/vm-without-availabilityset/README.md: -------------------------------------------------------------------------------- 1 | # List all virtual machines without an Availability Set 2 | 3 | ## Description 4 | This query will return all virtual machines that are not included in an Availability Set. 5 | 6 | ## Sample output 7 | ``` 8 | [ 9 | { 10 | "name": "vm1", 11 | "resourceGroup": "app1", 12 | "subscriptionId": "00000000-0000-0000-0000-000000000000" 13 | } 14 | ] 15 | ``` -------------------------------------------------------------------------------- /queries/virtualMachines/vm-without-availabilityset/query.txt: -------------------------------------------------------------------------------- 1 | where type =~ 'Microsoft.Compute/virtualMachines' 2 | | where properties.availabilitySet.id == '' 3 | | project subscriptionId, resourceGroup, name --------------------------------------------------------------------------------