Workspace ONE UEM Workflow Log parser

Ok a real quick one, this is something that I QUICKLY whipped up, its not the prettiest code, its almost embarassing in parts, but Im flat out like a lizard drinking, so I dont have a lot of time to make things pretty or put in a massive blurb, but this is useful enough in its current form for someone to use, or take and improve.. or laugh at. You do you 😀

Its a simple function that reads in the Workflow log created by UEM, it may work for other logs, but the highlighting it does is written specifically for workflow. The Remove-StepID function does what it says on the label, and is required.

I’ve included a -search paramater which will highlight lines in the output to make life easier to find things.

Hopefully this makes someones life easier.

    Function Remove-StepID
        {
        param
            (
            $InputObject
            )
        $ErrorActionPreference="SilentlyContinue"
        if($InputObject.indexof("StepId") -gt 0)
            {
            Return $InputObject.substring(0,($InputObject.indexof("StepId")))
            }
        else
            {
            Return $InputObject
            }
        }


Function Get-Ws1WorkFlowLog
    {
    <#
    .Description
    This function parses the UEM Workflow logs and turns them in to something a little more easy to ready

    .PARAMETER FileName
    Name of the Log File.
    
    .PARAMETER Search
    A basic search, this will highlight lines in the log
    .EXAMPLE
    PS> Get-WS1WorkFlowLog -FileName c:\programdata\airwatch\unifiedagent\logs\workflow-20230905.log
    .EXAMPLE
    PS> Get-WS1WorkFlowLog -FileName c:\programdata\airwatch\unifiedagent\logs\workflow-20230905.log -Search MyAwesomeApp
    #>
    param
        (
        $FileName,
        $Search
        )

    $LogContents=get-content $FileName | ConvertFrom-Json
    $ConvertedLog=@()
    $i=0
    Foreach($logline in $LogContents)
        {

        $Obj=New-Object psobject
        [datetime]$date=$Logline.'@t'
        $FormattedDate=get-date $date -Format "yyyy-MM-dd HH:mm:ss"
        If($logline.'@l' -eq $Null)
            {
            $LogLevel=""
            }
        else
            {
            $LogLevel=$Logline.'@l'
            }
        $Message=$Logline.'@mt'

        $pattern = '\{([^}]*)\}'
        $matches = $Message | Select-String -Pattern $pattern -AllMatches | ForEach-Object { $_.Matches } | ForEach-Object { $_.Groups[1].Value }

        if($Matches.count -gt 0)
            {
            Switch ($Matches.count)
                {
                1
                    {
                    $prop=$matches
                    $prop=$prop -replace "@",""
                    $ExtendedLine=$Logline.$prop
                    Switch($prop)
                        {
                        "Step"
                            {
                            
                            $ParamJson=$logline.$prop.Parameters |convertFrom-json
                            $Message="Processing Task Step '{0}',Version: {1},TimeOut={2}" -f (Remove-StepID -InputObject $logline.$prop.StepName),$ParamJson.Version,$logline.$prop.TimeoutSeconds
               
                            break
                            }
                        "TaskResult"
                            {
                            $message="Call Handle result '{0}',Proceed: {1}, EventName: {2}, Status: {3},ErrorCode: {4},IsError: {5}" -f $logline.ProcessName,$logline.$Prop.Proceed,$logline.$Prop.EventName,$logline.$Prop.EventName,$logline.$Prop.Status,$logline.$Prop.StepExecutionErrorCode,$logline.$Prop.IsErrorCaught
                            break
                            }
                        "WorkFlowRequest"
                            {
                            $Message="Registering the workflow: {0},Version: {1},Type: {2}" -f $logline.WorkflowRequest.WorkflowName,$logline.WorkflowRequest.Version,$logline.WorkflowRequest.Version
                            }
                        Default
                            {
                            $Message=$message -replace "{$prop}",$Logline.$prop
                            }
                    
                        }#End logline prop switch
                    break
                    }
                2
                    {
                    $Prop=$matches[1] -replace "@",""
                    $type=$matches[0] -replace "@",""
                    $message=$Message -replace "@",""
                    [string]$ExtendedLine=$Logline.$Prop
                    $ExtraInfo=""

                    Switch($type)
                        {
                        "ScheduleWrapper"
                            {
                            
                            If ($logline.$type.body -eq $null)
                                {
                                $Body=$logline.$type
                                }
                            else
                                {
                                $body=$logline.$type.body
                                }
                            If ($prop = "StepKey")
                                {
                                $ExtraInfo=Remove-StepID $logline.$prop
                                }
                            else
                                {
                                $ExtraInfo=$body | convertfrom-json | Select StepName -ExpandProperty Stepname
                                $Extrainfo=Remove-StepID -InputObject $ExtraInfo
                                $logline.$type="ScheduledWrapper"
                                }
                            break
                            }
                        "ScheduleMessage"
                            {
                            $logline.$type=Remove-StepID -InputObject $logline.$type.StepName
                            break
                            }
                        "StepName"
                            {
                            $logline.$type=Remove-StepID -InputObject $logline.$type
                            break
                            }
                        }
                
                   $Message=$message -replace "{$type}",$Logline.$type
               
                
                    If($ExtendedLine.StepName)
                        {
                    
                        $ExtraInfo+="Step: {0}" -f (Remove-StepID -InputObject $Extendedline.StepName)

                        }
                    Switch($Prop)
                        {
                        "StepExecutionResult"
                            {
                            $ExtraInfo += "EventName: {3},Proceed: {0},Output: {1},Status: {2},ErrorCode: {4},ErrorCaught: {5}" -f $Logline.$prop.Proceed,$Logline.$prop.Output,$Logline.$prop.Status,$logline.$prop.EventName,$logline.$prop.StepExecutionErrorCode,$logline.$prop.IsErrorCaught
                            break
                            }
                        "EventData"
                            {
                            If($logline.$type -eq "WorkflowCompletedEvent" -or $logline.$Type -eq "WorkflowInProgressEvent")
                                {
                                $ExtraInfo=$logline.$prop.WorkflowUuid
                                }
                            else
                                {
                                $ExtraInfo=Remove-StepID -InputObject $Logline.$prop.StepName
                                }
                            break
                            }
                        }#End Prop switch

                
                    if($ExtraInfo -eq "")
                        {
                        $extraInfo=Remove-StepID -InputObject $ExtendedLine
                        }
                
                    $message=$message -replace "{$prop}",$ExtraInfo

                   ### After here for messages that totally need changing
                    if($type -eq "ApplicationDetails")
                        {
                        $message="Application Details: Name: {0} v{1}, Installed {2}, LastAction: {3}, LastError: {4},ErrorDesc: {5},StatusReason: {6}, ProductCode: {7}" -f $logline.$type.Name,$logline.$type.Version,$logline.$type.IsInstalled,$logline.$type.LastAction,$logline.$type.LastError,$logline.$type.LastErrorDesc,$logline.$type.StatusReason,$logline.ProductCode
                        }                   
                    break
                    }
                3
                    {
                    $First=$matches[0] -replace "@",""
                    $Second=$matches[1] -replace "@",""
                    $Third=$matches[2] -replace "@",""
                    $message=$Message -replace "@",""
                    $ExtendedLine=$Logline.$Prop
                    $ExtraInfo=""

                    $message=$Message -replace "{$first}",(Remove-StepID -InputObject $logline.$first)
                    $message=$Message -replace "{$Second}",(Remove-StepID -InputObject $logline.$Second)
                    $message=$Message -replace "{$Third}",(Remove-StepID -InputObject $logline.$Third)
                    break
                    }
                4
                    {
                    $First=$matches[0] -replace "@",""
                    $Second=$matches[1] -replace "@",""
                    $Third=$matches[2] -replace "@",""
                    $Fourth=$matches[3] -replace "@",""
                    $message=$Message -replace "@",""
                    $ExtendedLine=$Logline.$Prop
                    $ExtraInfo=""
                    $message=$Message -replace "{$first}",(Remove-StepID -InputObject $logline.$first.ToString())
                    $message=$Message -replace "{$Second}",(Remove-StepID -InputObject $logline.$Second.ToString())
                    $message=$Message -replace "{$Third}",(Remove-StepID -InputObject $logline.$Third.ToString())
                    $message=$Message -replace "{$Fourth}",(Remove-StepID -InputObject $logline.$Fourth.ToString())
                    break

                    }
                }#end switch
            }
        else
            {
            $ExtendedLine=""
            }
    
        Add-member -InputObject $Obj -MemberType NoteProperty -Name Line -Value $i
        Add-Member -InputObject $obj -MemberType NoteProperty -Name DateTime -Value $FormattedDate
        Add-Member -InputObject $obj -MemberType NoteProperty -Name Level -Value $LogLevel
        Add-Member -InputObject $obj -MemberType NoteProperty -Name Message -Value $Message
        $ConvertedLog += $obj
        $i++
        }


        Foreach($line in $ConvertedLog)
                                                                                                                                                                                                                                                                                    {
        if($line.Level -eq "")
            {
            $line.Level="     "
            }
    
        $Output="{0}  {1}  {2}  {3}" -f $line.Line,$line.DateTime,$line.Level,$line.Message
        $Pattern="Status: Completed"
        switch -Wildcard ($line)
            {
            {$_.Message -like "*$Search*" -AND $search -ne $null}
                {
                Write-host $Output -BackgroundColor Blue -ForegroundColor white
                break
                }
            {$_.Message -like "*Profile installed successfully*"}
                {
                Write-Host $output -ForegroundColor Green
                break
                }
            {$_.Message -like "*Message : Success*"}
                {
                Write-Host $output -ForegroundColor Green
                break
                }
            {$_.Message -like "*Received 'WorkflowStepInProgressEvent'*"}
                {
                Write-Host $output -ForegroundColor DarkYellow
                break
                }
            {$_.Message -like "*Message : ProfileActivated*"}
                {
                Write-Host $output -ForegroundColor green
                break
                }

            {$_.Message -like "*Status: WaitingToBeRetried*"}
                {
                Write-Host $output -ForegroundColor DarkYellow
                break
                }

            {$_.Message -like "*Proceed: False*"}
                {
                Write-Host $output -ForegroundColor red
                break
                }
            {$_.Message -like "*Status: Completed*"}
                {
                Write-Host $output -ForegroundColor Green
                break
                }
            {$_.Message -like "*Status: WaitingForEvent*"}
                {
                Write-Host $output -ForegroundColor DarkCyan
                break
                }
            {$_.Level -eq "Error"}
                {
                Write-Host $output -ForegroundColor Red
                break
                }
            {$_.Level -eq "Warning"}
                {
                Write-Host $output -ForegroundColor Yellow
                break
                }
            
                default
                {
                Write-Host $output
                }
           }#End Switch
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.