Cómo ejecutar el script de PowerShell simultáneamente en varias computadoras

Cómo ejecutar el script de PowerShell simultáneamente en varias computadoras

Estoy intentando ejecutar el script de PowerShell, que tengo, en varias computadoras simultáneamente. Actualmente estoy usando PowerShell versión 5.

Quiero saber si es posible ejecutarlo sin un proceso en segundo plano para comprobar una mejor comprensión de los registros.

$computers = @("Hostname1", "Hostname2", "Hostname3")
$scriptPath = "C:\Projects\Scripts\Environment\InstallEnvironment.ps1"

$scriptBlock = {
    param (
        [string]$scriptPath
    )
    try {
        # Execute the script
        & $scriptPath
    }
    catch {
        Write-Host "Error occurred on $($env:COMPUTERNAME): $_"
    }
}
foreach ($computer in $computers) {
    Start-Job -ScriptBlock $scriptBlock -ArgumentList $scriptPath -Name $computer
}
while (Get-Job -State Running) {
    Start-Sleep -Milliseconds 100
}
Get-Job | Receive-Job
Get-Job | Remove-Job

Cualquier ayuda es muy apreciada.

Respuesta1

Creo que tienes tres opciones:

  • Continúe con Jobs, pero refactorice un poco su código.
  • Usar ForEach-Object -Parallelen PowerShell 7
  • Tratar de usarFlujos de trabajoen PowerShell 5, que permiten foreach -Parallel ($a in $x) {}cuáles son un tipo diferente de dolor de cabeza

Aquí hay un fragmento de código que se utiliza Invoke-Commandpara crear los trabajos y Wait-Jobesperarlos:

$computers = @("Hostname1", "Hostname2", "Hostname3")
$scriptPath = "C:\Projects\Scripts\Environment\InstallEnvironment.ps1"
$scriptBlock = {
    try {
        & $Using:scriptPath
    }
    catch {
        Write-Host "Error occurred on $($env:COMPUTERNAME): $_"
    }
}
$Jobs = Invoke-Command -ScriptBlock $scriptBlock -ComputerName $computers -AsJob
# Results (Logs) are stored in the $Result variable
$Result = $Jobs | Wait-Job | Receive-Job
$Jobs | Remove-Job

Así es como puedes usar ForEach-Object -Parallel, pero ten cuidado, a veces esto no te permite enviar cosas a la consola como lo harías normalmente y puede causarte otros tipos de dolores de cabeza:

#Requires -Version 7
$computers = @("Hostname1", "Hostname2", "Hostname3")
$scriptPath = "C:\Projects\Scripts\Environment\InstallEnvironment.ps1"
$scriptBlock = {
    try {
        & $Using:scriptPath
    }
    catch {
        Write-Host "Error occurred on $($env:COMPUTERNAME): $_"
    }
}
$computers | ForEach-Object -Parallel {
    Invoke-Command -ScriptBlock $scriptBlock -ComputerName $_
}

Recomiendo absolutamente quedarse con Jobs y obtener sus registros a través deReceive-Job

información relacionada