lib/LegacyHandler.ps1
#region Legacy Handler # $EventHandler_CollectAndReportJobDetails = [scriptblock] { # try { # ## Disable Error Stops so we can receive the data back and continue running # $ErrorActionPreference = 'Continue' # ## Get the Runspaces in the Remote Session # $RunspaceJobs = Get-RSJob # Write-Host 'Runspace Count: '$RunspaceJobs.Count # # # ## Connect to each Runspace and create a report of it's status # # # $RunspaceReports = [System.Collections.ArrayList] @() # # # foreach ($RunspaceJob in $RunspaceJobs) { # # # ## Create the TaskIdString used to report status to TMD # # # $TaskId = $RunspaceJob.Name.split('_') | Select-Object -First 1 # # # ## Disable Error Throws so we can receive the data back and handle it conditionally # # # $ErrorActionPreference = 'Continue' # # # ## Check for Errors and get the Error String # # # # Write-Host 'ERROR ERROR ERROR: ErrorItem has Exception' # # # # if ($RunspaceJob.HasErrors) { # # # # ## Create an array of strings to return # # # # $ErrorStrings = [System.Collections.ArrayList]@() # # # # ## Iterate over each Error in the Runspace Error list # # # # foreach ($ErrorItem in $RunspaceJob.Error) { # # # # ## Not all Errors have an Exception node, it may just be a text Error # # # # if ($ErrorItem.Exception) { # # # # ## Exceptions might be an exception, or an error record. # # # # if ($ErrorItem.Exception.Message) { # # # # # Write-Host 'ERROR ERROR ERROR: ErrorItem has Exception.Message'$ErrorItem.Exception.Message # # # # $ErrorStrings.Add($ErrorItem.Exception.Message) | Out-Null # # # # } # # # # elseif ($ErrorItem.Exception.ErrorRecord) { # # # # # Write-Host 'ERROR ERROR ERROR: ErrorItem has Exception.Message'$ErrorItem.Exception.ErrorRecord # # # # $ErrorStrings.Add($ErrorItem.Exception.ErrorRecord) | Out-Null # # # # } # # # # else { # # # # # Write-Host 'ERROR ERROR ERROR: ErrorItem is not a known exception type'$ErrorItem.Exception.toString() # # # # $ErrorStrings.Add($ErrorItem.Exception.ToString()) | Out-Null # # # # } # # # # } # # # # else { # # # # # Write-Host 'ERROR ERROR ERROR: ErrorItem does NOT have an Exception' # # # # $ErrorStrings.Add('Unhandled Error. No error message returned from the process.') | Out-Null # # # # } # # # # ## With an Exception Thrown, Mark the job for removal immediately # # # # if ($ErrorStrings.Count -gt 0) { # # # # ## Add a removal timestamp of now so the job is removed on this pass # # # # $Global:RemoteSessionCache.RemoveJobAfter | Add-Member -NotePropertyName $TaskIdString -NotePropertyValue (Get-Date) -Force # # # # } # # # # } # # # # } # # # ## Return a formatted object back for SessionManager to interpret and process without using the session # # # ## Parts of this Object are piped into a ConvertTo-JSON so they are snapped and no live items are returned. # # # # $RunspaceReport = @{ # # # # Type = 'RunspaceReport' # # # # TaskIdString = $TaskIdString; # # # # Runspace = @{ # # # # Guid = $RunspaceJob.InstanceId # # # # <# # # # # RunspaceJob States # # # # https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.psinvocationstate?view=powershellsdk-7.0.0 # # # # ENUMS # # # # ================== # # # # Completed 4 PowerShell has completed executing a command. # # # # Disconnected 6 PowerShell is in disconnected state. # # # # Failed 5 PowerShell completed abnormally due to an error. # # # # NotStarted 0 PowerShell has not been started # # # # Running 1 PowerShell is executing # # # # Stopped 3 PowerShell is completed due to a stop request. # # # # Stopping 2 PowerShell is stoping execution. # # # # #> # # # # State = $RunspaceJob.State # # # # HasErrors = $RunspaceJob.HasErrors # # # # Output = $RunspaceJob.Output # # # # Errors = $ErrorStrings # # # # ## Stream objects have too much information lost when they are passed from the session back to the Session Manager. # # # # ## Convert them to JSON and return them as structured text. # # # # Streams = @{ # # # # Information = $RunspaceJob.InnerJob.Streams.Information | ConvertTo-Json -Compress -ErrorAction 'SilentlyContinue' # # # # Progress = $RunspaceJob.InnerJob.Streams.Progress | ConvertTo-Json -Compress -ErrorAction 'SilentlyContinue' # # # # Verbose = $RunspaceJob.Verbose #| ConvertTo-Json -Compress -ErrorAction 'SilentlyContinue') # # # # Debug = $RunspaceJob.Debug #| ConvertTo-Json -Compress -ErrorAction 'SilentlyContinue') # # # # Warning = $RunspaceJob.Warning #| ConvertTo-Json -Compress -ErrorAction 'SilentlyContinue') # # # # } # # # # } # # # # } | ConvertTo-Json -Compress # # # # ## Add the JSON Runspace Report to the Runspace Queue # # # # $RunspaceReports.Add($RunspaceReport) | Out-Null # # # # ## Clear the Output Queue and Streams # # # # if ($RunspaceJob.HasMoreData) { # # # # ## Clear the Output Queue # # # # $RunspaceJob | Receive-RSJob | Out-Null # # # # } # # # # ## Clear the Output Streams # # # # $RunspaceJob.InnerJob.Streams.ClearStreams() # # # # ## Add a debug token # # # # # $RunspaceReports.Add((@{ # # # # # Type = 'DebugReport' # # # # # Message = ('Checking Status of Runspace ' + $TaskIdString + ', Runspace.State ' + $RunspaceJob.State) # # # # # } | ConvertTo-Json -Compress)) | Out-Null # # # # ## Mark the Job for removal. This allows for the data to be collected before the job is removed at the end of this loop # # # # ## Failed = 5, Completed = 4 # # # # if (($RunspaceJob.State -in $FinishedJobStatuses) -and (-Not $RunspaceJob.HasMoreData)) { # # # # ## Check the RemoteSessionCache list for this existing JobId # # # # if ($Global:RemoteSessionCache.RemoveJobAfter.PSObject.Properties.Name -notcontains $TaskIdString) { # # # # ## Create a RemoveAfter timestamp # # # # $RemoveAfter = (Get-Date).AddSeconds(-1) # # # # $Global:RemoteSessionCache.RemoveJobAfter | Add-Member -NotePropertyName $TaskIdString -NotePropertyValue $RemoveAfter # # # # # ## Add a debug token # # # # # $RunspaceReports.Add(([PSCustomObject]@{ # # # # # Type = 'DebugReport' # # # # # Message = ('Marking Task ID ' + $TaskIdString + ' for removal at ' + $RemoveAfter) # # # # # } | ConvertTo-Json -Compress)) | Out-Null # # # # } # # # # } # # # # ## Check the RemoteSessionCache list for this existing JobId # # # # if ($Global:RemoteSessionCache.RemoveJobAfter.PSObject.Properties.Name -contains $TaskIdString) { # # # # ## Get the timestamp details of when the Job can be removed # # # # $PermittedRemovalTimestamp = $Global:RemoteSessionCache.RemoveJobAfter.$TaskIdString # # # # $TimeUntilRemoval = New-TimeSpan -Start (Get-Date) -End $PermittedRemovalTimestamp # # # # # ## Add a debug token # # # # # $RunspaceReports.Add(([PSCustomObject]@{ # # # # # Type = 'DebugReport' # # # # # Message = ('Checking Task ID ' + $TaskIdString + ' if the removal time at ' + $RemoveAfter + ' is after ' + (Get-Date)) # # # # # } | ConvertTo-Json -Compress)) | Out-Null # # # # ## Check the RemoveAfter timestamp # # # # if ($TimeUntilRemoval.TotalSeconds -lt 0) { # # # # ## Remove the Runspace from the Session List # # # # $Global:RemoteSessionCache.RemoveJobAfter.PSObject.Properties.Remove($TaskIdString) # # # # if ($OutputVerbose) { Write-Host 'Removing Runspace Job: '$RunspaceJob.Id } # # # # ## Remove the Runspace Job itself # # # # Remove-RSJob $RunspaceJob | Out-Null # # # # ## Create a Task End report # # # # $TaskEndReport = @{ # # # # Type = 'TaskEndReport'; # # # # TaskIdString = $TaskIdString; # # # # State = $RunspaceJob.State # # # # } | ConvertTo-Json -Compress # # # # $RunspaceReports.Add($TaskEndReport) | Out-Null # # # # } # # # # } # # # # ## Return any Runspace reports provided # # # # $RunspaceReports # # # } # } # catch { # Write-Host 'VERBOSE: ' $_ # } # } #endRegion |