Fetch Microsoft Teams Creation and Deletion Dates with Graph PowerShell

Microsoft Teams is an essential tool for collaboration in modern organizations, and keeping track of administrative actions such as Teams creation and deletion is crucial for maintaining governance and security. Using Microsoft Graph PowerShell, administrators can query audit logs to retrieve detailed information about who created or deleted a Team, when the action occurred, and whether the action was successful.


The Script

Here’s the full PowerShell script for querying Teams creation and deletion actions:

# Connect to Microsoft Graph
Connect-MgGraph -Scopes "AuditLog.Read.All"

# Query for Group (Team) creation and deletion actions
$AuditLogs = Get-MgAuditLogDirectoryAudit -Filter "category eq 'GroupManagement' and (activityDisplayName eq 'Add group' or activityDisplayName eq 'Delete group')"

# Extract relevant details and display in tabular format
$Results = $AuditLogs | ForEach-Object {
    # Attempt to extract the user's UPN (userPrincipalName), fallback to displayName if UPN is not available
    $User = $_.initiatedBy.user.userPrincipalName
    if (-not $User) {
        $User = $_.initiatedBy.user.displayName
    }
    if (-not $User) {
        $User = "Unknown/Not Available"
    }

    # Extract the team/group name
    $TeamName = ($_.targetResources | Where-Object { $_.type -eq 'Group' -or $_.type -eq 'Team' }).displayName
    if (-not $TeamName) {
        $TeamName = "Unknown/Not Available"
    }

    # Create a custom object for the output
    [PSCustomObject]@{
        "Created/Deleted Time" = $_.'activityDateTime'
        "User"                 = $User
        "Operation"            = $_.'activityDisplayName'
        "Team Name"            = $TeamName
        "Result Status"        = if($_.'result' -eq 'success') {'Success'} else {'Failed'}
    }
}

# Output the results in a tabular format
$Results | Format-Table -AutoSize

How the Script Works

This script leverages Microsoft Graph PowerShell to query audit logs for Teams creation and deletion actions. Here’s a breakdown of how it works:

  • Connecting to Microsoft Graph: The script starts by connecting to Microsoft Graph using the required AuditLog.Read.All scope, which grants access to audit logs.
  • Querying Audit Logs: We use the Get-MgAuditLogDirectoryAudit cmdlet to query the logs. The filter specifically looks for actions under the GroupManagement category (since Microsoft Teams are backed by Microsoft 365 groups) and checks for the Add group and Delete group actions.
  • Extracting Key Information:
    • Created/Deleted Time: Retrieved from the activityDateTime field.
    • User: We extract the userPrincipalName (or fall back to the displayName) of the user who performed the action.
    • Team Name: The name of the team is extracted from the targetResources field, specifically looking for resources of type Group or Team.
    • Result Status: The result of the operation (success or failure) is derived from the result field.
  • Displaying the Results: The final output is formatted into a table with the key information presented in columns: Created/Deleted Time, User, Operation, Team Name, and Result Status.

Enhancing the Script

  • Adding Date Filtering: You can add a date range to narrow down the results to a specific period. For instance, filtering the actions that took place in the last 30 days.
  • $StartDate = (Get-Date).AddDays(-30).ToString("yyyy-MM-ddTHH:mm:ssZ")
    $AuditLogs = Get-MgAuditLogDirectoryAudit -Filter "category eq 'GroupManagement' and (activityDisplayName eq 'Add group' or activityDisplayName eq 'Delete group')" -StartDateTime $StartDate
  • Exporting to CSV: If you'd like to keep a record of the audit logs or further analyze the results, you can easily export the data to a CSV file:
  • $Results | Export-Csv -Path "TeamsAuditLogs.csv" -NoTypeInformation
  • Filter by User: If you’re only interested in actions performed by a specific user, you can modify the script to filter by initiatedBy.userPrincipalName.
  • $AuditLogs = Get-MgAuditLogDirectoryAudit -Filter "initiatedBy/user/userPrincipalName eq 'user@domain.com' and (activityDisplayName eq 'Add group' or activityDisplayName eq 'Delete group')"
  • Filter by Operation: If you only want to see creation or deletion actions, you can update the filter accordingly:
  • # For creation only
    $AuditLogs = Get-MgAuditLogDirectoryAudit -Filter "activityDisplayName eq 'Add group'"

Possible Errors & Solutions

Insufficient Permissions

Error: "Authorization_RequestDenied"

Cause: The user does not have the required permissions.

Solution: Ensure that the user running the script has the AuditLog.Read.All permission in Azure Active Directory.

Empty or Incomplete Results

Error: The script returns empty fields or incomplete results.

Cause: Some audit logs may not contain the expected details, such as team names or user names.

Solution: Check the targetResources and initiatedBy properties for alternative ways to access the missing information. For instance, check the displayName if userPrincipalName is not available.

Rate Limiting

Error: "Too many requests"

Cause: Microsoft Graph API has rate limits that may throttle requests if too many are made in a short period.

Solution: Consider implementing retries with delays or reduce the frequency of script execution.


Conclusion

Tracking Teams creation and deletion actions is an important aspect of maintaining control and oversight within an organization. By leveraging Microsoft Graph PowerShell, administrators can automate the process of querying audit logs and retrieving detailed information about who created or deleted a Team, when the action took place, and whether it was successful. This script can be further customized to meet specific needs, such as filtering by date or user, and can be easily extended to export data for auditing purposes.

With these capabilities, administrators can ensure a more transparent and secure management of Microsoft Teams, ensuring that all actions are properly tracked and reviewed.


© m365corner.com. All Rights Reserved. Design by HTML Codex