2

I have been investigating an issue we see in some deployments at work.

For background, we have multiple services deploying into Azure, and there is one main script which uses Start-Job to run concurrent sub-jobs. Most of the time this worked, although occasionally we saw builds where a sub-job reported as completed, but its HasMoreData attribute was false, and no errors showed up anywhere. No sub-job that we run could complete successfully without at least having one line of logs, so this appears to be an error with starting the job.

This is the command we used to create the jobs:

Start-Job -Name $RepoName -ScriptBlock {Invoke-Expression -Command "$args"} -ArgumentList $command

During discussions we thought possibly there was an error, but that the Invoke-Expression was eating it, so we changed the job creation to instead be:

Start-Job -Name $RepoName -ScriptBlock ([ScriptBlock]::Create(".{$command}"))

Since making that change yesterday we have not seen this issue re-appear. To test I created a new branch where I reverted back to the Invoke-Expression method and immediately began seeing the error again.

I was just hoping to see if anyone might have an idea about why this issue might be appearing, and why it is an intermittent problem when using the Invoke-Expression method, but not the [ScriptBlock]::Create method.

Thank you!

Edit for further background:

So the main script (deployAll.ps1) has a list of services to deploy and for each one it builds up a command to execute, which builds the necessary environment, then calls a deployService.ps1 script provided by each service.

Regarding building the command to execute, we have a common script all the sub-jobs use, so we import that and login to Azure as part of the command we build up, so the command that actually gets passed to Start-Job looks something like:

Import-Module $ScriptPath\AzureWrapper.ps1 -Force; $ScriptPath\login.ps1 -AzureAppID $Env:AZURE_APP_ID -AzurePassword $Env:AZURE_PASSWORD -AzureTenantId $Env:AZURE_TENANT_ID; $ScriptPath\..\$RepoName\deploy\deployService.ps1 -subscriptionId '$subscriptionId' -environmentFilePath '$configPath'

Additionally, after looking into Invoke-Expression further it seems it may have been the reason those setup commands were necessary, since it runs in a separate environment.

  • 1
    `$args` is an automatic variable and `Invoke-Expression` is a dangerous cmdlet that you shouldn't use in general. It could be possible `$args` isn't being populated properly. You could test this by adding a line outputting the value in the scriptblock before `iex` – Maximilian Burszley Apr 10 '18 at 16:36
  • 1
    I think my question here is why are you trying to indiscriminately run powershell commands through jobs? – Maximilian Burszley Apr 10 '18 at 16:41
  • Thanks for the response! We are calling subscripts to run deployments, but need to do some environment setup ahead of time for authentication. – Matt Brenner Apr 10 '18 at 18:35
  • Sorry, accidentally hit enter too soon there, continuation: So the main script (deployAll.ps1) has a list of services to deploy and for each one it builds up a command to execute, which builds the necessary environment, then calls a deployService.ps1 script provided by each service. – Matt Brenner Apr 10 '18 at 18:49
  • What do you mean "builds up a command"? Could you give an example? (preferably in your question) – Maximilian Burszley Apr 10 '18 at 19:58
  • I edited my question with the information I provided in these comments, as well as an example command. – Matt Brenner Apr 10 '18 at 20:18

0 Answers0