1 Star 0 Fork 54

Yuna/kasini3000

forked from chuanjiao10/kasini3000 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
krun-mt.ps1 14.14 KB
一键复制 编辑 原始数据 按行查看 历史
#建议保存编码为:bom头 + utf8
<#
win,linux通用。轻量,简易的多线程并发。
必须使用powershell7,最好用7.4+
超过1小时,一定要手动启动新的pwsh进程。
本脚本无法实现超时,和失败任务重试。所以必须手动fork新进程。
不支持nodelist分组,不支持nodelist分os,
linux被控机必须安装powershell。
不写sqlite数据库。
用法:
所有node:
c:\ProgramData\kasini3000\krun-mt.ps1 -ps1脚本文件路径 'a:\xx\yy.ps1' -allparameter 'a','b' -被控机ip列表文件路径 'd:\xxx\nodelista.csv'
c:\ProgramData\kasini3000\krun-mt.ps1 {$args[0] + $args[1] } -allparameter 'a','b' -被控机ip列表文件路径 'd:\xxx\nodelista.csv'
单台node,则先设定:
$global:_krun_mt_one_node_ip = '1.2.3.4'
返回值(单台或所有node):
$global:_krun_mt_out
#>
param
(
[parameter(Position = 0)][Alias("scriptblock")][scriptblock]$powershell代码块 = { },
[Alias("allparameter")]$全部传入参数,
[Alias('ps1_path')][String]$ps1脚本文件路径,
[ValidateNotNullOrEmpty()]
[Alias("node_list_file_path_csv")][String]$被控机ip列表文件路径,
[ValidateSet("none","onscreen","writelog","onscreen_and_writelog",'屏显','写日志','屏显和写日志')]
[Alias('choose_output')][String]$输出方式 = '屏显和写日志',
[Alias("check_return_from_node_erery_n_second")][byte]$输出间隔秒 = 5,
[Alias("max_thread")][byte]$最大同时运行任务数 = 99,
[Alias("copy_nodescript_folder_to_node")][bool]$复制主控机node_script目录到被控机 = $false
)
& "${PSScriptRoot}/get_Language.ps1"
# 本脚本无法实现超时,和失败任务重试。所以必须手动fork新进程。
if ( ${global:_krun_krun_mt超时} )
{
if ( (${global:_krun_krun_mt超时} -lt (Get-Date)) -or ((Get-Job).count -gt 100) )
{
if ($env:LANG -eq 'zh_CN.UTF-8')
{
Write-Error '错误:必须手动启动新的 pwsh 进程,再运行本脚本 ...'
}
else
{
Write-Error '错误:You must manually start a new pwsh process before running this script ...'
}
}
}
else
{
${global:_krun_krun_mt超时} = (Get-Date).AddHours(1)
}
if ($PSVersionTable.psversion.major -lt 7) #win
{
if ($env:LANG -eq 'zh_CN.UTF-8')
{
Write-Error '错误:需要powershell v7! 最好是 v7.4+'
}
else
{
Write-Error 'error:need powershell v7! best v7.4+'
}
exit 1
}
if ($env:LANG -eq 'zh_CN.UTF-8')
{
$msg = @'
* 重量级后台多线程任务,建议使用k-commit-rs.ps1
* 而本脚本致力于轻量级。并发多线程,任务总数建议不超过200个。进程不超过1小时。不具备自动轮换进程功能。
* 脚本或代码块中的write-error命令,不支持前台显示。
* 本脚本不会保存结果到数据库。
* 任务默认超时=1小时。
* 任务通过多线程运行。可以通过write-host,write-warning,前台显示结果。
* 默认同时运行任务数=99。被控机列表中的被控机可以超过此数,超过的任务会排队等待。
'@
}
else
{
$msg = @'
* Heavyweight backend multithreaded tasks, it is recommended to use k-commit-rs.ps1
* This script is dedicated to lightweight.
Concurrent multithreading, it is recommended that the total number of tasks should not exceed 200.
The process should not exceed 1 hour.
Does not have automatic rotation process function.
* The write-error command in the script or code block does not support front-end display.
* This script will not save the results to the database.
* Task default timeout = 1 hour.
* Tasks run through multiple threads. results can be displayed on the front desk through write-host, write-warning.
* The default number of running thread = 99. The number of node in nodelist can exceed this number,
the exceeding tasks will be queued for waiting.
'@
}
Write-Warning $msg
if ( ($IsWindows -eq $True) -or ($PSVersionTable.psversion.major -lt 6) ) #win
{
& 'c:\ProgramData\kasini3000\0k_source.ps1'
}
if ($IsLinux -eq $True)
{
& '/etc/kasini3000/0k_source.ps1'
}
if ( ($null -eq $被控机ip列表文件路径) -or ($被控机ip列表文件路径 -eq '') )
{
}
else
{
if (Test-Path -LiteralPath $被控机ip列表文件路径)
{
$global:被控机列表文件 = $被控机ip列表文件路径
}
}
Write-Warning ('信息:当前被控机列表文件是:{0}' -f $global:被控机列表文件)
& 'zd只读nodelist文件.ps1'
if ($global:_krun_mt_one_node_ip)
{
$global:所有被控机 = $global:所有被控机 | Where-Object { $_.ip -eq $global:_krun_mt_one_node_ip }
}
$win = 'win7','win8','win10','win11','win2008r2','win2012r2','win2016','win2019','win2022'
$linux = & "${PSScriptRoot}/linux_distribution_str.ps1"
$all = $win + $linux
Write-Warning ('信息:{0}开始在被控机上提交任务' -f $(Get-Date -Format 'HH:mm:ss'))
foreach ($private:当前被控机 in $global:所有被控机)
{
if ($private:当前被控机.被控机os类型 -notin $all)
{
& 'sx1刷新单个被控机对象的_os类型属性.ps1' -被控机ip地址 $private:当前被控机.ip
}
Write-Verbose $private:当前被控机.被控机os类型
if ($private:当前被控机.被控机os类型 -notin $all)
{
Write-Error ("错误:当前被控机【{0}】,【端口不通】或【账户密码不对】。任务无法运行。" -f $private:当前被控机.ip)
#《卡死你3000》之表情包斗图乐
if ( ($IsWindows -eq $True) -or ($PSVersionTable.psversion.major -lt 6) ) #win
{
$private:pname = (Get-Process -Id $pid).Parent.ProcessName
$private:ppname = (Get-Process -Id $pid).Parent.Parent.ProcessName
if ( ($private:pname -eq 'WindowsTerminal') -or ($private:ppname -eq 'WindowsTerminal') )
{
& "${global:kasini3000目录}\admin_gui\pic\bc随机报错背景图片.ps1"
}
}
continue
}
if ( ($IsWindows -eq $True) -or ($PSVersionTable.psversion.major -lt 6) ) #win
{
if ( $private:当前被控机.被控机os类型 -in $win)
{
if ( $private:当前被控机.端口 -eq '')
{
$private:cmd1 = { & 'run_win2win5985_pwd.ps1' -目的ip地址 $args[0] -powershell代码块 $args[1] -ps1脚本文件名 $args[2] -传入参数 $args[3] -复制主控机node_script目录到被控机 $args[4] }
$private:当前线程 = Start-ThreadJob -ThrottleLimit $最大同时运行任务数 -ScriptBlock $private:cmd1 -ArgumentList $private:当前被控机.ip,$powershell代码块,$ps1脚本文件路径,$全部传入参数,$复制主控机node_script目录到被控机
Add-Member -InputObject $private:当前被控机 -MemberType NoteProperty -Name '线程id' -Value $private:当前线程.id -Force
}
else
{
$private:cmd1 = { & 'run_win2win5985_pwd.ps1' -目的ip地址 $args[0] -powershell代码块 $args[1] -ps1脚本文件名 $args[2] -传入参数 $args[3] -复制主控机node_script目录到被控机 $args[4] -端口 $args[5] }
$private:当前线程 = Start-ThreadJob -ThrottleLimit $最大同时运行任务数 -ScriptBlock $private:cmd1 -ArgumentList $private:当前被控机.ip,$powershell代码块,$ps1脚本文件路径,$全部传入参数,$复制主控机node_script目录到被控机,$private:当前被控机.端口
Add-Member -InputObject $private:当前被控机 -MemberType NoteProperty -Name '线程id' -Value $private:当前线程.id -Force
}
}
if ( $private:当前被控机.被控机os类型 -in $linux)
{
if ( $private:当前被控机.端口 -eq '')
{
$private:cmd1 = { & 'run_win2linux_key_pwd.ps1' -目的ip地址 $args[0] -powershell代码块 $args[1] -ps1脚本文件名 $args[2] -传入参数 $args[3] -复制主控机node_script目录到被控机 $args[4] }
$private:当前线程 = Start-ThreadJob -ThrottleLimit $最大同时运行任务数 -ScriptBlock $private:cmd1 -ArgumentList $private:当前被控机.ip,$powershell代码块,$ps1脚本文件路径,$全部传入参数,$复制主控机node_script目录到被控机
Add-Member -InputObject $private:当前被控机 -MemberType NoteProperty -Name '线程id' -Value $private:当前线程.id -Force
}
else
{
$private:cmd1 = { & 'run_win2linux_key_pwd.ps1' -目的ip地址 $args[0] -powershell代码块 $args[1] -ps1脚本文件名 $args[2] -传入参数 $args[3] -复制主控机node_script目录到被控机 $args[4] -端口 $args[5] }
$private:当前线程 = Start-ThreadJob -ThrottleLimit $最大同时运行任务数 -ScriptBlock $private:cmd1 -ArgumentList $private:当前被控机.ip,$powershell代码块,$ps1脚本文件路径,$全部传入参数,$复制主控机node_script目录到被控机,$private:当前被控机.端口
Add-Member -InputObject $private:当前被控机 -MemberType NoteProperty -Name '线程id' -Value $private:当前线程.id -Force
}
}
}
if ($IsLinux -eq $True)
{
if ( $private:当前被控机.被控机os类型 -in $win)
{
Write-Error "收费功能。欢迎给官方群反馈,QQ群号=700816263"
exit 3
}
if ( $private:当前被控机.被控机os类型 -in $linux)
{
if ( $private:当前被控机.端口 -eq '')
{
$private:cmd1 = { & 'run_linux2linux_key_pwd.ps1' -目的ip地址 $args[0] -powershell代码块 $args[1] -ps1脚本文件名 $args[2] -传入参数 $args[3] -复制主控机node_script目录到被控机 $args[4] }
$private:当前线程 = Start-ThreadJob -ThrottleLimit $最大同时运行任务数 -ScriptBlock $private:cmd1 -ArgumentList $private:当前被控机.ip,$powershell代码块,$ps1脚本文件路径,$全部传入参数,$复制主控机node_script目录到被控机
Add-Member -InputObject $private:当前被控机 -MemberType NoteProperty -Name '线程id' -Value $private:当前线程.id -Force
}
else
{
$private:cmd1 = { & 'run_linux2linux_key_pwd.ps1' -目的ip地址 $args[0] -powershell代码块 $args[1] -ps1脚本文件名 $args[2] -传入参数 $args[3] -复制主控机node_script目录到被控机 $args[4] -端口 $args[5] }
$private:当前线程 = Start-ThreadJob -ThrottleLimit $最大同时运行任务数 -ScriptBlock $private:cmd1 -ArgumentList $private:当前被控机.ip,$powershell代码块,$ps1脚本文件路径,$全部传入参数,$复制主控机node_script目录到被控机,$private:当前被控机.端口
Add-Member -InputObject $private:当前被控机 -MemberType NoteProperty -Name '线程id' -Value $private:当前线程.id -Force
}
}
}
}
Write-Warning ('信息:{0}结束在被控机上提交任务' -f $(Get-Date -Format 'HH:mm:ss'))
#-----------------------------------------------------------------------------------
if ($env:LANG -eq 'zh_CN.UTF-8')
{
$msg = @'
输出方式: {0}
'@ -f $输出方式
}
else
{
$msg = @'
output type: {0}
'@ -f $输出方式
}
Write-Warning $msg
$script:日志路径 = '{0}/{1}.csv' -f ${global:kasini3000_data_path},$(Get-Date -Format 'yyyy_MM_dd_HH_mm_ss')
if ($env:LANG -eq 'zh_CN.UTF-8')
{
$msg = @'
日志路径: {0}
'@ -f $script:日志路径
}
else
{
$msg = @'
log path: {0}
'@ -f $script:日志路径
}
Write-Warning $msg
$输出结束时间 = (Get-Date).AddMinutes(1)
$private:已经输出 = @()
$private:log输出 = @()
if ($输出方式 -eq 'none')
{
}
else
{
Write-Warning ('信息:{0}开始输出' -f $(Get-Date -Format 'HH:mm:ss'))
if ( ($null -eq $global:_krun_mt_out) -or ($global:_krun_mt_out -eq '') )
{
}
else
{
$global:_krun_mt_out_old = $global:_krun_mt_out
}
$global:_krun_mt_out = @()
do
{
foreach ($private:当前被控机 in $global:所有被控机)
{
if ( ($null -eq $private:当前被控机.线程id) -or ($private:当前被控机.线程id -eq '') )
{
continue
}
if ( $private:当前被控机.线程id -in $private:已经输出)
{
continue
}
if ( (Get-Job $private:当前被控机.线程id).State -eq 'Completed')
{
$private:已经输出 += $private:当前被控机.线程id
[string]$private:t2 = Receive-Job -Id $private:当前被控机.线程id
}
else
{
Write-Host '.' -ForegroundColor Yellow -NoNewline
continue
}
if ($输出方式 -eq '屏显和写日志')
{
$private:temp997 = [PSCustomObject]@{
ip = $private:当前被控机.ip
被控机名 = $private:当前被控机.被控机显示名
被控机os = $private:当前被控机.被控机os类型
输出 = $private:t2
}
$private:log输出 += $private:temp997
Write-Host "`nip:" -ForegroundColor Cyan -NoNewline
Write-Host $private:当前被控机.ip -ForegroundColor Yellow -NoNewline
Write-Host " 被控机名:" -ForegroundColor Cyan -NoNewline
Write-Host $private:当前被控机.被控机显示名 -ForegroundColor Yellow -NoNewline
Write-Host " 被控机os:" -ForegroundColor Cyan -NoNewline
Write-Host $private:当前被控机.被控机os类型 -ForegroundColor Yellow
Write-Host $private:t2
}
elseif ($输出方式 -eq '屏显')
{
Write-Host "`nip:" -ForegroundColor Cyan -NoNewline
Write-Host $private:当前被控机.ip -ForegroundColor Yellow -NoNewline
Write-Host " 被控机名:" -ForegroundColor Cyan -NoNewline
Write-Host $private:当前被控机.被控机显示名 -ForegroundColor Yellow -NoNewline
Write-Host " 被控机os:" -ForegroundColor Cyan -NoNewline
Write-Host $private:当前被控机.被控机os类型 -ForegroundColor Yellow
Write-Host $private:t2
}
elseif ($输出方式 -eq '写日志')
{
$private:temp997 = [PSCustomObject]@{
ip = $private:当前被控机.ip
被控机名 = $private:当前被控机.被控机显示名
被控机os = $private:当前被控机.被控机os类型
输出 = $private:t2
}
$private:log输出 += $private:temp997
}
else
{
Write-Error '错误:krun-mt.ps1 10001'
klog -被写入的log内容 '错误:krun-mt.ps1 10001'
}
Remove-Job $private:当前被控机.线程id -Force
$global:_krun_mt_out += $private:temp997
}
if ((Get-Job).count -le 0)
{
break
}
Start-Sleep -Seconds $输出间隔秒
}
while ((Get-Date) -lt $输出结束时间)
$private:log输出 | Export-Csv -LiteralPath $script:日志路径 -Encoding UTF8bom -NoTypeInformation
Write-Warning ('信息:{0}结束输出' -f $(Get-Date -Format 'HH:mm:ss'))
}
if ( ($null -eq $global:_krun_mt_one_node_ip) -or ($global:_krun_mt_one_node_ip -eq '') )
{
}
else
{
$global:_krun_mt_one_node_ip = $null
$global:所有被控机 = $null
$global:zd只读nodelist文件 = $false
$global:kasini3000_config = $false
$global:0k_source = $false
}
exit 0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
PowerShell
1
https://gitee.com/YunaCode/kasini3000.git
git@gitee.com:YunaCode/kasini3000.git
YunaCode
kasini3000
kasini3000
master

搜索帮助