Public/Jobs/Get-RMMJobResult.ps1
|
<#
Copyright (c) 2025-2026 Robert Faddes SPDX-License-Identifier: MPL-2.0 #> function Get-RMMJobResult { <# .SYNOPSIS Retrieves job execution results and output for a specific device from the Datto RMM API. .DESCRIPTION Retrieves execution results, standard output, and error output for a job on a specific device in the Datto RMM system. You can specify JobUid and DeviceUid directly, or pipe ActivityLog objects (from Get-RMMActivityLog) with Entity: Device, Category: Job, and Action: Deployment. The -UseExperimentalDetailClasses switch must be used with Get-RMMActivityLog to provide the required detail type (DRMMActivityLogDetailsDeviceJobDeployment). Non-deployment activity logs are safely skipped with a warning. .PARAMETER JobUid The unique identifier (GUID) of the job. .PARAMETER DeviceUid The unique identifier (GUID) of the device associated with the job results. .PARAMETER ActivityLog An activity log object (from Get-RMMActivityLog -Entity Device -Category Job -Action Deployment -UseExperimentalDetailClasses) containing job deployment details. Can be piped to this function. Non-deployment activity logs are skipped with a warning. .PARAMETER IncludeOutput Switch to retrieve standard output and error output for the job result, if available. .EXAMPLE Get-RMMJobResult -JobUid $JobUid -DeviceUid $DeviceUid Retrieves the execution results for a job on a specific device. .EXAMPLE Get-RMMJobResult -JobUid $JobUid -DeviceUid $DeviceUid -IncludeOutput Retrieves the execution results and includes standard output and error output for the job. .EXAMPLE Get-RMMActivityLog -Entity Device -Category Job -Action Deployment -UseExperimentalDetailClasses | Get-RMMJobResult Retrieves job results for all deployment job activity logs for devices. The -UseExperimentalDetailClasses switch is required to provide the correct detail type for piping. .INPUTS System.Guid, DRMMActivityLog. You can pipe ActivityLog objects to this function. .OUTPUTS DRMMJobResults. Returns job result objects. If -IncludeOutput is used, includes standard output and error output. .NOTES This function requires an active connection to the Datto RMM API. Use Connect-DattoRMM to authenticate before calling this function. For details on -UseExperimentalDetailClasses, see Get-RMMActivityLog help. .LINK https://github.com/TheShadowTek/DattoRMM.Core/blob/main/docs/commands/Jobs/Get-RMMJobResult.md .LINK about_DRMMJobResult .LINK Get-RMMActivityLog .LINK Get-RMMJob .LINK New-RMMQuickJob #> [CmdletBinding(DefaultParameterSetName = 'JobUid')] param ( # Unique identifier for the Datto RMM job. [Parameter( ParameterSetName = 'JobUid', Mandatory = $true )] [guid] $JobUid, # Unique identifier for the device associated with the job results. [Parameter( ParameterSetName = 'JobUid', Mandatory = $true )] [guid] $DeviceUid, # Activity log object containing details about the job. [Parameter( ParameterSetName = 'ActivityLog', Mandatory = $true, ValueFromPipeline = $true )] [DRMMActivityLog] $ActivityLog, [Parameter( Mandatory = $false )] [switch] $IncludeOutput ) begin { Write-Debug "Getting RMM job results with parameter set: $($PSCmdlet.ParameterSetName)" } process { switch ($PSCmdlet.ParameterSetName) { 'ActivityLog' { if ($ActivityLog.Details -isnot [DRMMActivityLogDetailsDeviceJobDeployment]) { Write-Warning "The provided ActivityLog object is not of type DRMMActivityLogDetailsDeviceJobDeployment. Only job deployment logs are supported. Entity: Device, Category: Job, Action: Deployment." return } else { $APIResultsPath = "job/$($ActivityLog.Details.JobUid)/results/$($ActivityLog.Details.DeviceUid)" $JobUid = $ActivityLog.Details.JobUid $DeviceUid = $ActivityLog.Details.DeviceUid } } 'JobUid' { $APIResultsPath = "job/$JobUid/results/$DeviceUid" } } $APIMethod = @{ Path = $APIResultsPath Method = 'Get' } $JobResult = Invoke-ApiMethod @APIMethod | ForEach-Object {[DRMMJobResults]::FromAPIMethod($_)} if ($IncludeOutput) { if ($JobResult.HasStdOut) { $StdOutAPIMethod = @{ Path = "$APIResultsPath/stdout" Method = 'Get' } $JobResult.StdOut = Invoke-ApiMethod @StdOutAPIMethod | ForEach-Object {[DRMMJobStdData]::FromAPIMethod($_, $JobUid, $DeviceUid, 'StdOut')} } if ($JobResult.HasStdErr) { $StdErrAPIMethod = @{ Path = "$APIResultsPath/stderr" Method = 'Get' } $JobResult.StdErr = Invoke-ApiMethod @StdErrAPIMethod | ForEach-Object {[DRMMJobStdData]::FromAPIMethod($_, $JobUid, $DeviceUid, 'StdErr')} } } return $JobResult } } # SIG # Begin signature block # MIIF+wYJKoZIhvcNAQcCoIIF7DCCBegCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCALwYJ2oZlq/Njs # ICf3Pw2Klbo1tOGInZ4XbyXRLQ4Zt6CCA04wggNKMIICMqADAgECAhB464iXHfI6 # gksEkDDTyrNsMA0GCSqGSIb3DQEBCwUAMD0xFjAUBgNVBAoMDVJvYmVydCBGYWRk # ZXMxIzAhBgNVBAMMGkRhdHRvUk1NLkNvcmUgQ29kZSBTaWduaW5nMB4XDTI2MDMz # MTAwMTMzMFoXDTI4MDMzMTAwMjMzMFowPTEWMBQGA1UECgwNUm9iZXJ0IEZhZGRl # czEjMCEGA1UEAwwaRGF0dG9STU0uQ29yZSBDb2RlIFNpZ25pbmcwggEiMA0GCSqG # SIb3DQEBAQUAA4IBDwAwggEKAoIBAQChn1EpMYQgl1RgWzQj2+wp2mvdfb3UsaBS # nxEVGoQ0gj96tJ2MHAF7zsITdUjwaflKS1vE6wAlOg5EI1V79tJCMxzM0bFpOdR1 # L5F2HE/ovIAKNkHxFUF5qWU8vVeAsOViFQ4yhHpzLen0WLF6vhmc9eH23dLQy5fy # tELZQEc2WbQFa4HMAitP/P9kHAu6CUx5s4woLIOyyR06jkr3l9vk0sxcbCxx7+dF # RrsSLyPYPH+bUAB8+a0hs+6qCeteBuUfLvGzpMhpzKAsY82WZ3Rd9X38i32dYj+y # dYx+nx+UEMDLjDJrZgnVa8as4RojqVLcEns5yb/XTjLxDc58VatdAgMBAAGjRjBE # MA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQU # H+B0vf97dYXqdUX1YMcWhFsY6fcwDQYJKoZIhvcNAQELBQADggEBAJmD4EEGNmcD # 1JtFoRGxuLJaTHxDwBsjqcRQRE1VPZNGaiwIm8oSQdHVjQg0oIyK7SEb02cs6n6Y # NZbwf7B7WZJ4aKYbcoLug1k1x9SoqwBmfElECeJTKXf6dkRRNmrAodpGCixR4wMH # KXqwqP5F+5j7bdnQPiIVXuMesxc4tktz362ysph1bqKjDQSCBpwi0glEIH7bv5Ms # Ey9Gl3fe+vYC5W06d2LYVebEfm9+7766hsOgpdDVgdtnN+e6uwIJjG/6PTG6TMDP # y+pr5K6LyUVYJYcWWUTZRBqqwBHiLGekPbxrjEVfxUY32Pq4QfLzUH5hhUCAk4HN # XpF9pOzFLMUxggIDMIIB/wIBATBRMD0xFjAUBgNVBAoMDVJvYmVydCBGYWRkZXMx # IzAhBgNVBAMMGkRhdHRvUk1NLkNvcmUgQ29kZSBTaWduaW5nAhB464iXHfI6gksE # kDDTyrNsMA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKAAKEC # gAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwG # CisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIL/jjAHg0D5o+B3EHzBJa6S84tNf # VLbQ+PPRkf3JK9fEMA0GCSqGSIb3DQEBAQUABIIBADBVeInDpR6GOKYHlu+fVZZh # zUdBKptvPomhrbPF6fn5W25wdO6YAPCLcy3ph2a08QLs1SsYeCE/hes13MChdRxt # w4lIzSla5dqG5+FawaVuHwVG9FK4oKKBtn1ak4PsJZNdBeWhN292tJtr+UdItOQH # uCLC1Z1XolevAtBDUs/3U/F0ORKKAIi8CtpRz/LuGHcB5GlYJzd2TI0/dozZnQbf # 6jMIW1wGFlt/7/Gt65zVTFB4m0uj2S8vF9AV21L/WdR/HaYfWbFkexpz4ZR8TZZ9 # P7R4lQ+55kQsLQV5/9YXcobjD6+OeG3snOcyuHkVMH0+ZMzTsziKxH+Li7Y4NhY= # SIG # End signature block |