23

I have a string in powershell, which contains a native sqlcmd command. The command itself can be executed successfully in cmd.exe. I have difficulty in executing them in powershell. Anyone can help? Thanks.

This is sql.sql

select @@servername
go
select @@servicename

This is the result when I execute the sqlcmd command from cmd.exe

C:\Users\test>sqlcmd -S "(local)\instance1" -U a -P a -i "c:\temp\sql.sql"

--------------------------------------------------
thesimpsons\INSTANCE1

(1 rows affected)

--------------------------------------------------
INSTANCE1

(1 rows affected)

C:\Users\test>

This is the powershell script to call the sqlcmd command.

$sql = @"
sqlcmd -S "(local)\instance1" -U a -P a -i "c:\temp\sql.sql"
"@

Invoke-Command $sql

When I execute this powershell script, I got the following error.

PS C:\TEMP> $sql = @"
sqlcmd -S "(local)\instance1" -U a -P a -i "c:\temp\sql.sql"
"@

Invoke-Command $sql
Invoke-Command : Parameter set cannot be resolved using the specified named parame
ters.
At line:5 char:15
+ Invoke-Command <<<<  $sql
    + CategoryInfo          : InvalidArgument: (:) [Invoke-Command], ParameterBin 
   dingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Microsoft.PowerShell.Commands 
   .InvokeCommandCommand
1

7 Answers 7

27

To call a Win32 executable you want to use the call operator & like this:

& sqlcmd -S "(local)\instance1" -U a -P a -i "c:\temp\sql.sql"
Sign up to request clarification or add additional context in comments.

Comments

21

You could also stop using the external 'SQLCMD.EXE' and use the Invoke-Sqlcmd cmdlet instead:

Invoke-Sqlcmd is a SQL Server cmdlet that runs scripts that contain statements from the languages (Transact-SQL and XQuery) and commands that are supported by the sqlcmd utility

Just open the 'sqlps' utility and run

Invoke-Sqlcmd -InputFile "C:\temp\sql.sql"

Please see Running SQL Server PowerShell

You can also load the SQL Server snap-ins manually in PowerShell before using 'Invoke-Sqlcmd';
for MS SQL Server 2012 you can do that by running
Import-Module SqlPs

4 Comments

While Andi Arismendi's answer is a good one, and directly answers executing of the sqlcmd executable, I believe this one should be the accepted answer. If you're running sqlcmd scripts through powershell, it will save you time, effort, and keystrokes to simply use Invoke-Sqlcmd.
1. Invoke-Sqlcmd doesn't implement all the commands that are available with SQLCMD. 2. Invoke-Sqlcmd is not included in the base Powershell install
Invoke-Sqlcmd adds a semicolon to the end of stored procedures, which causes issues with comparison tools. See social.msdn.microsoft.com/Forums/sqlserver/en-US/… and reddit.com/r/PowerShell/comments/5v29o2/…
Not to mention, Invoke-Sqlcmd wasn't supported in Powershell 2.0.
6

This is how I build some externals command in my scripts

$scriptblock = {fullpath\sqlcmd -S `"(local)\instance1`" <# comment option -S #>`
                                -U a `
                                -P a `
                                -i `"c:\temp\sql.sql`" }
Invoke-Command -ScriptBlock $scriptBlock

You can then use $args variable inside it and even start it remotly.

$scriptblock = {fullpath\sqlcmd -S `"(local)\instance1`" <# comment option -S #>`
                                -U a `
                                -P a `
                                -i `"$($args[0])`" }
Invoke-Command -ScriptBlock $scriptBlock -argumentList "c:\temp\sql.sql" -computer "remote1"

Remark :

This allow to comment each param.

Be careful not to forget a "`" and no space after them where they are at the end of the line.

Comments

3

Use Invoke-Expression rather than Invoke-Command

3 Comments

I don't see why people try to use Invoke-Expression when calling Win32 executables... This is what the call operator is for.
@Andy - Invoke-Expression allows you to generate the entire command as a string first, which could be useful depending upon the circumstances. See stackoverflow.com/questions/6604089/…
Yep, but that's not happening here. Only use Invoke-Expression when there is an expression that needs to be evaluated.
3

The first positional parameter of invoke-command is -scriptblock, and it expects a script block argument. To take advantage of a here-string to build the command and then run it with invoke-command, you need to convert the here-string to a script block:

$sql = @"
sqlcmd -S "(local)\instance1" -U a -P a -i "c:\temp\sql.sql"
 "@

 Invoke-Command ([scriptblock]::create($sql))

1 Comment

All this is going to do is return the value in $sql, it will not actually execute it (at least not on my machine).
0

Both instance name and username should be fully qualified

<domain_name>\Instanc_name and <domai_name>\Username. Only your instance name is correctly scripted.

Comments

0

This is what worked for me for using sqlcmd from within the powershell script using the & operator, see sample to generate a csv file:

& cmd /c "sqlcmd -S $sv -i $PROCFILE -s, -v varDB = $dbclean -o $filename"

$sv has server name like SERVERNAME\INSTANCE

$PROCFILE is like d:\TSTSQL\Sqlquery.SQL

$filename is d:\TSTSQL\Desiredoutfilename.CSV

$dbclean is a parameter passed to the sql file

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.