internal/functions/remoting/Invoke-SessionCommand.ps1
function Invoke-SessionCommand { <# .SYNOPSIS Executes a command in an already provided session and returns the results in a consistent manner. .DESCRIPTION Executes a command in an already provided session and returns the results in a consistent manner. This simplifies error handling, especially ErrorAction for errors that happen remotely. This command will never throw an error - it will always only return an object with three properties: + Success (bool): Whether the operation succeeded. + Error (ErrorRecord): If it failed, the error record. Will be deserialized, if it was not a remoting error. + Data (object): Any return values the scriptblock generated. .PARAMETER Session The session to invoke the command in. .PARAMETER Code The Code to execute .PARAMETER ArgumentList The arguments to pass to the code .EXAMPLE PS C:\> Invoke-SessionCommand -Session $session -Code { Remove-Item -Path C:\Temp\* -Force -Recurse -ErrorAction stop } Tries to delete all items under C:\Temp in the remote session. Successful or not, it will always return a return object, reporting the details. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [System.Management.Automation.Runspaces.PSSession] $Session, [Parameter(Mandatory = $true)] [scriptblock] $Code, [object[]] $ArgumentList ) process { $data = @{ Code = $Code ArgumentList = $ArgumentList } $scriptblock = { param ($Data) try { # Local Execution, but with Invoke-Command so that the arguments properly enumerate $result = Invoke-Command ([scriptblock]::Create($Data.Code.ToString())) -ArgumentList $Data.ArgumentList [PSCustomObject]@{ Success = $true Error = $null Data = $result } } catch { [PSCustomObject]@{ Success = $false Error = $_ Data = $null } } } try { Invoke-Command -Session $Session -ScriptBlock $scriptblock -ArgumentList $data -ErrorAction Stop } catch { [PSCustomObject]@{ Success = $false Error = $_ Data = $null } } } } |