Searching OMS Using the New Search Language (Kusto) REST API in PowerShell

Currently Microsoft is in the process of upgrading all OMS Log Analytics workspaces to the new query language (named Kusto). Once your workspace has been upgraded, you will no longer able to invoke search queries using the Get-AzureRmOperationalInsightsSearchResults cmdlet from the AzureRM.OperationalInsights PowerShell module. Kusto comes with a new set of REST APIs, you can find the documentation site here:

According to the documentation, this REST API has the following limitations:

  • Queries cannot return more than 500,000 rows
  • Queries cannot return more than 64,000,000 bytes (~61 MiB total data)
  • Quries cannot run longer than 10 minutes by default.

From the documentation site, you can also find a sample PowerShell module which allows you to invoke Kusto search queries via the ARM REST API:

I have contacted the OMS product group and I have been advised that since the sample PowerShell module offered from the documentation site invokes searches via ARM REST API (as opposed to via the direct Kusto API), the limitation for ARM REST API also applies, which means the query cannot return more than 8MB payload – which is significantly smaller than the direct Kusto API.

Previously with the old language, we also had similar limitations, and I have blogged ways to overcome the throttling limitations using ‘skip’ command. You can find my previous blog post here: However, the new Kusto language does not have a ‘skip’ or equivalent command so it was not possible to use the same method when querying against a large result set. Luckily with the help from the OMS product group, I managed to get it working using the row_number() function, and developed a script directly invoking the new Log Analytics search REST API (instead of going through ARM).

Here’s the PowerShell script I developed, in order to run it, in addition to the AzureRM.Profile and AzureRM.Resources module, you will also need the AzureServicePrincipalAccount PowerShell module v1.2.0 or above (developed by myself) :

This script searches your workspace using Kusto API and exports results to one or more files. you will need to specify the following parameters:

  • -AzureCredential: a PSCredential object for an Azure AD account that has access to your workspace
  • -TenantId: the GUID for your AAD Tenant ID
  • -WorkspaceId: the GUID for your Log Analytics workspace ID
  • -SearchQuery: the Kusto search query you wish to perform
  • -StartUTCTime: the start (earliest) time in UTC for the search operation. Optional, if not specified, the default value is 1 day ago
  • -EndUTCTime: the end(latest) time in UTC for the search operation. Optional, if not specified, the default value is now
  • -Timeout: the HTTP Rest time out for the Log Analytics REST API. optional, default value is 180 (seconds)
  • -OutputDir: the directory where you want the search results to be saved. optional, default value is the script root folder.
  • -OutputFileNamePrefix: the prefix for the output file name. Optional, default value is ‘OMSSearchResult’
  • -OutputFormat: the format for the output files. you can choose between CSV and JSON. this parameter is optional, default is CSV
  • -MaximumRowPerFile: the maximum number of rows for each output file. optional, default is 5000

I’ve added many verbose messages in the script. so if you run it with –Verbose switch, you’ll see more details while the script is running:


Note: If you perform search within a large time window, the script will take a long time to run depending on number of rows returned from the search result.

Lastly, please feel free to contact me if you have issues or suggestions.


  1. Hello! I am trying to get this to work in my environment and running into some trouble (mind you, I’m only intermediate in Powershell). I have it working ok until it gets to the line “$SearchResult = Invoke-OMSKustoSearch -AADToken $AADToken -WorkspaceId $WorkspaceId -SearchQuery $SearchQuery -ISO8601TimeSpan $ISO8601TimeSpan -Timeout $Timeout”

    Specifically, Invoke-WebRequest in the “Invoke-OMSKustoSearch” function is failing on the line ” $InitialQuery = “$SearchQuery | sort by TimeGenerated asc | extend rn=row_number()”” If I take out everything except “$InitialQuery = $SearchQuery” the command will complete, but leaving in the 2 piped commands (either or both) causes the following errors:

    Invoke-WebRequest : {“error”:{“message”:”The request had some invalid properties”,”code”:”BadArgumentError”,”innererror”:{“code”:”SemanticError”,”message”:”A semantic error
    occurred.”,”innererror”:{“code”:”SEM0237″,”message”:”Function ‘row_number’ cannot be invoked in current context”}}}}

    Invoke-WebRequest : {“error”:{“message”:”The request had some invalid properties”,”code”:”BadArgumentError”,”innererror”:{“code”:”SemanticError”,”message”:”A semantic error
    occurred.”,”innererror”:{“code”:”SEM0100″,”message”:”‘order’ operator: Failed to resolve scalar expression named ‘TimeGenerated'”}}}}

    Can you provide a fix or workaround, or guide me to where I may find an answer?

    1. This issue actually resolved itself for no discernible reason… I’m going to guess your Powershell prowess scared it off.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: