2

I am using a PowerShell module called Logging. I use other Jobs to do some work, but unforunately the logs that I write in them are not received by the command Receive-Job.

function Get-Topic {
    [CmdletBinding(DefaultParameterSetName = "Normal")]
    [OutputType(ParameterSetName = "Normal")]
    [OutputType(ParameterSetName = "AsJob")]
    param (
        [Parameter(Mandatory = $true, ParameterSetName = "Normal")]
        [Parameter(Mandatory = $true, ParameterSetName = "AsJob")]
        [string]
        $ResourceGroupName,

        [Parameter(Mandatory = $true, ParameterSetName = "Normal")]
        [Parameter(Mandatory = $true, ParameterSetName = "AsJob")]
        [string]
        $Namespace,

        [Parameter(Mandatory = $true, ParameterSetName = "Normal")]
        [Parameter(Mandatory = $true, ParameterSetName = "AsJob")]
        [string]
        $Topic,

        [Parameter(Mandatory = $true, ParameterSetName = "AsJob")]
        [switch]
        $AsJob
    )

    if ($AsJob) {
        $PSBoundParameters.Remove('AsJob') | Out-Null
        return Start-ThreadJob -ScriptBlock {
            param(
                [string]$myFunction,
                [System.Collections.IDictionary]$argTable,
                [System.Collections.Concurrent.ConcurrentDictionary[string, hashtable]] $loggingTargets
            )

            $loggingTargets.Keys | ForEach-Object { Add-LoggingTarget -Name $_ -Configuration $loggingTargets[$_] }
            $cmd = [scriptblock]::Create($myFunction)

            & $cmd @argTable
        } -ArgumentList $MyInvocation.MyCommand.Definition, $PSBoundParameters, (Get-LoggingTarget)
    }

    $topicObj = Get-AzServiceBusTopic `
        -ResourceGroupName $ResourceGroupName `
        -Namespace $Namespace `
        -Name $Topic
    Write-Log -Message "Received topic $($topicObj.Name)" -Level INFO
    return $topicObj
}

Is there any way to redirect the output to the parent powershell session? I saw that Write-Host works, but the logger with the Console target doesn't. Any workarounds for this?

Garbem
  • 149
  • 1
  • 13
  • I looked more into it and apparently the Information/Warning/Error output streams are empty aswell. Anybody having experience with this module? – Garbem Oct 12 '20 at 08:38

1 Answers1

1

The solution is the following:

return Start-ThreadJob -StreamingHost (Get-Host) -ScriptBlock {
            param(
                [string]$myFunction,
                [System.Collections.IDictionary]$argTable,
                [System.Collections.Concurrent.ConcurrentDictionary[string, hashtable]] $loggingTargets
            )

            $loggingTargets.Keys | ForEach-Object { Add-LoggingTarget -Name $_ -Configuration $loggingTargets[$_] }
            $cmd = [scriptblock]::Create($myFunction)

            & $cmd @argTable
        } -ArgumentList $MyInvocation.MyCommand.Definition, $PSBoundParameters, (Get-LoggingTarget)

Thanks god the cmdlet Start-ThreadJob allows for such a functionality, basically the param -StreamingHost solved the deal

Garbem
  • 149
  • 1
  • 13
  • Hi @garbem, I'm the author of the Logging module; I'm glad you worked out to resolve the issue cause the module doesn't support runspaces as it uses itself runspaces to offload the targets. If you want to submit a PR on github feel free, contribution are welcome. – EsOsO Oct 19 '20 at 06:50
  • Hello. I don't know if the approach mentioned is worth adding to your module. It doesn't really work that good if you have multiple threads because the log messages will be unsynced. I tried two approaches to have a better result. 1. Created a custom target that only holds the messages in a data strucutre and then redirect them to the main thread. This is tidious since the custom target isn't visible inside the thread without readding it. The second approach was to use a file that holds the messages, and then load them after the thread is done. An approach for threads is needed though :( – Garbem Oct 19 '20 at 08:23