Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass an array into a PowerShell script from the OS

The following command line causes my script to throw due to missing arguments. The problem only happens when the -WebServerList parameter contains parentheses to denote an array.

This is launched by TeamCity, which I assume is making a simple Windows shell command and so its possible that the () are being interpreted by the shell/Windows.

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -ExecutionPolicy ByPass -File E:\PowerShell\DeploySolution.ps1`
    -ProjectName Integro -BuildVersion "8.0.5 (build 27692) " -DeploymentType IIS`
    -WebServerList @("ws1", "ws2") -WebServerUserName TeamCityMSDeploy`
    -WebServerPassword yeahR1ght -WebPackagePath E:\WebDeployPackages\IntegroWebAPI_QA_MSDeploy_Package.zip`
    -WebServerDestination Integro-QA`
    -MSDeployPath "C:\Program Files\IIS\Microsoft Web Deploy V3"

However, I've tried DOS escaping e.g. ^( ... ^) and that doesn't help. Invoking PowerShell scripts from Windows has always been hard work, afterall who'd wanna do a crazy thing like that right?!

In the mean time, I'm going to change my script to access a CSV in a single string and split it manually, so I can go home, but it'd be nice to know if there's a proper way to handle this.

like image 267
Luke Puplett Avatar asked Nov 28 '13 19:11

Luke Puplett


2 Answers

It seems like the issue is that array configuration cannot be correctly defined by the OS. You can achive something similar to what you want by using -Command instead of -File:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -ExecutionPolicy ByPass `
-Command "& E:\PowerShell\DeploySolution.ps1 -ProjectName Integro`
-BuildVersion '8.0.5 (build 27692) ' -DeploymentType IIS  `
-WebServerList @('ws1', 'ws2') -WebServerUserName TeamCityMSDeploy`
-WebServerPassword yeahR1ght `
-WebPackagePath E:\WebDeployPackages\IntegroWebAPI_QA_MSDeploy_Package.zip `
-WebServerDestination Integro-QA `
-MSDeployPath 'C:\Program Files\IIS\Microsoft Web Deploy V3'"

Cheers, Chris.


I took the liberty of editing your answer to demo the results, and prove it works.

From a DOS command prompt:

C:\>c:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -ExecutionPolicy ByPass -File c:\DATA\Git\PowerShell\Test-PassingArray.ps1 -Array milk
milk

C:\>c:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -ExecutionPolicy ByPass -File c:\DATA\Git\PowerShell\Test-PassingArray.ps1 -Array @("milk", "cheese")
@(milk,

C:\>c:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -ExecutionPolicy ByPass -Command "& c:\DATA\Git\PowerShell\Test-PassingArray.ps1 -Array @("milk", "cheese")"
At line:1 char:61
+ & c:\DATA\Git\PowerShell\Test-PassingArray.ps1 -Array @(milk, cheese)
+                                                             ~
Missing argument in parameter list.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : MissingArgument


C:\>c:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -ExecutionPolicy ByPass -Command "& c:\DATA\Git\PowerShell\Test-PassingArray.ps1 -Array @('milk', 'cheese')"
milk
cheese

C:\>
like image 178
dwarfsoft Avatar answered Nov 05 '22 19:11

dwarfsoft


You need a work around for this in TeamCity as it passes its command-line items separated by a comma which is the same separator for the array items in Powershell. Pass the array as a semicolon separated strings and split these in the Powershell script. Here is an example.

Pass this to the script in the command line (whether File or plain script):

-WebServerList "ws1;ws2"

Then use this in the script:

$WebServerList -split ";" | ForEach {
    $server = $_
    # do whatever you like here
}

Note: this solution works for simple array objects like strings and numbers but not complex objects.

like image 31
katrash Avatar answered Nov 05 '22 18:11

katrash