Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell script file parameters non-string

Tags:

powershell

Is there a way to pass an object such as a hashtable to a powershell script file via command line?

This is my code:

Param(
    [hashtable]$lookupTable = @{}
)

I tried this:

powershell.exe -NonInteractive -ExecutionPolicy ByPass -File D:\script.ps1  @{APIKey="Uz9tkNhB9KJJnOB-LUuVIA"}

@{APIKey="Uz9tkNhB9KJJnOB-LUuVIA"} being the hashtable parameter.

Error:

D:\script.ps1 : Cannot process argument transformation on parameter 'lookupTable'.
Cannot convert the "@{APIKey=Uz9tkNhB9KJJnOB-LUuVIA}" value of type "System.String" to type "System.Collections.Hashtable". 
+ CategoryInfo : InvalidData: (:) [script.ps1], ParentContainsErrorRecordException 
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,script.ps1

Based on the error, its interpreting the parameter as a string. I am also passing this parameter through teamcity, which only accepts parameters directly and passes it to a command line shown above.

Is there anything I can do to the parameter to tell powershell that it is an object of type hashtable?

PS.

The inputs allowed by teamcity are:

  1. Script File
  2. Script execution mode ["Put script into PowerShell stdin with "-Command -" arguments" and "Execute .ps1 script with "-File" argument"].
  3. Additional command line parameters.
  4. Script arguments (enabled if "Execute .ps1 with -File argument" is selected)

This is the format teamcity is using to execute the script in -Command mode:

powershell.exe -NonInteractive [commandline params] -ExecutionPolicy ByPass -Command - < [script file]

hence:

powershell.exe -NonInteractive @{ APIKey = 'Uz9tkNhB9KJJnOB-LUuVIA'} -ExecutionPolicy ByPass -Command - < D:\BuildAgent-02\work\2204bf4ff5f01dd3\scripts\script.ps1

This is the format teamcity is using to execute the script in -File mode:

powershell.exe -NonInteractive [commandline params] -ExecutionPolicy ByPass -File [script file] [script arguments]

hence when i use script params:

powershell.exe -NonInteractive -ExecutionPolicy ByPass -File D:\BuildAgent-02\work\2204bf4ff5f01dd3\scripts\script.ps1 @{ APIKey = 'Uz9tkNhB9KJJnOB-LUuVIA'}

Is there anyway to work around this format that teamcity is using? For eg. under script arguments, could I do -Command there to serialize the params?

like image 349
Shawn Mclean Avatar asked Feb 09 '14 01:02

Shawn Mclean


2 Answers

The TeamCity PowerShell build step allows you to either execute a script file directly or to execute PowerShell source code entered into the build step definition editor.

When executing a script from a file a hash table parameter is not passed correctly, but when executing PowerShell source code everything works as expected.

However, if the script you want to run is actually in a file, you can execute the script file via PowerShell source code entered into the build step definition:

  1. In the Script field, choose Source

  2. Enter a minimal PowerShell script to execute the script file into the Script source field, for example:

    &'%system.teamcity.build.checkoutDir%\BuildScripts\SomeScript.ps1' -MyArrayOfHashTablesParameter @{SomeParam1='val1';SomeParam2='val2'},@{SomeParam1='val1';SomeParam2='val2'}
    

The PowerShell snippet above executes the script from a script file checked out from version control during the build. To achieve this the TeamCity variable system.teamcity.build.checkoutDir is used to construct a path relative to the checkout directory.

The &' and ' surrounding the script is used to make sure the snippet works even if the path to the script file contains spaces.

like image 155
Erik Öjebo Avatar answered Sep 25 '22 09:09

Erik Öjebo


One option might be to modify the script to take that argument as [string[]], giving it key-value pairs in the arguments and then turn that into a hash table using ConvertFrom-StringData in the script:

$script = {
param ( [string[]]$lookuplist )
$lookupTable = ConvertFrom-StringData ($lookuplist | out-string)
$lookupTable
}

&$script 'APIKey=Uz9tkNhB9KJJnOB-LUuVIA','APIKey2=Uz9tkNhB9KJJnOB-LUuVIA'


Name                           Value                                                         
----                           -----                                                         
APIKey                         Uz9tkNhB9KJJnOB-LUuVIA                                        
APIKey2                        Uz9tkNhB9KJJnOB-LUuVIA 
like image 37
mjolinor Avatar answered Sep 22 '22 09:09

mjolinor