SOLVED

Is it possible to "pipe" the output of one query to another?

%3CLINGO-SUB%20id%3D%22lingo-sub-922190%22%20slang%3D%22en-US%22%3EIs%20it%20possible%20to%20%22pipe%22%20the%20output%20of%20one%20query%20to%20another%3F%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-922190%22%20slang%3D%22en-US%22%3E%3CP%3EHi%2C%3C%2FP%3E%3CP%3EFirstly%20excuse%20me%20if%20this%20is%20a%20silly%20question%2C%20I%20am%20new%20to%20Kusto%20and%20query%20languages%20in%20general.%3C%2FP%3E%3CP%3EIs%20it%20possible%20to%20%22pipe%22%20the%20results%20of%20one%20query%20and%20use%20it%20to%20query%20on%20with%20another%3F%3C%2FP%3E%3CP%3EWhat%20are%20trying%20to%20do%20is%20get%20the%20output%20from%20the%20Auditlogs%20and%20use%20an%20attribute%20from%20that%20to%20then%20feed%20in%20to%20a%20query%20on%20the%20SigninLogs%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3Elet%20AddMember%20%3D%20(%3CBR%20%2F%3EAuditLogs%3CBR%20%2F%3E%7C%20where%20TimeGenerated%20%26gt%3B%20ago(2h)%3CBR%20%2F%3E%7C%20where%20OperationName%20%3D%3D%20%22Add%20member%20to%20group%22%20and%20TargetResources%20contains%20%22Our%20Group%22%3CBR%20%2F%3E%7C%20project%20TimeGenerated%2C%20OperationName%2C%20UserName%3DTargetResources%5B0%5D.userPrincipalName%2C%20GroupName%3DTargetResources%5B0%5D.modifiedProperties%5B1%5D.newValue%3CBR%20%2F%3E)%3B%3CBR%20%2F%3Elet%20AppSignIn%20%3D%20(%3CBR%20%2F%3ESigninLogs%3CBR%20%2F%3E%7C%20where%20TimeGenerated%20%26gt%3B%20ago(2h)%3CBR%20%2F%3E%7C%20where%20AppDisplayName%20%3D%3D%20%22Our%20App%22%3CBR%20%2F%3E%7C%20where%20Status.errorCode%20%3D%3D%20%220%22%3CBR%20%2F%3E%7C%20project%20TimeGenerated%2C%20OperationName%2C%20UserName%3DUserPrincipalName%2C%20AppDisplayName%3CBR%20%2F%3E)%3B%3CBR%20%2F%3EAddMember%3C%2FP%3E%3CP%3E%7C%20union%20AppSignIn%3CBR%20%2F%3E%7C%20sort%20by%20TimeGenerated%20asc%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%3CBR%20%2F%3EI%20am%20not%20familiar%20with%20all%20the%20operators%20but%20I%20understand%20that%20the%20Union%20operator%20creates%20a%20single%20table%20from%20both%20outputs...%20not%20quite%20what%20I%20am%20after%20because%20I'd%20like%20to%20use%20the%20output%20from%20one%20to%20feed%20in%20to%20the%20other.%26nbsp%3B%3C%2FP%3E%3CP%3EHopefully%20I%20have%20made%20sense%20and%20thanks.%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-LABS%20id%3D%22lingo-labs-922190%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EAzure%20Log%20Analytics%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3CLINGO-SUB%20id%3D%22lingo-sub-926588%22%20slang%3D%22en-US%22%3ERe%3A%20Is%20it%20possible%20to%20%22pipe%22%20the%20output%20of%20one%20query%20to%20another%3F%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-926588%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F430100%22%20target%3D%22_blank%22%3E%40TheGreenGorilla%3C%2FA%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EAre%20you%20looking%20for%20a%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fkusto%2Fquery%2Fjoinoperator%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%22%3Ejoin%3C%2FA%3E%3F%20Something%20like%20this%3F%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3Elet%20AddMember%20%3D%20(%0AAuditLogs%0A%7C%20where%20TimeGenerated%20%26gt%3B%20ago(24h)%0A%7C%20where%20OperationName%20%3D%3D%20%22Add%20member%20to%20group%22%20and%20TargetResources%20contains%20%22Our%20Group%22%0A%7C%20project%20TimeGenerated%2C%20OperationName%2C%20UserName%3DTargetResources%5B0%5D.userPrincipalName%2C%20GroupName%3DTargetResources%5B0%5D.modifiedProperties%5B1%5D.newValue%2C%20ResourceId%0A)%3B%0ASigninLogs%0A%7C%20where%20TimeGenerated%20%26gt%3B%20ago(2h)%0A%7C%20where%20AppDisplayName%20%3D%3D%20%22Our%20App%22%0A%7C%20where%20Status.errorCode%20%3D%3D%20%220%22%0A%7C%20project%20TimeGenerated%2C%20OperationName%2C%20UserName%3DUserPrincipalName%2C%20AppDisplayName%2C%20ResourceId%0A%7C%20join%20(%0A%20%20%20%20%20%20%20%20AddMember%0A%20)%20on%20ResourceId%20%0A%20%7C%20project%20AppDisplayName%20%2C%20OperationName%20%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%20%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-933978%22%20slang%3D%22en-US%22%3ERe%3A%20Is%20it%20possible%20to%20%22pipe%22%20the%20output%20of%20one%20query%20to%20another%3F%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-933978%22%20slang%3D%22en-US%22%3E%3CP%3EThanks%20for%20your%20reply%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F239477%22%20target%3D%22_blank%22%3E%40Clive%20Watson%3C%2FA%3E%3C%2FP%3E%3CP%3E%26nbsp%3BI%20have%20tried%20the%20Join%20operator%2C%20but%20doesnt%20that%20just%20join%20the%20columns%20from%20the%26nbsp%3B%202%20outputs%3F%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI'd%20like%20the%20output%20from%20the%20AuditLogs%20to%20be%20the%20source%2Finput%20in%20to%20the%20SignIn%20logs%20query.%20A%20bit%20like%20how%20you%20would%20pipe%20resultant%20objects%20from%20one%20PowerShell%20command%20to%20the%20next.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI%20guess%20I%20would%20somehow%20need%20to%20create%20a%20temporary%20table%20from%20the%20AuditLogs%20and%20use%20that%20as%20a%20source%20for%20the%20next%20query...%20I%20am%20new%20to%20Kusto%20(and%20query%20languages)%20so%20I%20may%20be%20a%20tough%20student.%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-934214%22%20slang%3D%22en-US%22%3ERe%3A%20Is%20it%20possible%20to%20%22pipe%22%20the%20output%20of%20one%20query%20to%20another%3F%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-934214%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F430100%22%20target%3D%22_blank%22%3E%40TheGreenGorilla%3C%2FA%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EMore%20like%20this%3F%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3Elet%20AddMember%20%3D%20(%0AAuditLogs%0A%7C%20where%20TimeGenerated%20%26gt%3B%20ago(2h)%0A%7C%20where%20OperationName%20%3D%3D%20%22Add%20member%20to%20group%22%20and%20TargetResources%20contains%20%22Our%20Group%22%0A%7C%20project%20TimeGenerated%2C%20OperationName%2C%20UserName%3DTargetResources%5B0%5D.userPrincipalName%2C%20GroupName%3DTargetResources%5B0%5D.modifiedProperties%5B1%5D.newValue%2C%20ResourceId%0A)%3B%0ASigninLogs%0A%7C%20where%20TimeGenerated%20%26gt%3B%20ago(2h)%0A%7C%20where%20AppDisplayName%20%3D%3D%20%22Our%20App%22%0A%7C%20where%20Status.errorCode%20%3D%3D%20%220%22%0A%7C%20where%20UserPrincipalName%20in%20(AddMember)%0A%7C%20project%20TimeGenerated%2C%20OperationName%2C%20UserName%3DUserPrincipalName%2C%20AppDisplayName%2C%20ResourceId%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EOr%20see%20my%20working%20example%20(using%20demo%20data)%2C%20please%20click%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CA%20href%3D%22https%3A%2F%2Fms.portal.azure.com%23%4072f988bf-86f1-41af-91ab-2d7cd011db47%2Fblade%2FMicrosoft_Azure_Monitoring_Logs%2FDemoLogsBlade%2FresourceId%2F%252FDemo%2Fsource%2FLogsBlade.AnalyticsShareLinkToQuery%2Fq%2FH4sIAAAAAAAAA52POw7CMBBEe0u%25252BwyqV3SI6BE2EoKDkAiYeESPijdZL0uTwJBLi09KO3rzR3KHUcNc%25252FFHJKRWlLzpojgugFQa2ZaGwhoHPqcECGBEWkHYUru9U6%25252Bg9RvzRUdG6XMWlLVc1ZuXC1YHH2p9zom1zCXviGn8xvrNkPyP%25252BNp0zu%25252B5B%25252FAlmmBk%25252FiAAAA%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3EGo%20to%20Log%20Analytics%20and%20Run%20Query%3C%2FA%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EGet%20all%20computers%20that%20%3CEM%3Estartswith%26nbsp%3B%3C%2FEM%3Ea%20name%20of%20%22Contoso%22%20from%20the%20%3CSTRONG%3EHeartbeat%3C%2FSTRONG%3E%20table%20and%20then%20only%20show%20%3CSTRONG%3EEvents%3C%2FSTRONG%3E%20for%20those%3F%26nbsp%3B%20You%20can%20use%20!in%20for%20the%20reverse%20i.e.%20%22not%20in%22%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3Elet%20computerList%20%3D%20(%0AHeartbeat%0A%7C%20where%20TimeGenerated%20%26gt%3B%20ago(24d)%0A%7C%20where%20Computer%20startswith%20%22Contoso%22%0A%7C%20distinct%20Computer%0A%7C%20project%20Computer%0A)%3B%0AEvent%0A%7C%20where%20TimeGenerated%20%26gt%3B%20ago(24d)%0A%7C%20where%20Computer%20in%20(computerList)%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-945014%22%20slang%3D%22en-US%22%3ERe%3A%20Is%20it%20possible%20to%20%22pipe%22%20the%20output%20of%20one%20query%20to%20another%3F%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-945014%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F239477%22%20target%3D%22_blank%22%3E%40Clive%20Watson%3C%2FA%3E%26nbsp%3B%3C%2FP%3E%3CP%3EYes!%20The%20IN%20operator%20has%20done%20the%20trick%20and%20have%20added%20to%20my%20vocabulary.%20I%20had%20to%20make%20a%20small%20adjustment%20to%20the%20first%20Project%20operator%20to%20produce%20the%20results%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3Elet%20AddMember%20%3D%20(%0AAuditLogs%0A%7C%20where%20TimeGenerated%20%26gt%3B%20ago(2h)%0A%7C%20where%20OperationName%20%3D%3D%20%22Add%20member%20to%20group%22%20and%20TargetResources%20contains%20%22Our%20Group%22%0A%7C%20project%20UserName%3DTargetResources%5B0%5D.userPrincipalName%0A)%3B%0ASigninLogs%0A%7C%20where%20TimeGenerated%20%26gt%3B%20ago(2h)%0A%7C%20where%20AppDisplayName%20%3D%3D%20%22Our%20App%22%0A%7C%20where%20Status.errorCode%20%3D%3D%20%220%22%0A%7C%20where%20UserPrincipalName%20in%20(AddMember)%0A%7C%20project%20TimeGenerated%2C%20OperationName%2C%20UserName%3DUserPrincipalName%2C%20AppDisplayName%2C%20ResourceId%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3BThanks%20for%20taking%20the%20time%20to%20offer%20a%20solution.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E
New Contributor

Hi,

Firstly excuse me if this is a silly question, I am new to Kusto and query languages in general.

Is it possible to "pipe" the results of one query and use it to query on with another?

What are trying to do is get the output from the Auditlogs and use an attribute from that to then feed in to a query on the SigninLogs;

 

 

let AddMember = (
AuditLogs
| where TimeGenerated > ago(2h)
| where OperationName == "Add member to group" and TargetResources contains "Our Group"
| project TimeGenerated, OperationName, UserName=TargetResources[0].userPrincipalName, GroupName=TargetResources[0].modifiedProperties[1].newValue
);
let AppSignIn = (
SigninLogs
| where TimeGenerated > ago(2h)
| where AppDisplayName == "Our App"
| where Status.errorCode == "0"
| project TimeGenerated, OperationName, UserName=UserPrincipalName, AppDisplayName
);
AddMember

| union AppSignIn
| sort by TimeGenerated asc

 


I am not familiar with all the operators but I understand that the Union operator creates a single table from both outputs... not quite what I am after because I'd like to use the output from one to feed in to the other. 

Hopefully I have made sense and thanks.

4 Replies

@TheGreenGorilla 

 

Are you looking for a join? Something like this?

 

let AddMember = (
AuditLogs
| where TimeGenerated > ago(24h)
| where OperationName == "Add member to group" and TargetResources contains "Our Group"
| project TimeGenerated, OperationName, UserName=TargetResources[0].userPrincipalName, GroupName=TargetResources[0].modifiedProperties[1].newValue, ResourceId
);
SigninLogs
| where TimeGenerated > ago(2h)
| where AppDisplayName == "Our App"
| where Status.errorCode == "0"
| project TimeGenerated, OperationName, UserName=UserPrincipalName, AppDisplayName, ResourceId
| join (
        AddMember
 ) on ResourceId 
 | project AppDisplayName , OperationName 

   

Thanks for your reply @Clive Watson

 I have tried the Join operator, but doesnt that just join the columns from the  2 outputs?

 

I'd like the output from the AuditLogs to be the source/input in to the SignIn logs query. A bit like how you would pipe resultant objects from one PowerShell command to the next.

 

I guess I would somehow need to create a temporary table from the AuditLogs and use that as a source for the next query... I am new to Kusto (and query languages) so I may be a tough student.

Best Response confirmed by TheGreenGorilla (New Contributor)
Solution

@TheGreenGorilla 

 

More like this?

let AddMember = (
AuditLogs
| where TimeGenerated > ago(2h)
| where OperationName == "Add member to group" and TargetResources contains "Our Group"
| project TimeGenerated, OperationName, UserName=TargetResources[0].userPrincipalName, GroupName=TargetResources[0].modifiedProperties[1].newValue, ResourceId
);
SigninLogs
| where TimeGenerated > ago(2h)
| where AppDisplayName == "Our App"
| where Status.errorCode == "0"
| where UserPrincipalName in (AddMember)
| project TimeGenerated, OperationName, UserName=UserPrincipalName, AppDisplayName, ResourceId

 

 

Or see my working example (using demo data), please click

 

Go to Log Analytics and Run Query

 

Get all computers that startswith a name of "Contoso" from the Heartbeat table and then only show Events for those?  You can use !in for the reverse i.e. "not in"

 

let computerList = (
Heartbeat
| where TimeGenerated > ago(24d)
| where Computer startswith "Contoso"
| distinct Computer
| project Computer
);
Event
| where TimeGenerated > ago(24d)
| where Computer in (computerList)

 

@Clive Watson 

Yes! The IN operator has done the trick and have added to my vocabulary. I had to make a small adjustment to the first Project operator to produce the results 

 

 

let AddMember = (
AuditLogs
| where TimeGenerated > ago(2h)
| where OperationName == "Add member to group" and TargetResources contains "Our Group"
| project UserName=TargetResources[0].userPrincipalName
);
SigninLogs
| where TimeGenerated > ago(2h)
| where AppDisplayName == "Our App"
| where Status.errorCode == "0"
| where UserPrincipalName in (AddMember)
| project TimeGenerated, OperationName, UserName=UserPrincipalName, AppDisplayName, ResourceId

 

 Thanks for taking the time to offer a solution.