|
1 | 1 | # AD FS Log Tools |
2 | 2 |
|
3 | | -## Get-ADFSEvents Overview |
| 3 | +## AdfsEventsModule Overview |
4 | 4 |
|
5 | | -This script gathers ADFS related events from the security, admin, and debug logs, |
6 | | -and allows the user to reconstruct the HTTP request/response headers from the logs. |
| 5 | +This module provides tools for gathering related ADFS events from the security, admin, and debug logs, |
| 6 | +across multiple servers. This tool also allows the user to reconstruct the HTTP request/response headers |
| 7 | +from the logs. |
7 | 8 |
|
8 | | -Given a correlation id, the script will gather all events with the same identifier and reconstruct the request |
9 | | -and response headers if they exist. Using the 'All' option (either with or without headers enabled) will first collect |
10 | | -all correlation ids and proceed to gather the events for each. If start and end times are provided, all events |
11 | | -that fall into that span will be returned. The start and end times will be assumed to be base times. That is, all |
12 | | -time conversions will be based on the UTC of these values. |
| 9 | +## Cmdlets in AdfsEventsModule |
13 | 10 |
|
14 | | -The output produced by Get-ADFSEvents is a list of objects with each containing the following properties: |
15 | | - |
16 | | -1. CorrelationID |
17 | | - |
18 | | -2. Events |
19 | | - |
20 | | -3. Headers |
21 | | - |
22 | | -The CorrelationID property contains a string representation of the correlation id that all events and headers within that object share. |
23 | | - |
24 | | -The Events property contains a list of [EventLogRecord](https://msdn.microsoft.com/en-us/library/system.diagnostics.eventing.reader.eventlogrecord) |
25 | | -objects that share the particular correlation id. |
26 | | - |
27 | | -The Headers property contains a list of objects, each composed of the following properties: |
28 | | - |
29 | | -1.QueryString |
| 11 | +This module exposes two cmdlets: |
30 | 12 |
|
31 | | -2.ResponseString |
| 13 | +__```Get-ADFSEvents```__ |
32 | 14 |
|
33 | | -3.RequestHeader |
| 15 | +and |
34 | 16 |
|
35 | | -4.ResponseHeader |
| 17 | +__```Write-ADFSEventsSummary```__ |
36 | 18 |
|
37 | | -The QueryString property contains the HTTP verb (GET, POST, etc) and the corresponding query string. |
38 | | - |
39 | | -The ResponseString property contains the HTTP response string (ex. 200 ok) |
40 | | - |
41 | | -The RequestHeader property is a dictionary representing the various headers included in the HTTP request |
42 | | - |
43 | | -The ResponseHeader property is a dictionary representing the various headers included in the HTTP response |
44 | | - |
45 | | -As a final note, the output is, by default, merely dumped to the console to allow users to manipulate the objects returned. |
46 | | -While this will likely prove sufficient for many users, those who desire future access to the output should use ```Export-Clixml``` |
47 | | -to write the output to an xml file. ```Import-Clixml``` can then be used to reconstruct the objects from the file. Examples of both are |
48 | | -included in the Using Get-ADFSEvents section below. |
49 | | - |
50 | | -## Using Get-ADFSEvents |
51 | | - |
52 | | -1. Import the PowerShell Module |
| 19 | +The detailed parameters for each are provided below. |
53 | 20 |
|
54 | | - In a PowerShell window, run the following: |
55 | 21 |
|
56 | | - ```ipmo Get-ADFSEvents.psm1``` |
| 22 | +The ```Get-ADFSEvents``` cmdlet is used to aggregate events by correlation ID, while the ```Write-ADFSEventsSummary``` |
| 23 | +cmdlet is used to generate a PowerShell Table of only the most relevant logging information from the events that are piped |
| 24 | +in. |
57 | 25 |
|
58 | | -2. Run Get-ADFSEvents |
59 | | - |
60 | | -EXAMPLE |
| 26 | +## Get-ADFSEvents Parameters |
61 | 27 |
|
62 | | -```Get-ADFSEvents -Logs Security, Admin, Debug -CorrelationID 669bced6-d6ae-4e69-889b-09ceb8db78c9 -Server LocalHost, MyServer``` |
| 28 | +* __Logs__ - A list of AD FS logs to include in the aggregation. Current options are: "Admin", "Debug", "Security". |
| 29 | +The default will pull from both Security and Admin. |
| 30 | +* __CorrelationID__ - The correlation ID for a single request. This will aggregate all chosen logs for this request |
| 31 | +* __AllWithoutHeaders__ - this flag will cause all requests to be grouped by correlation ID, but the HTTP headers |
| 32 | +will not be extracted from the logs |
| 33 | +* __AllWithHeaders__ - this flag will cause all requests to be grouped by correlation ID, and the HTTP headers of |
| 34 | +each request will be extracted from the logs |
| 35 | +* __StartTime__ - the UTC start time to use when aggregating multiple requests. All requests that start after this |
| 36 | +time will be aggregated |
| 37 | +* __EndTime__ - the UTC end time to use when aggregating multiple requests. All requests that end before this time |
| 38 | +will be aggregated |
| 39 | +* __Server__ - a comma-separated list of server names to pull logs from. |
| 40 | +The default will pull from LocalHost |
63 | 41 |
|
64 | | -EXAMPLE |
| 42 | +## Get-ADFSEvents Output |
65 | 43 |
|
66 | | -```Get-ADFSEvents -Logs Admin -AllWithHeaders -Server LocalHost``` |
| 44 | +The output produced by Get-ADFSEvents is a list of objects with each containing the following properties: |
67 | 45 |
|
68 | | -EXAMPLE |
| 46 | +1. __CorrelationID__ |
| 47 | +2. __Events__ |
| 48 | +3. __Headers__ |
69 | 49 |
|
70 | | -```Get-ADFSEvents -Logs Debug, Security -AllWithoutHeaders -Server LocalHost, Server1, Server2``` |
| 50 | +The __CorrelationID__ property contains a string representation of the Correlation ID that all events and headers within that object share. |
71 | 51 |
|
72 | | -EXAMPLE |
| 52 | +The __Events__ property contains a list of [EventLogRecord](https://msdn.microsoft.com/en-us/library/system.diagnostics.eventing.reader.eventlogrecord) |
| 53 | +objects for the matching Correlation ID. |
73 | 54 |
|
74 | | -```Get-ADFSEvents -Logs Debug -StartTime (Get-Date -Date "1970-01-01 00:00:00Z") -EndTime (Get-Date) -Server localhost``` |
| 55 | +The __Headers__ property contains a list of objects, each containing of the following properties: |
75 | 56 |
|
76 | | -EXAMPLE |
| 57 | +1. __QueryString__ |
| 58 | +2. __ResponseString__ |
| 59 | +3. __RequestHeader__ |
| 60 | +4. __ResponseHeader__ |
77 | 61 |
|
78 | | -```$Result = Get-ADFSEvents -Logs Admin -AllWithHeaders -Server LocalHost``` |
| 62 | +The __QueryString__ property contains the HTTP verb (GET, POST, etc) and the corresponding query string. |
79 | 63 |
|
80 | | -```$CorrelationID = $Result[0].CorrelationID #Obtain correlation id for first entry in output``` |
| 64 | +The __ResponseString__ property contains the HTTP response string (ex. 200 ok) |
81 | 65 |
|
82 | | -```$Events = $Result[0].Events #List of EventLogRecord objects``` |
| 66 | +The __RequestHeader__ property is a dictionary containing the headers included in the HTTP request |
83 | 67 |
|
84 | | -```$QueryString = $Result[0].Headers[0].QueryString #Query String for first header in list``` |
| 68 | +The __ResponseHeader__ property is a dictionary containing the headers included in the HTTP response |
85 | 69 |
|
86 | | -EXAMPLE |
87 | 70 |
|
88 | | -```Get-ADFSEvents -Logs Security, Admin, Debug -AllWithHeaders -Server localhost | Export-Clixml "output.xml" #Store output in file``` |
| 71 | +## Using Get-ADFSEvents |
89 | 72 |
|
90 | | -```$ReconstructedOutput = Import-Clixml output.xml #Rebuild objects from xml file``` |
| 73 | +1. Import the PowerShell Module |
91 | 74 |
|
92 | | -## Get-ADFSEvents Parameters |
| 75 | + In a PowerShell window, run the following: |
| 76 | + |
| 77 | + ```ipmo AdfsEventsModule.psm1``` |
| 78 | + |
| 79 | +2. Run Get-ADFSEvents with your desired parameters to get a list of PowerShell objects |
| 80 | + |
| 81 | + EXAMPLE: Retrieve all logs from two servers for a specific request |
| 82 | + |
| 83 | + ```$logs = Get-ADFSEvents -Logs Security, Admin, Debug -CorrelationID 0c0fd6ee-4b1e-4260-0300-0080070000e3 -Server LocalHost, MyServer``` |
| 84 | + |
| 85 | + OUTPUT: |
| 86 | + |
| 87 | + ``` |
| 88 | + Events Headers CorrelationID |
| 89 | + ------ ------- ------------- |
| 90 | +
|
| 91 | + {EventLogRecord, EventLogRecord} {} 0c0fd6ee-4b1e-4260-0300-0080070000e3 |
| 92 | + ``` |
| 93 | +
|
| 94 | +3. To view specific records: |
| 95 | +
|
| 96 | + ```$logs.Events[0]``` |
| 97 | +
|
| 98 | + OUTPUT: |
| 99 | +
|
| 100 | + ``` |
| 101 | + Message : An HTTP request was received. See audit 510 with the same Instance ID for headers. |
| 102 | +
|
| 103 | + Instance ID: 64fb88c5-7f4e-4888-8b61-7d0d85563b82 |
| 104 | +
|
| 105 | + Activity ID: 0c0fd6ee-4b1e-4260-0300-0080070000e3 |
| 106 | +
|
| 107 | + Request Details: |
| 108 | + Date And Time: 2017-09-19 20:50:43 |
| 109 | + Client IP: 123.45.67.9 |
| 110 | + HTTP Method: GET |
| 111 | + Url Absolute Path: /adfs/portal/logo/logo.png |
| 112 | + Query string: ?id=12345 |
| 113 | + Local Port: 443 |
| 114 | + Local IP: 123.45.67.8 |
| 115 | + User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36 |
| 116 | + Content Length: 0 |
| 117 | + Caller Identity: - |
| 118 | + Certificate Identity (if any): - |
| 119 | + Targeted relying party: - |
| 120 | + Through proxy: False |
| 121 | + Proxy DNS name: - |
| 122 | + CorrelationID : 0c0fd6ee-4b1e-4260-0300-0080070000e3 |
| 123 | + PSComputerName : LocalHost |
| 124 | + RunspaceId : 6d3d7715-08db-4aa1-b299-40d51d5db682 |
| 125 | + Id : 403 |
| 126 | + Version : |
| 127 | + Qualifiers : 0 |
| 128 | + Level : 0 |
| 129 | + Task : 3 |
| 130 | + Opcode : |
| 131 | + Keywords : 12345 |
| 132 | + RecordId : 12345 |
| 133 | + ProviderName : AD FS Auditing |
| 134 | + ProviderId : |
| 135 | + LogName : Security |
| 136 | + ProcessId : |
| 137 | + ThreadId : |
| 138 | + MachineName : contoso.com |
| 139 | + UserId : |
| 140 | + TimeCreated : 9/19/2017 1:50:43 PM |
| 141 | + ActivityId : |
| 142 | + RelatedActivityId : |
| 143 | + ContainerLog : security |
| 144 | + MatchedQueryIds : {} |
| 145 | + Bookmark : System.Diagnostics.Eventing.Reader.EventBookmark |
| 146 | + LevelDisplayName : Information |
| 147 | + OpcodeDisplayName : Info |
| 148 | + TaskDisplayName : |
| 149 | + KeywordsDisplayNames : {Audit Success, Classic} |
| 150 | + Properties : {} |
| 151 | + ``` |
| 152 | +
|
| 153 | +4. You can pipe your output to ```Write-ADFSEventsSummary``` |
| 154 | +
|
| 155 | + EXAMPLE: |
| 156 | +
|
| 157 | + ```Get-ADFSEvents -Logs Security, Admin, Debug -CorrelationID 0c0fd6ee-4b1e-4260-0300-0080070000e3 -Server LocalHost, MyServer | Write-ADFSEventsSummary``` |
| 158 | +
|
| 159 | + OUTPUT: |
| 160 | +
|
| 161 | + ``` |
| 162 | + Time : 9/19/2017 1:50:43 PM |
| 163 | + EventID : 403 |
| 164 | + Details : An HTTP request was received. See audit 510 with the same Instance ID for headers. |
| 165 | +
|
| 166 | + Instance ID: 64fb88c5-7f4e-4888-8b61-7d0d85563b82 |
| 167 | +
|
| 168 | + Activity ID: 0c0fd6ee-4b1e-4260-0300-0080070000e3 |
| 169 | +
|
| 170 | + Request Details: |
| 171 | + Date And Time: 2017-09-19 20:50:43 |
| 172 | + Client IP: 123.45.67.9 |
| 173 | + HTTP Method: GET |
| 174 | + Url Absolute Path: /adfs/portal/logo/logo.png |
| 175 | + Query string: ?id=12345 |
| 176 | + Local Port: 443 |
| 177 | + Local IP: 123.45.67.8 |
| 178 | + User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36 |
| 179 | + Content Length: 0 |
| 180 | + Caller Identity: - |
| 181 | + Certificate Identity (if any): - |
| 182 | + Targeted relying party: - |
| 183 | + Through proxy: False |
| 184 | + Proxy DNS name: - |
| 185 | + CorrelationID : 0c0fd6ee-4b1e-4260-0300-0080070000e3 |
| 186 | + Machine : contoso.com |
| 187 | + Log : Security |
| 188 | +
|
| 189 | + Time : 9/19/2017 1:50:43 PM |
| 190 | + EventID : 410 |
| 191 | + Details : Following request context headers present : |
| 192 | +
|
| 193 | + Activity ID: 0c0fd6ee-4b1e-4260-0300-0080070000e3 |
| 194 | +
|
| 195 | + X-MS-Client-Application: - |
| 196 | + X-MS-Client-User-Agent: - |
| 197 | + client-request-id: - |
| 198 | + X-MS-Endpoint-Absolute-Path: /adfs/portal/logo/logo.png |
| 199 | + X-MS-Forwarded-Client-IP: - |
| 200 | + X-MS-Proxy: - |
| 201 | + X-MS-ADFS-Proxy-Client-IP: - |
| 202 | + CorrelationID : 0c0fd6ee-4b1e-4260-0300-0080070000e3 |
| 203 | + Machine : contoso.com |
| 204 | + Log : Security |
| 205 | + ``` |
| 206 | +
|
| 207 | +5. You can pipe the output of ```Write-ADFSEventsSummary``` to a CSV |
| 208 | +
|
| 209 | + ```Get-ADFSEvents -Logs Security, Admin, Debug -CorrelationID 0c0fd6ee-4b1e-4260-0300-0080070000e3 -Server LocalHost, MyServer | Write-ADFSEventsSummary | Export-CSV mylogs.csv``` |
| 210 | +
|
| 211 | +
|
| 212 | +6. You can output the full data objects from ```Get-ADFSEvents``` to XML using: |
| 213 | +
|
| 214 | + ```Export-Clixml``` |
| 215 | +
|
| 216 | + ```Import-Clixml``` |
93 | 217 |
|
94 | | -* Logs - A list of AD FS logs to include in the aggregation. Current options are: "Admin", "Debug", "Security" |
95 | | -* CorrelationID - The correlation ID for a single request. This will aggregate all chosen logs for this request |
96 | | -* AllWithoutHeaders - this flag will cause all requests to be grouped by correlation ID, but the HTTP headers |
97 | | -will not be extracted from the logs |
98 | | -* AllWithHeaders - this flag will cause all requests to be grouped by correlation ID, and the HTTP headers of |
99 | | -each request will be extracted from the logs |
100 | | -* StartTime - the UTC start time to use when aggregating multiple requests. All requests that start after this |
101 | | -time will be aggregated |
102 | | -* EndTime - the UTC end time to use when aggregating multiple requests. All requests that end before this time |
103 | | -will be aggregated |
104 | | -* Server - a comma-separated list of server names to pull logs from |
105 | 218 |
|
106 | 219 | ## Contributing |
107 | 220 |
|
108 | | -This project welcomes contributions and suggestions. Most contributions require you to agree to a |
109 | | -Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us |
110 | | -the rights to use your contribution. For details, visit https://cla.microsoft.com. |
| 221 | +This project welcomes contributions and suggestions. We encourage you to fork this project, include any scripts you |
| 222 | +use for parsing, managing, or manipulating ADFS logs, and then do a pull request to master. If your scripts work, |
| 223 | +we'll include them so everyone can benefit. |
| 224 | +
|
| 225 | +Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the |
| 226 | +right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com. |
111 | 227 |
|
112 | 228 | When you submit a pull request, a CLA-bot will automatically determine whether you need to provide |
113 | 229 | a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions |
|
0 commit comments