第8天课后作业
习题1:使用后台作业并行检测多个主机连通性
习题1参考答案:Start-Job 并行 Ping 检测
$hosts = 'google.com', 'github.com', 'baidu.com', 'nonexistent.fake'
# 启动作业
$jobs = foreach ($h in $hosts) {
Start-Job -ScriptBlock {
param($hostName)
$result = Test-Connection $hostName -Count 1 -Quiet -ErrorAction SilentlyContinue
[PSCustomObject]@{
Host = $hostName
Online = $result
Status = if ($result) { "Online" } else { "Offline" }
}
} -ArgumentList $h
}
# 等待所有作业完成
$jobs | Wait-Job | Out-Null
# 收集结果
$results = $jobs | Receive-Job
# 清理作业
$jobs | Remove-Job
# 输出表格
$results | Format-Table -AutoSize
🔍 解析要点:
-ArgumentList:向 ScriptBlock 传递外部变量(避免作用域问题)Test-Connection -Quiet:返回布尔值,适合自动化判断Wait-Job:阻塞直到所有作业完成Receive-Job:提取作业输出(必须在Remove-Job前调用)
⚠️ 缺点:
Start-Job启动慢(每个 Job 开新进程),仅适合少量任务。
✅ 习题2答案:注册计划任务(ScheduledJob)
参考答案
# 创建日志目录
$null = New-Item -Path "C:\logs" -ItemType Directory -Force
# 定义脚本块
$scriptBlock = {
$freeGB = [math]::Round((Get-Volume -DriveLetter C).SizeRemaining / 1GB, 2)
$logEntry = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), C盘剩余: ${freeGB} GB"
Add-Content -Path "C:\logs\disk_usage.log" -Value $logEntry
}
# 注册计划任务(每天凌晨2点)
$trigger = New-JobTrigger -Daily -At "2:00AM"
$options = New-ScheduledJobOption -RunElevated -WakeToRun
Register-ScheduledJob -Name "DailyDiskReport" `
-ScriptBlock $scriptBlock `
-Trigger $trigger `
-ScheduledJobOption $options
# 验证注册
Get-ScheduledJob -Name "DailyDiskReport"
🔍 解析要点:
Register-ScheduledJob:创建的是 PowerShell 作业,不是传统 Windows 任务(但底层由 Task Scheduler 托管)-RunElevated:以管理员权限运行(访问 C 盘可能需要)- 日志路径:确保目录存在,否则任务静默失败
- 查看历史:
Get-Job -Name "DailyDiskReport"可查执行记录
💡 查看任务位置:
任务计划程序库 → Microsoft → Windows → PowerShell → ScheduledJobs
✅ 习题3参考答案:Runspace 池并发请求(高性能)
# 安装 ThreadJob 模块(如未安装)
# Install-Module ThreadJob -Scope CurrentUser -Force
# 生成50个URL(混合200/404/example)
$urls = @()
for ($i = 0; $i -lt 50; $i++) {
switch ($i % 3) {
0 { $urls += "https://httpbin.org/status/200" }
1 { $urls += "https://httpbin.org/status/404" }
2 { $urls += "https://example.com" }
}
}
# 创建 Runspace 池(最大10线程)
$sessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
$runspacePool = [runspacefactory]::CreateRunspacePool(1, 10, $sessionState, $Host)
$runspacePool.Open()
$jobs = @()
$handles = for ($i = 0; $i -lt $urls.Count; $i++) {
$url = $urls[$i]
$ps = [powershell]::Create()
$ps.RunspacePool = $runspacePool
[void]$ps.AddScript({
param($targetUrl)
$sw = [System.Diagnostics.Stopwatch]::StartNew()
try {
$response = Invoke-WebRequest -Uri $targetUrl -UseBasicParsing -TimeoutSec 10
$statusCode = $response.StatusCode
} catch {
$statusCode = $_.Exception.Response?.StatusCode?.value__ -as [int] -or 0
}
$sw.Stop()
[PSCustomObject]@{
URL = $targetUrl
Status = $statusCode
Duration = $sw.ElapsedMilliseconds
}
}).AddArgument($url)
$jobs += [PSCustomObject]@{ PowerShell = $ps; Handle = $ps.BeginInvoke() }
$ps
}
# 等待所有完成
while ($jobs.Handle.IsCompleted -contains $false) {
Start-Sleep -Milliseconds 100
}
# 收集结果
$results = $jobs | ForEach-Object {
$_.PowerShell.EndInvoke($_.Handle)
$_.PowerShell.Dispose()
}
# 关闭池
$runspacePool.Close()
$runspacePool.Dispose()
# 输出前10条(避免刷屏)
$results | Select-Object -First 10 | Format-Table -AutoSize
Write-Host "共处理 $($results.Count) 个请求。" -ForegroundColor Green
🔍 解析要点:
- Runspace 池 vs Job:
Start-Job:每个任务开新powershell.exe进程(内存高、启动慢)- Runspace 池:复用 .NET 线程,内存低、速度快(适合 >50 任务)
- 错误处理:捕获
Invoke-WebRequest异常,提取 HTTP 状态码(即使 404 也是有效响应) - 性能监控:用
Stopwatch精确计时 - 资源清理:必须调用
.Dispose()防止内存泄漏
1225

被折叠的 条评论
为什么被折叠?



