Just over 18 months ago I wrote this post on using PowerShell and oAuth to access the Azure AD Reports API to retrieve MIM Hybrid Report data. This week I went to re-use that for Azure Password Reset Reporting and found out that the API had been deprecated.
Using the error information that actually was informative I proceeded to the new API. Having authenticated as I had in the previous article, I executed the following to retrieve a list of the Audit Reports available.
$TenantDomain = "customer.com.au" $url = 'https://graph.windows.net/' + $tenantdomain + "/activities/auditActivityTypes?api-version=beta" # Returns a JSON document for the Audit Activity Types $auditActivities= (Invoke-WebRequest-Headers $headerParams-Uri $url).Content |ConvertFrom-Json $auditActivities.activityTypes
Before I go any further it’s a good time to mention you can easily access the Audit log events using the Azure Portal and retrieve the data you maybe looking for and download a report. There is also the Azure Audit logs content pack for PowerBI as detailed here. Those are awesome solutions, but if you want to do something a little more bespoke and programmatic then keep reading.
Azure AD Password Events Audit Log Data
For the record (as at 18 Dec 2018) there are 1023 different Activity Resource Types. The full list is available here. The ones I’m interested in right now though are a subset of the Self-service Password Management category;
https://graph.microsoft.com/beta/auditLogs/directoryAudits
My Azure AD Registered App needed to be updated to have the additional role (AuditLog.Read.All) which was done via the Registered Applications blade under Azure Active Directory in the Azure Portal;
AuditLog.Read.All
My script then needed to be updated to talk to the Microsoft Graph and the new scope;
$resource = "https://graph.microsoft.com" $scope = "AuditLog.Read.All; Directory.Read.All"
So to get Azure Password Reset events for the last week the following calls can be made;
# Get Reset Password Events $DirectoryAuditURL = "https://graph.microsoft.com/beta/auditLogs/directoryAudits" $passwordMgmtAuditData = Invoke-RestMethod -Method Get -Uri "$($DirectoryAuditURL)?`$filter=category eq `'UserManagement`' and activityDateTime ge 2018-12-11T03:15:10.6837342Z and startswith(activityDisplayName%2C+`'Reset password`')" -Headers @{Authorization = "Bearer $($Global:accesstoken)"}
To retrieve the other events contained in the auditLog we just need to alter the event to retrieve events for and the timeframe of interest. The events from the table above associated with Azure Self Service Password Reset and Azure Change Password are;
Blocked from self-service password reset Change password (self-service) Credentials Registered and Password Reset Status of User Reset password (by admin) Reset password (self-service) Security info saved for self-service password reset Self-serve password reset flow activity progress Self-service password reset flow activity progress Unlock user account (self-service) User completed security info registration for self-service password reset User registered for self-service password reset User started security info registration for self-service password reset
The Script
Here is the modified script from my previous post here that uses oAuth to retrieve Azure Password Reset events. As per the other script it enables the scopes required. If you’re not Global Admin get the script run initially by someone who has the Global Admin role or get them to assign the AuditLog.Read.All permission to the Azure AD Application you have created. You can then login and get an Access Token and a Refresh Token.
Update;
- Line 5 for your Application ClientID
- Line 6 for your Application Secret
- Line 18 for where you want to store the Refresh Token
- Line 97 can be un-remarked after getting a token to use the Refresh Token (and Line 96 commented out). To get a new Access Token using the stored Refresh Token (Line 18) call the Get-NewTokens function
If, due to your time filter you have more than the maximum (1000 events) that can be returned per call, you can use the skiptoken to get the next page. If you have more than 2000 use the subsequent skipToken in additional calls in a do { get data } while ($skipToken) loop with the addition of adding the returned data to a collection.
$skipToken = $passwordMgmtAuditData.'@odata.nextLink' $results = Invoke-RestMethod -Method Get -Uri $skipToken -Headers @{Authorization = "Bearer $($Global:accesstoken)"}
If you want to automate the time period to retrieve events for then you can use the Get-Date function and set the time window.
# Date Time for the report. Last 14 Days [string]$strDateTimeNow = Get-Date -Format yyyy-MM-ddThh:mm:ss [datetime]$dateTimeNow = Get-Date -Format yyyy-MM-ddThh:mm:ss [datetime]$minus14Days = $dateTimeNow.AddDays(-14) [string]$14daysAgo = get-date($minus14Days) -Format yyyy-MM-ddThh:mm:ss
so then the call for the last 14 days of events would be
$passwordMgmtAuditData = Invoke-RestMethod -Method Get -Uri "$($DirectoryAuditURL)?`$filter=category eq `'UserManagement`' and activityDateTime ge $($14daysAgo)z and activityDateTime le $($strDateTimeNow)z and startswith(activityDisplayName%2C+`'Reset password`')" -Headers @{Authorization = "Bearer $($Global:accesstoken)"}
Summary
Using the Microsoft Graph auditLog API we can retrieve using PowerShell events of interest for reporting or other requirements.