Search code examples
powershellparametersargumentsio-redirection

PowerShell: execute a command line with input (arguments) from the caller


I'm trying to write a powershell script, when it's executing, it takes 2 variables and pass it to a function. That function runs a command line with the input variables.

code:

function ExecuteSQLScript($sqlfile, $dbconnection) {
    & 'sqlplus ' $dbconnection' @'$sqlfile ' <nul'
}

main block:

    ExecuteSQLScript('c:\test.sql', 'testing/password@db')

*basically I want the command line to execute:
SQLPLUS testing/password@db @c:\test.sql < nul*

runs the command line to call SQLPLUS to execute a sql file in powershell.


Solution

  • Define your function as follows:

    function ExecuteSQLScript($sqlfile, $dbconnection) {
        @() | sqlplus $dbconnection "@$sqlfile"
    }
    
    • @() | ... is PowerShell's equivalent of cmd.exe's <NUL (PowerShell has no < operator); @() is an empty array that is enumerated in the pipeline and therefore sends nothing to the external program' stdin stream.

    • & for invocation is only needed for command names that are quoted and/or contain variable references; while you may use & sqlplus ..., just sqlplus ... is sufficient.

    • Variable references that by themselves act as command arguments ($dbonnection above) never need quoting in PowerShell (except if you want to explicitly force stringification up-front, e.g. "$dbconnection")

    • @ is a metacharacter in PowerShell, so it must either be escaped or inside a quoted string; here, an expandable (double-quoted) string ("...") is used both to use the @ verbatim and to use string interpolation (expansion) to append the value of $sqlfile.

    Invoke it as follows, for instance:

    # Note: *Whitespace* between arguments, no (...)
    ExecuteSQLScript 'c:\test.sql 'testing/password@db'
    
    • That is, PowerShell functions, cmdlets, scripts, and external programs must be invoked like shell commands - foo arg1 arg2 - not like C# methods - foo('arg1', 'arg2').
      If you use , to separate arguments, you'll construct an array that a command sees as a single argument.
      See the this answer and this answer for more information.