none
Многопоточный скрипт powershell RRS feed

  • Вопрос

  • Кто-нибудь пользовался? я много раз ловил себя на мысли, вот было бы хорошо запустить некий скрипт в параллельную работу, но всегда ограничивался запуском нескольких окошек 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@E:\@E:\share
    server5@domain1@E:\@E:\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, но у меня пока мозгов не хватает, помогите пож, мб есть у кого рабочий пример

    20 ноября 2019 г. 14:09

Ответы

Все ответы

  • Добрый день,

     Посмотрите по ссылке, есть примеры

    https://stackoverflow.com/questions/4016451/can-powershell-run-commands-in-parallel

    • Помечено в качестве ответа Lostmy 21 ноября 2019 г. 6:39
    20 ноября 2019 г. 14:19
  • т.е.
    workflow work {
      foreach -parallel ($i in 1..3) { 
        sleep 5 
        "$i done" 
      }
    }
    
    work
    это ответ на мой вопрос?
    • Изменено Lostmy 20 ноября 2019 г. 14:32
    20 ноября 2019 г. 14:31
  • 1 создавать строку только ради того чтобы ее потом разбить это сильно

    $ShareObjList = @("server1@domain1@E:\@E:\share",
    "server2@domain2@E:\@E:\share",
    "server3@domain2@E:\@E:\blabla",
    "server4@domain1@E:\@E:\share",
    "server5@domain1@E:\@E:\soft")
    2 следующий суровый момент в том чтобы использовать строки вместо обьектов в обьектно ориентированном языке
        $ShareObj = $ShareObj -split "@" | % {$_.trim()}
        $Share = $null
        $Share = ("\\"+$($ShareObj[0])+"\"+$($ShareObj[3])).replace("$($ShareObj[2])","")
    На ненужных операциях обьединения и разделения строк вы теряете время. И если при выполнении скрипта на 2 параметра это будет незаметро то при тысячах операший будете ждать по пол дня

    3 переназначение переменных по сотню раз еще и с IFaми так же имеет огромное влияние на производительность. Вы наперед можете отсортировать инпуты и усстановить необходимые $cred"ы

        if ($ShareObj[1] -eq "domain2"){$Cred = $adm2}
        else {$Cred = $adm1}

    4 расспараллелить создание удаление PSDrive можно, только вам стоит решить логическую задачу с тем что этот Drive не может иметь одно название - пока в одном параллельном таске драйв будет создаваться в другом будет удаляться...

    Как итог, я бы рекоммендовал переписать скрипт на использование Invoke-Command вместо мапинга диска, избавиться от Foreach в тех местах где он не нужен, избавиться от странной практики с парсингом строк и все полетит без паралельного выполнения
    А если этого окажется не достаточно то существуют аж 3 варианта Job (help new-job -full), Workflow (help about_workflows full), скрипт invoke-parrallel из галлерей


    The opinion expressed by me is not an official position of Microsoft

    20 ноября 2019 г. 14:43
    Модератор
  • т.е.
    workflow work {
      foreach -parallel ($i in 1..3) { 
        sleep 5 
        "$i done" 
      }
    }
    
    work
    это ответ на мой вопрос?
    это один из возможных вариантов, но из коробки не взлетит (выше писал почему)

    The opinion expressed by me is not an official position of Microsoft

    20 ноября 2019 г. 15:04
    Модератор
  • 4 расспараллелить создание удаление PSDrive можно, только вам стоит решить логическую задачу с тем что этот Drive не может иметь одно название - пока в одном параллельном таске драйв будет создаваться в другом будет удаляться...


    за это спасибо
    21 ноября 2019 г. 6:40
  • Workflow это deprecated фича. Её удалили из PowerShell Core. Зато в последнем PowerShell Core 7.0 Preview6 вы найдете ForEach-Object -Parallel . Ссылка на описание есть у меня в блоге https://isazonov.wordpress.com/2019/09/20/powershell-7-0-preview4/

    Сазонов Илья

    https://isazonov.wordpress.com/

    22 ноября 2019 г. 11:14
    Модератор