You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现PowerShell SSH脚本同时执行ip.txt中所有主机的命令

没问题!要让你的PowerShell脚本同时处理所有IP地址,我们可以利用PowerShell的并行处理能力,下面分两种常用场景给你修改后的脚本:

方法1:PowerShell 7+ 推荐使用 ForEach-Object -Parallel

如果你的环境已经升级到PowerShell 7或更高版本,这种方式最简洁高效,原生支持并行执行:

# 读取IP列表并过滤空行
$Computers = Get-Content -Path .\ip.txt | Where-Object { $_ -match '\S' }

# 提前创建通用凭据,避免重复创建浪费资源
$User = "-"
$Password = "-"
$secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential($User, $secpasswd)
$Command = 'hostname'

# 并行处理每台主机,-ThrottleLimit可以限制同时运行的数量(按需调整)
$Computers | ForEach-Object -Parallel -ThrottleLimit 10 {
    $Computer = $_
    Write-Host "正在处理主机: $Computer"
    
    # 清理当前会话的SSH信任主机列表
    Get-SSHTrustedHost | Remove-SSHTrustedHost
    
    # 建立SSH会话
    $SessionID = New-SSHSession -ComputerName $Computer -Credential $using:Credentials -AcceptKey:$true
    
    # 执行命令并提取输出
    $output = Invoke-SSHCommand -Index $SessionID.SessionId -Command $using:Command | Select-Object -ExpandProperty Output
    
    # 用完会话记得关闭,避免资源泄漏
    Remove-SSHSession -SessionId $SessionID.SessionId
    
    # 返回带主机标识的结果,方便后续写入文件
    [PSCustomObject]@{
        Computer = $Computer
        Output   = $output -join "`n"
    }
} | ForEach-Object {
    # 将结果写入文件,格式可以根据需求调整
    Add-Content -Path result.txt -Value "$($_.Computer):`n$($_.Output)`n------------------------`n"
}

为什么这么改?

  • ForEach-Object -Parallel会自动在后台启动多个并行线程,同时处理不同的IP
  • 用$using:前缀传递外部变量到并行块中,保证每个线程能拿到正确的凭据和命令
  • 增加了会话清理逻辑,避免残留未关闭的SSH连接
  • 结果中绑定了主机IP,方便你在输出文件里区分不同主机的执行结果
方法2:兼容Windows PowerShell 5.1的后台作业方式

如果你的环境还在使用Windows PowerShell 5.1(老系统默认版本),可以用后台作业实现并行:

# 读取IP列表并过滤空行
$Computers = Get-Content -Path .\ip.txt | Where-Object { $_ -match '\S' }

# 提前创建通用凭据
$User = "-"
$Password = "-"
$secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential($User, $secpasswd)
$Command = 'hostname'

# 存储所有后台作业的实例
$jobs = @()

# 为每个IP启动一个后台作业
foreach($Computer in $Computers){
    Write-Host "启动主机 $Computer 的处理作业"
    $job = Start-Job -ScriptBlock {
        param($Computer, $Credentials, $Command)
        
        Write-Host "正在处理主机: $Computer"
        Get-SSHTrustedHost | Remove-SSHTrustedHost
        $SessionID = New-SSHSession -ComputerName $Computer -Credential $Credentials -AcceptKey:$true
        $output = Invoke-SSHCommand -Index $SessionID.SessionId -Command $Command | Select-Object -ExpandProperty Output
        Remove-SSHSession -SessionId $SessionID.SessionId
        
        # 返回带主机标识的结果
        return [PSCustomObject]@{
            Computer = $Computer
            Output   = $output -join "`n"
        }
    } -ArgumentList $Computer, $Credentials, $Command
    
    $jobs += $job
}

# 等待所有后台作业完成
Write-Host "等待所有作业执行完成..."
Wait-Job -Job $jobs | Out-Null

# 收集所有作业结果并写入文件
foreach($job in $jobs){
    $result = Receive-Job -Job $job
    Add-Content -Path result.txt -Value "$($result.Computer):`n$result.Output`n------------------------`n"
    # 清理已完成的作业,释放资源
    Remove-Job -Job $job
}

Write-Host "所有处理完成,结果已写入result.txt"

注意事项

  • 如果目标主机数量较多,建议调整-ThrottleLimit(方法1)或控制同时启动的作业数(方法2),避免本地或目标主机资源过载
  • 确保你已经安装了Posh-SSH模块(没装的话可以用Install-Module Posh-SSH -Scope CurrentUser安装)
  • 两种方式都保留了信任主机清理逻辑,避免SSH连接时的证书验证问题

内容的提问来源于stack exchange,提问作者SySx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 21:07:29