powershellpackerngen

Calling ngen.exe in a script by Packer to create an AWS AMI


I have this script that I need to call inside my AWS AMI creation by packer:

$path = Get-ChildItem C:\WINDOWS\Microsoft.NET\Framework -Filter ngen.exe -Recurse | % { $_.FullName }
Invoke-Expression -Command $path[0] executequeueditems

What I do here, is first I look for the path of the cmd ngen.exe then I call it.

Here is the error I get in packer output:

2020-08-05T19:37:36+02:00: ==> amazon-ebs: Invoke-Expression : A positional parameter cannot be found that accepts argument 'executequeueditems'.
2020-08-05T19:37:36+02:00: ==> amazon-ebs: At C:\Windows\Temp\script-5f2ae86b-540f-14de-f644-90d9dee39092.ps1:2 char:1
2020-08-05T19:37:36+02:00: ==> amazon-ebs: + iex $path[0] executequeueditems
2020-08-05T19:37:36+02:00: ==> amazon-ebs: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2020-08-05T19:37:36+02:00: ==> amazon-ebs:     + CategoryInfo          : InvalidArgument: (:) [Invoke-Expression], ParameterBindingException
2020-08-05T19:37:36+02:00: ==> amazon-ebs:     + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.InvokeExpressionCommand

I don't understand what is going wrong here. In my laptop I can call this command without any error. Here is the output from my laptop:

C:\Windows\Microsoft.NET\Framework\v4.0.30319>ngen.exe executequeueditems
Microsoft (R) CLR Native Image Generator - Version 4.7.3056.0
Copyright (c) Microsoft Corporation.  All rights reserved.
All compilation targets are up to date.

C:\Windows\Microsoft.NET\Framework\v4.0.30319>

I don't know much about ngen.exe (all I do is creating the AMI for the dev team) but here is the documentation : https://learn.microsoft.com/en-us/dotnet/framework/tools/ngen-exe-native-image-generator

and it seems that executequeueditems is the correct command/option.

Do I need to install something before calling it?


Solution

  • You don't need Invoke-Expression (and in fact, it's not recommended).

    I think you can do this:

    Get-ChildItem  $env:SystemRoot\Microsoft.NET\Framework ngen.exe -Recurse | ForEach-Object {
      & $_.FullName executequeueditems
    }
    

    Note that this will run ngen.exe multiple times if it exists in more than one subdirectory under Framework.