EDIT
Clarification, issue happens on both PowerShell versions due to az CLI implemented as a batch file (mistakenly took it for a .NET console app). The solution replacing " for "" works on both versions (tested).
If you want to get rid of these kind of issues for good, my recommendation will always be to avoid any type of external application when the same can be accomplished with a PowerShell Module, in this case you can install Az.OperationalInsights & Az.Accounts Modules:
Install-Module Az.OperationalInsights, Az.Accounts -Scope CurrentUser
Then, the code to accomplish the same becomes (you can do a one-liner too but becomes pretty unreadable):
Connect-AzAccount
$params = @{
ResourceGroupName = '...tbd...'
WorkspaceName = '...tbd...'
SavedSearchId = '...tbd...'
}
$savedSearch = Get-AzOperationalInsightsSavedSearch @params
$params = @{
WorkspaceId = 'xxxx-xxxx-xxxx-....'
Query = $savedSearch.Properties.Query
}
Invoke-AzOperationalInsightsQuery @params
To give more context, the issue very likely only happens in Windows PowerShell 5.1, in PowerShell 7 doesn't seem to be a problem. What is happening is that the shell is eating all double-quotes in the query passed as argument of --analytics-query, to prove it and helping visualizing the issue, we can use a little inline console application (assuming you have the .NET 10 SDK, you can run them to test yourself):
$query = @'
AzureDiagnostics
| where ResourceType == 'VAULTS'
| where OperationName contains '' 'Secret' or OperationName contains '' 'Key'
| where TimeGenerated > ago (60d)
| summarize Count = count() by id_s
| extend findchar = indexof(id_s,".",1,-1,1) -8
| extend kv = substring(id_s,8,findchar)
| extend findchar = indexof(id_s,"/",1,-1,4) +1
| extend sec = substring(id_s,findchar)
| extend findchar = indexof(sec,"/",1,-1,1)
| extend sec = iff((findchar != -1),substring(sec,0,findchar),sec)
| project kv, sec
'@
'
using System;
for (int i = 0; i < args.Length; i++)
Console.WriteLine($"[{i}] {args[i]}");' |
dotnet run - -f net10.0 -- az monitor log-analytics query -w 123 --analytics--query $query
The above, in PS 7+ and assuming you are using the default value (Windows) for $PSNativeCommandArgumentPassing, would output:
[0] az
[1] monitor
[2] log-analytics
[3] query
[4] -w
[5] 123
[6] --analytics--query
[7] AzureDiagnostics
| where ResourceType == 'VAULTS'
| where OperationName contains '' 'Secret' or OperationName contains '' 'Key'
| where TimeGenerated > ago (60d)
| summarize Count = count() by id_s
| extend findchar = indexof(id_s,".",1,-1,1) -8
| extend kv = substring(id_s,8,findchar)
| extend findchar = indexof(id_s,"/",1,-1,4) +1
| extend sec = substring(id_s,findchar)
| extend findchar = indexof(sec,"/",1,-1,1)
| extend sec = iff((findchar != -1),substring(sec,0,findchar),sec)
| project kv, sec
But, in PS 5.1 you can see the problem, all " are gone:
[0] az
[1] monitor
[2] log-analytics
[3] query
[4] -w
[5] 123
[6] --analytics--query
[7] AzureDiagnostics
| where ResourceType == 'VAULTS'
| where OperationName contains '' 'Secret' or OperationName contains '' 'Key'
| where TimeGenerated > ago (60d)
| summarize Count = count() by id_s
| extend findchar = indexof(id_s,.,1,-1,1) -8
| extend kv = substring(id_s,8,findchar)
| extend findchar = indexof(id_s,/,1,-1,4) +1
| extend sec = substring(id_s,findchar)
| extend findchar = indexof(sec,/,1,-1,1)
| extend sec = iff((findchar != -1),substring(sec,0,findchar),sec)
| project kv, sec
As for the solution, as you've already figured out, replacing all " for ' in the KQL query solves it. And, for another solution that wouldn't require to change the query, doubling down on " seems to also solve the problem, this means adding .Replace to the resulted string of the inner command call (shortened for visibility):
$secrets = az monitor ... "$(az monitor log-analytics workspace...)".Replace('"', '""')
az monitor log-analytics workspace saved-search show...outputs the stored query which is then passed toaz monitor log-analytics query....right?