Reputation: 171
I have a powershell script file which is as follows
param(
[parameter(Mandatory = $true)]
[string] $db_server,
[parameter (Mandatory = $true)]
[string[]] $db_server_list
)
write-output "My DB server is $db_server"
foreach ($list in $db_server_list)
{
write-output $list
}
Let us assume the file is saved as script1.ps1
On my development laptop, I can run this from visual studio code without any issues.
.\script1.ps1 -db_Server 'my_db_server,999' -db_server_list ("server1,5694","server2,7788")
It runs fine, the value of db_Server is as specified that is my_db_server,999 and i am able to loop through the db_Server_list without loosing the comma which is the port number.
I am calling the file from an external orchestration program, and to do so. I need to run
powershell.exe .\script1.ps1 -db_Server 'my_db_server,999' -db_server_list ("server1,5694","server2,7788")
And all of a sudden i get errors.
Cannot process argument transformation on parameter 'db_server'. cannott convert value to type System.string. I do not want db_server to be an array even though it has a comma, I need it back as a single string as I used this for a connection string, and if the value after the comma is stripped off, it will break my script.
Please note that this only happens when i call powershell.exe scriptfile.ps1. Running from VS code doesnt result in such errors.
Thanks all.
I have ran it again, its thesame issue.
The reason why I need to add powershell.exe is because I am calling the script from an ansible playbook.
Upvotes: 1
Views: 281
Reputation: 440471
Note:
Ansible also offers the ansible.windows.win_shell
module, which uses a shell to process the specified command line, and that shell is PowerShell.
If you use this method, you can therefore use your original PowerShell command as-is (note that I've removed the unnecessary (...)
around the array passed to -db_server_list
and have switched to single-quoting):
.\script1.ps1 -db_Server 'my_db_server,999' -db_server_list 'server1,5694', 'server2,7788'
By contrast, if you use ansible.windows.win_command
, no shell is involved and you must indeed call (Windows) PowerShell's CLI, powershell.exe
, explicitly, as shown below.
Note:
The command below is meant to be run from outside PowerShell and only works there[1]; from inside PowerShell, you wouldn't need to call powershell.exe
to begin with, but if you did, you'd either have to enclose everything after -c
in "..."
in this case (which would also work from outside PowerShell) or, from inside PowerShell only, in { ... }
- but note that neither approach is a valid test for whether a given a command line will work when called from OUTSIDE PowerShell.
If you were to call from cmd.exe
, it is generally preferable to enclose the entire argument list passed to -c
(-command
) in "..."
, so as to prevent inadvertent interpretation of special characters such as &
by cmd.exe
up front. This is not necessary in shell-free invocation scenarios, such as with ansible.windows.win_command
or from a scheduled task, for instance.
Either way, if you want "
characters to be seen by PowerShell's -c
parameter as part of the command to (ultimately) execute, you must escape them as \"
- unescaped "
characters are stripped during command-line parsing, which explains why your attempt didn't work: -db_server_list ("server1,5694","server2,7788")
, when passed from outside PowerShell, is ultimately seen as
-db_server_list (server1,5694,server2,7788)
, which is broken syntax.
By contrast, '
characters need no escaping, and switching to using '...'
arguments exclusively offers the simplest solution in your case.
powershell.exe -c .\script1.ps1 -db_Server 'my_db_server,999' -db_server_list 'server1,5694', 'server2,7788'
[1] The reason it doesn't work from PowerShell is that the calling PowerShell session interprets the '...'
strings, and in this case passes their content unquoted, because the content happens not to contain space characters.
[2] Note that pwsh
, the PowerShell (Core) 7+ CLI now defaults to -File
instead. See this answer for details on how arguments passed to -c
(-Command
) are parsed, juxtaposed with -f
(-File
) arguments, and when to use which parameter.
Upvotes: 2