如何将PowerShell作业信息存储到变量中?
Hey there! Let's tackle this PowerShell v2 multithreading optimization for your remote host checks—slow single-threaded processing for 100+ machines is definitely a pain, and using Jobs is the right direction. Here's a refined, efficient approach tailored to v2's capabilities, plus key tips to keep things running smoothly:
Core Optimization: Controlled Concurrent Jobs
PowerShell v2's Start-Job spawns full PowerShell processes (not threads), so spawning 100+ at once will drain system resources and actually slow you down. We'll cap concurrent jobs and manage their lifecycle properly.
Here's the adjusted code structure with your remote check logic integrated:
# 1. Define the script block that runs checks for a single host $checkHostScript = { param($targetHost) $result = [PSCustomObject]@{ Hostname = $targetHost OverallStatus = "Success" CheckDetails = @() } try { # Replace with your actual file/software checks # Example 1: Check if a file exists on the remote host $filePath = "\\$targetHost\c$\Required\Path\File.exe" if (Test-Path $filePath -ErrorAction Stop) { $result.CheckDetails += "✅ Target file found at $filePath" } else { $result.CheckDetails += "❌ Target file missing from $filePath" $result.OverallStatus = "Warning" } # Example 2: Check for specific software via WMI $software = Get-WmiObject -ComputerName $targetHost ` -Class Win32_Product ` -Filter "Name='YourCriticalSoftware'" ` -ErrorAction Stop if ($software) { $result.CheckDetails += "✅ Software installed (Version: $($software.Version))" } else { $result.CheckDetails += "❌ Required software not installed" $result.OverallStatus = "Warning" } } catch { $result.OverallStatus = "Failed" $result.CheckDetails += "⚠️ Error accessing host: $($_.Exception.Message)" } return $result } # 2. Configure your host list and job limits $hostList = Get-Content "C:\Path\To\Your\Hosts.txt" # Replace with your host source $maxConcurrentJobs = 12 # Adjust based on your system's CPU/RAM (10-20 is safe for most) $activeJobs = @() # 3. Launch jobs with concurrency control foreach ($host in $hostList) { # Wait until we have room for a new job while ($activeJobs.Count -ge $maxConcurrentJobs) { $completedJobs = $activeJobs | Wait-Job -Any $activeJobs = $activeJobs | Where-Object { $_.Id -notin $completedJobs.Id } } # Start a new job for the current host $newJob = Start-Job -ScriptBlock $checkHostScript -ArgumentList $host $activeJobs += $newJob Write-Host "Started check for $host (Job ID: $($newJob.Id))" } # 4. Wait for all remaining jobs to finish and collect results Wait-Job $activeJobs | Out-Null $allResults = @() foreach ($job in $activeJobs + Get-Job) { $jobResult = Receive-Job $job $allResults += $jobResult Remove-Job $job # Clean up completed jobs to avoid leftover processes } # 5. Format results and send email $emailBody = @" Remote Host Compliance Report ============================= $(foreach ($result in $allResults) { "`n### Host: $($result.Hostname)`nStatus: $($result.OverallStatus)`nDetails:`n- $($result.CheckDetails -join "`n- ")" }) "@ # Replace with your email server details Send-MailMessage -From "admin@yourdomain.com" ` -To "team@yourdomain.com" ` -Subject "Remote Host Check Results $(Get-Date -Format 'yyyy-MM-dd')" ` -Body $emailBody ` -SmtpServer "smtp.yourdomain.com"
Key Tips for PowerShell v2
- Cap concurrent jobs: As mentioned, v2 jobs are heavyweight processes—too many will cripple performance. Start with 10-15 and adjust based on your server's load.
- Robust error handling: The
try/catchblock ensures you capture issues like unreachable hosts or permission errors instead of letting jobs hang silently. - Clean up jobs: Always use
Remove-Jobafter collecting results to avoid orphaned PowerShell processes cluttering your system. - Keep the job script lean: Avoid loading unnecessary modules or running redundant commands inside the script block—each job runs in its own process, so bloat adds up fast.
内容的提问来源于stack exchange,提问作者user9362046
相关产品推荐
相关产品推荐

