0

I have a Jenkins job which calls upon a PowerShell script with some parameters. The parameters are always start/stop and then a number of selenium test machines to power on/off. Examples:

powershell.exe -File gridControl.ps1 start grid1 grid2 grid3
powershell.exe -File gridControl.ps1 stop grid4 grid6 grid7

The script was working fine recently until we got asked to add a timeout to it as sometimes a part of it was hanging. The problem is that to add the timeout, we encapsulated the whole thing in a function so that we could run it as a job and time it.

This means that we needed to also parse the arguments into the function. I did so following Powershell pass variable to start-job

My problem is that my first variable gets lost. Here's the code (which doesn't include the actual machine starting/stopping. It's just connecting to the VCS and trying printing out my args):

Write-Host " gridControl - Started"
$timeoutSeconds = 60
$code =  
{
    param($args)
    $vcenter = "vc-3dc-v01.redacted.local"
    $delaysec = 120
    $toolsdelayCheck = 30
    $looprepeats = 10
    $toolsrunningDelay = 60
    $emailTo = @('redacted@zetta.bg', 'redacted@finanalytica.com')

    Write-Host " Connecting to VCenter..."

    Add-PSSnapin VMware.VimAutomation.Core -WarningAction SilentlyContinue | Out-Null
    Connect-VIServer -Server $vcenter -WarningAction SilentlyContinue -Verbose

    if(!$?){
        Write-Host "Could not connect to VCenter"
    }
    else{
        Write-Host "Successfully connected to vCenter"
    }

    Write-Host $args[0]
    Write-Host $args[1] $args[2] $args[3]

    Write-Host " gridControl - Ready to finish"
    Disconnect-VIServer -Server $vcenter -Confirm:$false -Force:$true -WarningAction SilentlyContinue -ErrorAction SilentlyContinue

    Write-Host " VIServer Disconnected"
    Remove-PSSnapin VMware.VimAutomation.Core
}
$j = Start-Job -ScriptBlock $code -Arg $args

Write-Host " cp2"
if (Wait-Job $j -Timeout $timeoutSeconds) { Receive-Job $j }
Write-Host " cp3"

Remove-Job -force $j
Write-Host " gridControl - Terminate"

What's important is the output I get from

Write-Host $args[0]
Write-Host $args[1] $args[2] $args[3]

Which is:

15:05:49 grid1
15:05:49 grid2 grid3 

When it should be

15:05:49 start
15:05:49 grid1 grid2 grid3

Any idea why this is the case?

boxdog
  • 7,894
  • 2
  • 18
  • 27
Kusnan
  • 135
  • 1
  • 10
  • 1
    `$args` is an [automatic variable](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_automatic_variables). Do not re-define automatic variables. – Ansgar Wiechers Jun 18 '19 at 13:35
  • YES! This is it. I just removed param($args) and it worked! Thanks. Could you please answer rather than comment so I can mark it? – Kusnan Jun 18 '19 at 13:37

1 Answers1

5

Reference items in the $args array directly. You don't need that param($args) statement at top of the script.

Simplified example...

$things = @(1, 2, 3);
$script = {
    Write-Host $args[0]
    Write-Host $args[1]
}

foreach ($thing in $things) {
    Start-Job -ScriptBlock $script -ArgumentList $thing, ($thing * 3) -Name "Job-${thing}"
}

Receive-Job -Name "Job-1"
Receive-Job -Name "Job-2"
Receive-Job -Name "Job-3"

If you run this in your shell, you'll see I'm getting both parameters.

enter image description here

Adam
  • 3,891
  • 3
  • 19
  • 42