Private/Collect/Invoke-TcIsolatedCollector.ps1
|
function Invoke-TcIsolatedCollector { <# .SYNOPSIS Runs collectors in a separate process and merges their tables. Returns how many were not collected. .DESCRIPTION PnP.PowerShell and the Graph and Exchange modules cannot share a process: PowerShell stops abruptly. So the PnP collectors of a tenant run together in their own process, and if it stops, only they are missing. The process needs the initial domain, which only Graph can read, so it is found here first. #> [CmdletBinding()] [OutputType([int])] param( [Parameter(Mandatory)][hashtable[]]$Collector, [Parameter(Mandatory)][string]$Role, [int[]]$Rank = @(), [int]$Total = 0, [AllowEmptyString()][string]$Folder = '' ) $output = Join-Path ([System.IO.Path]::GetTempPath()) ('tc-isolated-{0}.json' -f [guid]::NewGuid()) $ids = ($Collector | ForEach-Object { $_['Id'] }) -join ',' $tenant = $script:TcTenants[$Role] if (-not (Get-TcProperty $tenant 'initialDomain')) { try { Connect-TcTenant -Role $Role } catch { Write-TcLog -Message "The initial domain of $Role is unknown: $(Get-TcErrorText $_)" -Level WARN } } $script = Join-Path $PSScriptRoot '..' '..' 'Scripts' 'Invoke-TcIsolatedCollection.ps1' $arguments = @( '-NoProfile', '-File', $script, '-ProjectPath', $script:TcProjectPath, '-Role', $Role, '-CollectorId', $ids, '-Rank', ($Rank -join ','), '-Total', [string]$Total, '-Depth', $script:TcDepth, '-OutFile', $output ) if ($Folder) { $arguments += @('-Folder', $Folder) } if ($script:TcUnattended) { $arguments += '-Unattended' } $initialDomain = Get-TcProperty $tenant 'initialDomain' if ($initialDomain) { $arguments += @('-InitialDomain', $initialDomain) } Write-TcLog -Message "Collectors $ids started in a separate process." $exitCode = Invoke-TcIsolatedProcess -Arguments $arguments if ($exitCode -ne 0) { Write-TcLog -Message "The separate process stopped with code $exitCode." -Level WARN } $result = $null if (Test-Path -LiteralPath $output) { try { $result = Read-TcJsonFile -Path $output } catch { Write-TcLog -Message 'The result of the separate process could not be read.' -Level WARN } Remove-Item -LiteralPath $output -Force -ErrorAction SilentlyContinue } if ($result) { $tables = Get-TcProperty $result 'tables' foreach ($key in @($tables.Keys)) { $rows = [System.Collections.Generic.List[object]]::new() foreach ($row in @($tables[$key])) { $rows.Add($row) } $script:TcCurrentTenant['tables'][$key] = $rows } } $missing = 0 foreach ($item in $Collector) { $line = if ($result) { @(Get-TcProperty $result 'coverage') | Where-Object { (Get-TcProperty $_ 'id') -eq $item['Id'] } | Select-Object -First 1 } if (-not $line) { $line = [ordered]@{ role = $Role tenant = $script:TcCurrentTenant['tenant'] id = $item['Id'] workload = $item['Workload'] title = $item['Title'] service = (Get-TcServiceInfo $item['Service'])['Label'] status = 'Failed' message = "The separate process of this workload stopped before the end (code $exitCode)." remedy = "Run this workload alone: Invoke-TcAssessment -Workload '$($item['Workload'])'. The details are in journal.log." duration = 0 rows = 0 tables = @() } Write-TcStepLine -Status Warning -Text "$($item['Id']): not collected, the separate process stopped (code $exitCode)." } $script:TcCurrentTenant['coverage'].Add($line) if ((Get-TcProperty $line 'status') -notin 'OK', 'Partial') { $missing++ } } $missing } |