Public/Intune/Get-IntuneODJConnectorServiceEventLog.ps1
|
<#
.SYNOPSIS Retrieves and parses event logs from the Microsoft Intune ODJ (Offline Domain Join) Connector Service. .DESCRIPTION This function uses the Get-WinEvent cmdlet to filter and retrieve specific event logs related to the Microsoft Intune ODJ (Offline Domain Join) Connector Service. It parses the event messages to extract structured information such as ActivityId, DeviceId, DeviceName, and other diagnostic data. Intune ODJ Connector Service is responsible for creating Windows computer objects in Active Directory during the device enrollment process via Windows Autopilot. .PARAMETER DeviceId Filters the results to show only events for the specified Device ID (GUID). .PARAMETER DeviceName Filters the results to show only events for the specified Device Name. Supports wildcards. .EXAMPLE Get-IntuneODJConnectorServiceEventLog Retrieves and parses the event logs for the Microsoft Intune ODJ Connector Service, returning structured objects with parsed properties. .EXAMPLE Get-IntuneODJConnectorServiceEventLog | Where-Object { $_.DiagnosticCode -ne 0 } Retrieves parsed event logs and filters for events with non-zero diagnostic codes (potential errors). .EXAMPLE Get-IntuneODJConnectorServiceEventLog -DeviceId 'e078603c-fe1a-488a-a760-415622ff9f45' Retrieves event logs for a specific device ID. .EXAMPLE Get-IntuneODJConnectorServiceEventLog -DeviceName 'DESKTOP-*' Retrieves event logs for devices with names matching the wildcard pattern. .LINK https://ps365.clidsys.com/docs/commands/Get-IntuneODJConnectorServiceEventLog .NOTES Must be executed on the server where the Microsoft Intune ODJ Connector Service is installed to access the relevant event logs. Requires local administrator privileges to read the event logs. Automatically resolves UserID to Active Directory account information (User, gMSA, Computer) when the ActiveDirectory module is available. #> function Get-IntuneODJConnectorServiceEventLog { [CmdletBinding()] param( [Parameter()] [string]$DeviceId, [Parameter()] [string]$DeviceName ) $filterHashTable = @{ LogName = 'Microsoft-Intune-ODJConnectorService/Operational' Id = 30130, 30140 } try { Write-Host -ForegroundColor Cyan 'Querying Windows Event Log...' $events = Get-WinEvent -FilterHashtable $filterHashTable -ErrorAction Stop Write-Host -ForegroundColor Green "Found $($events.Count) raw events" } catch { Write-Warning "Failed to retrieve event logs: $($_.Exception.Message)" return } # Parse the event messages and return structured objects $parsedEvents = [System.Collections.Generic.List[PSCustomObject]]@() Write-Host -ForegroundColor Cyan "Parsing $($events.Count) events..." foreach ($event in $events) { $parsedEvent = [PSCustomObject][ordered]@{ TimeCreated = $event.TimeCreated DeviceName = $null DeviceId = $null EventId = $event.Id UserId = $event.UserId CreatedBy = $null ElapsedMilliseconds = $null DiagnosticCode = $null DiagnosticText = $null EventType = $null } # Parse the message content $message = $event.Message if ($message) { # Extract event type from the first line $firstLine = ($message -split "`n")[0] if ($firstLine -match '^([^:]+):') { $parsedEvent.EventType = $matches[1].Trim() } # Extract structured properties using regex patterns if ($message -match 'ElapsedMilliseconds:\s*(\d+)') { $parsedEvent.ElapsedMilliseconds = [int]$matches[1] } if ($message -match 'DeviceId:\s*([a-fA-F0-9-]+)') { $parsedEvent.DeviceId = $matches[1] } if ($message -match 'DeviceName:\s*(.+)') { $deviceName = $matches[1].Trim() if ($deviceName -ne '') { $parsedEvent.DeviceName = $deviceName } } if ($message -match 'DiagnosticCode:\s*(\d+)') { $parsedEvent.DiagnosticCode = [int]$matches[1] } if ($message -match 'DiagnosticText:\s*(.+)') { $parsedEvent.DiagnosticText = $matches[1].Trim() } } # Resolve UserID to Active Directory account if available if ($event.UserId -and $event.UserId.Value -ne $null) { try { $identity = $event.UserId.Value # Try gMSA first with Get-ADServiceAccount try { $adObject = Get-ADServiceAccount -Identity $identity -Properties SamAccountName -ErrorAction Stop $parsedEvent.CreatedBy = $adObject.SamAccountName } catch { # Fall back to Get-ADObject for other account types try { $adObject = Get-ADObject -Identity $identity -Properties SamAccountName -ErrorAction Stop $parsedEvent.CreatedBy = $adObject.SamAccountName } catch { # Account not found } } } catch { # Silently ignore if AD module not available } } $parsedEvents.Add($parsedEvent) } Write-Host -ForegroundColor Green "Parsed $($parsedEvents.Count) events successfully" # Apply filters only if explicitly provided if ($PSBoundParameters.ContainsKey('DeviceId') -and $DeviceId) { Write-Host -ForegroundColor Cyan "Filtering events for Device ID: $DeviceId" $parsedEvents = $parsedEvents | Where-Object { $_.DeviceId -eq $DeviceId } Write-Host -ForegroundColor Green "Found $($parsedEvents.Count) matching events" } if ($PSBoundParameters.ContainsKey('DeviceName') -and $DeviceName) { Write-Host -ForegroundColor Cyan "Filtering events for Device Name: $DeviceName" $parsedEvents = $parsedEvents | Where-Object { $_.DeviceName -like $DeviceName } Write-Host -ForegroundColor Green "Found $($parsedEvents.Count) matching events" } return $parsedEvents } |