Access caller variables from threads (PS)

In PowerShell, threads getting executed in separate run spaces. To access variables from the caller scope, you have to use the ‘using’ scope modifier.


function DownloadFiles([string]$WebstoreUrl, [string]$FileList)
{
    Get-Content $FileList | ForEach-Object -Parallel {
        Invoke-WebRequest "$using:WebstoreUrl/$_" -OutFile $_
    } -ThrottleLimit 10
}

For safety reasons, you can’t mutate these variables directly. There is a workaround by assigning it to another variable, but better synchronize the access.

function DownloadFiles([string]$WebstoreUrl, [string]$FileList)
{
    $NoError = $true
    $SyncObject = [System.Object]::new()

    Get-Content $FileList | ForEach-Object -Parallel {
        try {
            Invoke-WebRequest "$using:WebstoreUrl/$_" -OutFile $_
        } catch {
            [System.Threading.Monitor]::Enter($SyncObject)
            try {
                Write-Output "Download error for $using:WebstoreUrl/$_"
                $NoError = $using:NoError
                $NoError = $false
            } finally {
                [System.Threading.Monitor]::Exit($SyncObject)
            }
        }
    } -ThrottleLimit 10

    return $NoError
}