Thursday, December 30, 2010

Setting dynamic connection string for dtexec.exe in Powershell

This one had me banging my head on the wall and hitting Google hard until I just took a step back and tried to get inside of Powershell’s head.

Basically I have a Powershell-based build script that (among other things) needs to execute an SSIS package that initializes a database from an Excel spreadsheet, and at the end of the build process deploys a web application to IIS using the Powershell WebAdministration module. 

But here’s the catch: the Excel data support in SSIS only works in 32-bit mode and the WebAdministration module only works in 64-bit mode.  So what I need to do is launch the 32-bit version of the dtexec.exe utility from my 64-bit Powershell script.  Seems easy enough, right?  Nope.

After struggling for a while in Powershell, I switched to the good old Windows Command Prompt and managed to get it working fairly quickly using the following syntax:

"C:\Program Files (x86)\Microsoft SQL Server\100\DTS\Binn\DTExec.exe" 
    /File "C:\Path\To\My\Package\Import Types.dtsx"
    /Conn Connection1;"Provider=SQLNCLI10;Server=MYSERVER;Database=DB_ONE;Uid=USERNAME;Pwd=PASSWORD;"
    /Conn Connection2;"Provider=SQLNCLI10;Server=MYSERVER;Database=DB_TWO;Uid=USERNAME;Pwd=PASSWORD;"
    /Set \package.variables[User::ExcelFilePath].Value;"C:\Path\To\My\Data\Import Types.Data.xls"

If you just try to slap a “&” on the front and execute it in Powershell, it doesn’t work.  I tried many variations until I arrived at this particular translation:

& "C:\Program Files (x86)\Microsoft SQL Server\100\DTS\Binn\DTExec.exe" 
    /File "C:\Path\To\My\Package\Import Types.dtsx"
    /Conn "Connection1;`"Provider=SQLNCLI10;Server=MYSERVER;Database=DB_ONE;Uid=USERNAME;Pwd=PASSWORD;`""
    /Conn "Connection2;`"Provider=SQLNCLI10;Server=MYSERVER;Database=DB_TWO;Uid=USERNAME;Pwd=PASSWORD;`""
    /Set "\package.variables[User::ExcelFilePath].Value;C:\Path\To\My\Data\Import Types.Data.xls"

I’ve tried to make complete sense of why that particular formatting works, but I can’t.  Here’s a couple of observations about the Powershell version:

  • The argument values  need to be wrapped in quotes in their entirety.
  • The quotes found in the Command Prompt version need to be escaped in Powershell in order for DTExec to receive them correctly.

But that second observation is only almost true.  The /Set argument only works if you drop the embedded quotes altogether.  When I tried retaining them from the Command Prompt version and escaping them for inclusion in the Powershell, I got an error.  Dropping the quotes altogether worked, despite the embedded space in the file name.  At this point, however, I’m not arguing!

3 comments:

Fahad Khalid Bhatti said...

I am unable to set connection string of a connection manager using /CONN. Can you please share the complete procedure?

Geoff McElhanon said...

I don't understand your question. The documentation for the dtexec utility is available at http://msdn.microsoft.com/en-us/library/ms162810%28v=sql.105%29.aspx, and it describes in there the exact format of the /Conn parameter.

This post was really just focusing on how to get the syntax correct for PowerShell.

tdai_dev said...

I built my argument in SSIS process task, but unfortunately, its not working. Could you please help.


My Argument:
----------------------
"/FILE \"" + @[User::entityStagePackage] + "\" /SET \\Package.Variables[User::controlCount].Properties[Value];\"" + (DT_WSTR,10) @[User::controlCount] + "\" /SET \\Package.Variables[User::fileID].Properties[Value];\"" + (DT_WSTR,10) @[User::fileID] + "\" /SET \\Package.Variables[User::filePathName].Properties[Value];\"" + @[User::filePathName] + "\"" + " /SET \\Package.Variables[User::archivePath].Properties[Value];\"" + @[User::entityArchivePath] + "\""

+ " /SET \\Package.Variables[User::stageID].Properties[Value];\"" + (DT_WSTR,10)@[User::stageID] + "\""
+ " /SET \\Package.Variables[User::MasterExceptionPkg].Properties[Value];\"" + (DT_WSTR,100)@[User::MasterExceptionPkg]
+ "\"" + (DT_WSTR,500) @[User::iniVariable]


Evaluate Expression:
--------------------------
/FILE "" /SET \Package.Variables[User::controlCount].Properties[Value];"0" /SET \Package.Variables[User::fileID].Properties[Value];"23" /SET \Package.Variables[User::filePathName].Properties[Value];"" /SET \Package.Variables[User::archivePath].Properties[Value];"" /SET \Package.Variables[User::stageID].Properties[Value];"26" /SET \Package.Variables[User::MasterExceptionPkg].Properties[Value];""/Conn metaDBl; "Provider=SQLNCLI10; Server=147.191.62.44; Database=STAGE; Trusted_Connection=yes;"

Error message:
-----------------
/Conn metaDB; "Provider=SQLNCLI10; Server=157.191.62.45; Database=OH_STAGE; Trusted_Connection=yes;"" at "",

The process exit code was "6" while the expected was "0".