custom/Invoke-BcPowerShellCommand.ps1

Function Invoke-BcPowerShellCommand {
    [cmdletbinding(DefaultParameterSetName = 'ByName')]
    param (
        [Parameter(
            ParameterSetName = 'ByName',
            Mandatory
        )]
        [Parameter(
            ParameterSetName = 'ByNameRaw',
            Mandatory
        )]
        [Alias('Name', 'AssetName')]
        [string]$RunnerName,

        [Parameter(
            ParameterSetName = 'ById',
            Mandatory
        )]
        [Parameter(
            ParameterSetName = 'ByIdRaw',
            Mandatory
        )]
        [Alias('Id', 'RunnerId')]
        [string]$AssetId,

        [Parameter(Mandatory)]
        [Alias('Command')]
        [scriptblock]$ScriptBlock,

        [switch]$PWSH,

        [switch]$LeaveJob,

        [Parameter(
            ParameterSetName = 'ById'
        )]
        [Parameter(
            ParameterSetName = 'ByName'
        )]
        [int]$SerializeDepth = 2,

        [Parameter(
            ParameterSetName = 'ById'
        )]
        [Parameter(
            ParameterSetName = 'ByName'
        )]
        [switch]$DefaultPropertiesOnly,

        [Parameter(
            ParameterSetName = 'ByIdRaw',
            Mandatory
        )]
        [Parameter(
            ParameterSetName = 'ByNameRaw',
            Mandatory
        )]
        [switch]$Raw
    )
    # Load the run command from the Action Repository
    $runCommand = Get-BcRepository -Name 'PowerShell:RunCommand'

    if ($null -ne $runCommand) {
        # If RunnerID is not passed, look it up
        if ($PSCmdlet.ParameterSetName -like 'ByName*') {

            $AssetId = (Get-BcRunnerByName -AssetName $RunnerName).AssetId
        }

        # Create a set to assign the job to
        $assignSet = New-BcSet

        # Add the runner to the Job
        Add-BcSetToSet -TargetSetId $assignSet -ObjectIds $AssetId | Out-Null

        # Generate a name, it should use Get-BcJobRandomJobName,
        # however that is currently bugged.
        $jobName = Get-BcJobRandomJobName

        # Create the job
        $nj = New-BcJob -IsEnabled -IsHidden:$false -EndpointSetId $assignSet -Name $jobName -Schedule (New-BcJobScheduleObject -ScheduleType 'RunNow' -RepeatMinutes 0) -Actions @(
            @{
                RepositoryActionId = $runCommand.Id
                Settings           = @{
                    Command                   = $ScriptBlock
                    PWSH                      = $PWSH.IsPresent
                    'Serialize Depth'         = $SerializeDepth
                    'Default Properties Only' = $DefaultPropertiesOnly.IsPresent
                    'Debug'                   = $true
                    'Raw Output'              = $Raw.IsPresent
                }
            }
        )
        
        # Wait for the job to complete
        $job = Get-BcJob -JobId $nj.JobId
        While ($job.TotalEndpointsFinished -lt $job.TotalEndpointsAssigned) {
            Start-Sleep -Seconds 2
            $job = Get-BcJob -JobId $nj.JobId
        }

        # Once it completes, look up the thread id for the job and runner
        $completedThread = Get-BcJobThread -JobId $job.Id | Where-Object { $_.ProdigalObjectId -eq $AssetId }
        
        # With the thread ID, pull the thread log
        Get-BcJobThreadLastLog -ThreadId $completedThread.Id -OutFile .\rwtmp.txt

        if ($Raw.IsPresent) {
            # Get the contents
            Get-Content .\rwtmp.txt | Where-Object { $_ -notlike '# *' }
        } else {
            # Write the content to disk, it will be in CliXml format
            Get-Content .\rwtmp.txt | Where-Object { $_ -notlike '# *' } | Out-File .\results.xml -Force

            # Import the output
            Import-Clixml .\results.xml

            # Clean up XML file
            Remove-Item .\results.xml
        }

        # Clean up the files
        Remove-Item .\rwtmp.txt

        # Clean up the job
        if (-not $LeaveJob.IsPresent) {
            Remove-BcJob -JobId $nj.JobId | Out-Null
        }
    } else {
        Write-Warning "Unable to find 'PowerShell:RunCommand' action. Add the command to your Runway tenant and then retry."
    }
}