Автор Тема: Многопоточный скрипт powershell  (Прочитано 1350 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн LostMy

  • Начинающий
  • *
  • Сообщений: 22
  • Рейтинг: 1
  • Пол: Мужской
    • Просмотр профиля
  • Откуда: Msk
Многопоточный скрипт powershell
« : 20 Ноября 2019, 17:05:15 »
Кто-нибудь пользовался? я много раз ловил себя на мысли, вот было бы хорошо запустить некий скрипт в параллельную работу, но всегда ограничивался запуском нескольких окошек powershell, сейчас увы так поступить не получается, т.к. 100 окошек запускать лень, прошу помощи

есть скрипт:
cls
$error.Clear()

$adm1 = Get-Credential "domain1\user1"
$adm2 = Get-Credential "domain2\user2"

$ShareObjList = "server1@domain1@E:\@E:\share
server2@domain2@E:\@E:\share
server3@domain2@E:\@E:\blabla
server4@domain1@D:\@D:\share
server5@domain1@G:\@G:\soft" -split "\n" | % {$_.trim()} | ? {$_}

foreach ($ShareObj in $ShareObjList){
    $ShareObj = $ShareObj -split "@" | % {$_.trim()}
    $Share = $null
    $Share = ("\\"+$($ShareObj[0])+"\"+$($ShareObj[3])).replace("$($ShareObj[2])","")
    $Cred = $null
    if ($ShareObj[1] -eq "domain2"){$Cred = $adm2}
    else {$Cred = $adm1}
    if ((Get-PSDrive "SH" -ErrorAction SilentlyContinue) -ne $null){Remove-PSDrive "SH" -Force -Verbose}
    New-PSDrive -Name "SH" -PSProvider FileSystem -Root $Share -Credential $Cred
    $result = $null
    $result = @()
    $result += Get-ChildItem "SH:\" -Recurse -Force | ? {$_.PSIsContainer -eq $true} | ? {(get-acl $_.fullname -Audit).AreAuditRulesProtected -eq $true} | % {$_.fullname}
    $error | Select TargetObject,Exception | Export-Csv $("D:\Аудит\Error_" + $($Share.Replace("\\","")).replace("\","_") + ".txt") -NoTypeInformation -Encoding Default
    $result | Out-File $("D:\Аудит\Audit_" + $($Share.Replace("\\","")).replace("\","_") + ".txt") -Encoding utf8
}

есть примеры с workflow, но у меня пока мозгов не хватает, помогите пож, мб есть у кого рабочий пример


Updated: 20 November 2019, 17:36:42

Симптоматично выглядит пример:

workflow work {
  foreach -parallel ($i in 1..3) {
    sleep 5
    "$i done"
  }
}

work

но возникает вопрос, есть ли какие-то ограничения?
как себя будут чувствовать переменные $result и $error?
« Последнее редактирование: 20 Ноября 2019, 17:36:42 от LostMy »

Оффлайн LostMy

  • Начинающий
  • *
  • Сообщений: 22
  • Рейтинг: 1
  • Пол: Мужской
    • Просмотр профиля
  • Откуда: Msk
Многопоточный скрипт powershell
« Ответ #1 : 25 Ноября 2019, 15:34:22 »
cls
$error.Clear()
Get-PSDrive | Remove-PSDrive
 
$Adm1 = Get-Credential "domain1\user1"
$Adm2 = Get-Credential "domain2\user2"
 
$ShareStringList = "server-05@domain2@E:\@E:\DiskO
server-05@domain2@E:\@E:\Shares
server-05@domain2@G:\@G:\share
server-06@domain2@E:\@E:\share2
server-06@domain2@E:\@E:\share1
server-06@domain2@E:\@E:\share
server1@domain2@E:\@E:\share
server2@domain1@E:\@E:\share
server3@domain1@E:\@E:\Share
server4@domain1@D:\@D:\Share
server5@domain1@E:\@E:\share
server6@domain1@E:\@E:\soft
server7@domain1@E:\@E:\Share
server8@domain1@E:\@E:\share
server8@domain1@G:\@G:\soft
server8@domain1@G:\@G:\doc
server9@domain1@F:\@F:\share" -split "\n" | % {$_.trim()} | ? {$_}
$ShareObjectList = @()
 
$LogPath = "D:\Аудит ACL"
if ((Test-Path $LogPath) -eq $false){
    New-Item -Path $LogPath -ItemType directory
}
#Наркомания
[int]$counter = "0"
$ABC = "H:
I:
J:
K:
L:
M:
N:
O:
P:
Q:
R:
S:
T:
U:
V:
W:
Y:
Z:"-split "\n" | % {$_.trim()} | ? {$_}
if ($ShareStringList.count -gt $abc.count){
    Write-Host "Список шар равен $($ShareStringList.count) он больше списка доступных букв $($abc.count), конец работы скрипта"
    exit
}
 
 
 
foreach ($ShareString in $ShareStringList){
    $ShareObjectList += New-Object psobject -Property @{
        ServerName = $ShareString.Split("@")[0]
        ServerDomain = $ShareString.Split("@")[1]
        ShareRoot = ("\\"+$($ShareString.Split("@")[0])+"\"+$($ShareString.Split("@")[3])).replace("$($ShareString.Split("@")[2])","")
        ShareName = ($($ShareString.Split("@")[0])+"_"+$($ShareString.Split("@")[3])).replace("$($ShareString.Split("@")[2])","")
        ShareLetter = $abc[$counter]
        LogPath = $($logpath+("\"+$($ShareString.Split("@")[0])+"_"+$($ShareString.Split("@")[3])+".txt").replace("$($ShareString.Split("@")[2])",""))
    }
    $counter = $counter + 1
}
 
foreach ($ShareObject in $ShareObjectList){
    Get-PSDrive  -PSProvider FileSystem | ? {$_.Root -like "$($ShareObject.ShareRoot)"} | Remove-PSDrive -ErrorAction SilentlyContinue -Force -Verbose
    if ($ShareObject.ServerDomain -eq "domain2"){New-PSDrive -Name $ShareObject.sharename -PSProvider FileSystem -Root $ShareObject.shareroot -Credential $Adm1}
    else {New-PSDrive -Name $($ShareObject.sharename) -PSProvider FileSystem -Root $($ShareObject.shareroot) -Scope global -Credential $Adm2}
    New-SmbMapping -localpath $ShareObject.ShareLetter -RemotePath $($ShareObject.ShareRoot)
}
 
workflow ScanShare {
param(
    [Parameter (Mandatory = $true)]
    [object[]]$ShareList
)
    foreach -parallel ($ShareObject in $ShareList){
        "$($ShareObject.ShareName) start job in $(Get-Date -Format hh:mm-dd.MM.yy)" | Out-File $ShareObject.LogPath -Encoding utf8 -Append
        "$($ShareObject.ShareName) start job in $(Get-Date -Format hh:mm-dd.MM.yy)"
        Get-ChildItem $ShareObject.ShareLetter -Recurse -Force  | ? {$_.PSIsContainer -eq $true} | ? {$(Get-Acl $_.fullname -Audit).AreAuditRulesProtected -eq $true} | % {$_.fullname} | Out-File $ShareObject.LogPath -Encoding utf8 -Append
        "$($ShareObject.ShareName) end job in $(Get-Date -Format hh:mm-dd.MM.yy)" | Out-File $ShareObject.LogPath -Encoding utf8 -Append
        "$($ShareObject.ShareName) end job in $(Get-Date -Format hh:mm-dd.MM.yy)"
    }
   
}
 
ScanShare -ShareList $ShareObjectList

Пока сделал так, умнее не придумал. каспер дает нагрузку по сети, ОЗУ уже 10гиг скушало. Есть у кого варианты по лучше?