PowerShell DTexec /ISServer pass a connectionstring as package variable - sql-server

I want to execute a SSIS package on ISServer via PowerShell.
I used the script found on microsoft page. This doesn't work out for me.
I want to pass a connectionstring but not to assign to the connectionmanager but just as a variable string. In the connectionstring there are \ and ; present and powershell sees this as a new option. I just want it to be seen as a whole string.
I've tried everything, adding "\" and \"" like some websites suggested, used instead of \, put double quotes, put ' quotes, nothing works. Always getting the error optionMyServer\MyServer;Initial is not valid.
I can't removeMyServer\MyServer` because connection is to that instance.
The Connectionstring is assigned via a changing variable. So variable contains Data Source=MyServer\Myserver;Initial Catalog=SQL_MyArchive;Provider=SQLNCLI11;Integrated Security=SSPI;
dtexec /ISSERVER "\SSISDB\Test\Test.dtsx" /SERVER "MYServer" /ENVREFERENCE 8 /Par "$Package::ConnectionSource";`""Data Source=MyServer\Myserver;Initial Catalog=SQL_MyArchive;Provider=SQLNCLI11;Integrated Security=SSPI;"`"
How can i let the system see the whole connectionstring as a string? "" and "" does not work.

use the following syntax to pass a connectionstring to a variable (you missed a \")
/Par "$Package::ConnectionSource";\""Data Source=MyServer\Myserver;Initial Catalog=SQL_MyArchive;Provider=SQLNCLI11.1;Integrated Security=SSPI;"\"

Related

SQL Connection String Format Error in Docker

I am running a Docker container with a gMSA identity to connect to SQL Server via Windows Authentication. I confirmed the gMSA identity is working correctly within the container, however I'm receiving a SQL connection string format error:
"Format of the initialization string does not conform to specification starting at index 0."
My Dockerfile looks like this:
FROM microsoft/dotnet:2.2-runtime-nanoserver-sac2016
COPY . .
ENTRYPOINT ["dotnet", "Daemon.dll"]
CMD ["EventConfig:MqHostName=10.23.2.1", "ConnectionStrings:TestDb1=Data Source=10.23.2.1;Initial Catalog=Events;Integrated Security=true", "ConnectionStrings:TestDb2=Data Source=10.23.2.1;Initial Catalog=Notifications;Integrated Security=true", "ConnectionStrings:TestDb3=Data Source=10.23.2.1;Initial Catalog=TESTDB;Integrated Security=true"]
Running docker inspect on the container looks like the CMD parameters are parsed correctly, however I'm still receiving the error. The connection strings work without issue outside of Docker.
I've tried surrounding the connection strings by a backtick `, single quotes, double quotes, and slash . I've also tried passing in the strings as ENV variables instead of as CMD parameters. I've also tried adding a parser directive such as
# escape=`
to the top of my Dockerfile. Any help would be greatly appreciated.
For anyone who may have a similar issue, I determined how to escape the inner quotes using the \ character. The correctly formatted Dockerfile connection strings looks like this:
CMD ["EventConfig:MqHostName=10.23.2.1", "ConnectionStrings:TestDb1\"=Data Source=10.23.2.1;Initial Catalog=Events;Integrated Security=true\"", "ConnectionStrings:TestDb2=\"Data Source=10.23.2.1;Initial Catalog=Notifications;Integrated Security=true\"", "ConnectionStrings:TestDb3=\"Data Source=10.23.2.1;Initial Catalog=TESTDB;Integrated Security=true\""]

How to get escape characters to behave through sql server's xp_cmdshell with command with Caret

I'm trying to print from a SQL Server stored procedure to a Label printer using ZPL with variables and a network printer
I've tested the ZPL to make sure it's working and then learned how to pass it through a PowerShell script to get it to print to the correct network printer and its working but I'm stumbling trying to get the command to run in SQL server's xp_cmdshell.
DECLARE #Pickloc varchar(6)
DECLARE #powershell varchar(2000)
print #powershell
set #Pickloc = 'PCK002'
set #powershell = 'powershell.exe -command """"^XA ^LH0,50^FS ^PR4,4 ^LL2233 ^CI0^FT20,15^A0N,20,20^FDBACKSTOCK^FS ^CI0^FT180,30^A0N,65,65^FDPick Loc: PCK002^FS ^FO50,50^GB700,1,3^FS ^CI0^FT50,114^A0N,65,65^FDSKU: 91007419^FS ^CI0^FT50,184^A0N,65,65^FDBackstock Loc: FL0002^FS ^FO50,200^GB700,1,3^FS ^CI0^FT50,270^A0N,48,48^FDDriver: Driver^FS ^CI0^FT50,330^A0N,48,48^FDFrom Loc: ABC001^FS ^CI0^FT475,330^A0N,48,48^FDTAG: T123456^FS ^XZ""" | Out-Printer -NAME """\\PrintServer\MyPrinter"""""'
print #powershell
EXEC master..xp_cmdshell #powershell
I'm expecting the string to get passed to PowerShell and print the ZPL.
I'm running into issues I think with windows cmd's escape character "^"
I'd also like to pass the variable #Pickloc inside the ZPL but I can't get past this part first.
I never got an answer but instead of injection the zpl into the powershell command via xp_cmdshell I resorted to creating a text file with the zpl with the variables then calling that file in powershell. Automatically

Deploying SQL Changes Containing $(ESCAPE_SQUOTE())

I have a Database project in Visual Studio that I am attempting to deploy automatically to a test environment nightly. To accomplish this I am using TFS which leverages a PowerShell script to run "SqlPackage.exe" to deploy any changes that have occurred during the day.
Some of my procs contain logic that is run inside of a script that is part of a agent job step and contains the following code(In dynamic SQL):
$(ESCAPE_SQUOTE(JOBID))
When deploying changes that affect this proc, I get the following issue:
SQL Execution error: A fatal error occurred. Incorrect syntax was
encountered while $(ESCAPE_SQUOTE( was being parsed.
This is a known issue, it appears as though that is not supported. It appears to be a function of the "SQLCmd" command misinterpreting the $( characters as a variable:
"override the value of a SQL command (sqlcmd) variable used during a
publish action."
So how do I get around this? It seems to be a major limitation of "sqlcmd" that you can't disable variables, I don't see that parameter that supports that...
Update 1
Seems as through you can disable variable substitution from "sqlcmd" by feeding it the "-x" argument(Source, Documentation):
-x (disable variable substitution)
Still don't see a way to do this from "SqlPackage.exe" though.
It seems that sqlcmd looks for the $( as a token, so separating those two characters is good enough. You can do this with a dynamic query that does nothing more than break the query into two strings:
DECLARE #query nvarchar(256) = N'... $' + N'(ESCAPE_SQUOTE(JOBID)) ...';
EXEC sp_executesql #query
One way to get around this is to refactor the "$(ESCAPE_SQUOTE(JOBID))" string into a scalar function, then setup a PowerShell script to directly invoke the "Sqlcmd" command with the "-x" parameter to "Create/Alter" said function before running "SqlPackage.exe".
Looks something like this in PowerShell:
$sql = #"
USE $database
GO
CREATE FUNCTION [dbo].[GetJobID] ()
RETURNS NVARCHAR(MAX)
AS
BEGIN
RETURN '$(ESCAPE_SQUOTE(JOBID))'
END
GO
"#;
Sqlcmd -S $servername -U $username -P $password -Q $sql -x;
This is a pretty poor workaround, but it does accomplish the task. Really hoping for something better.
I propose another workaround
my job has a step running : DTEXEC.exe /SERVER "$(ESCAPE_NONE(SRVR))"
I just have to add a SQLCMD variable before:
:setvar SRVR "$(ESCAPE_NONE(SRVR))"
this way the toked is considered as SQLCMD variables $(SRVR) and is replaced by the requested value

Running Powershell command in a command line/batch file

I am creating a batch file which involves converting a SID to local/domain username. Since we can not achieve this using the command prompt I am planning to use powershell and I have the PS command as well. I am able to run it in powershell console without any issue, but not sure how to use it in command prompt as a SINGLE LINE(to use it in batch file). I have already tried the below.
Powershell command which works perfectly in PS console -
([System.Security.Principal.SecurityIdentifier]("S-1-5-32-544")).Translate([System.Security.Principal.NTAccount]).Value
Command lines which I have already tried but with no success -
powershell -command ([System.Security.Principal.SecurityIdentifier]("S-1-5-32-544")).Translate([System.Security.Principal.NTAccount]).Value
powershell -command {([System.Security.Principal.SecurityIdentifier]("S-1-5-32-544")).Translate([System.Security.Principal.NTAccount]).Value}
What am I doing wrong? Is it due to any escape characters or am I missing any powershell command parameters? Any help is greatly appreciated.
powershell -command "([System.Security.Principal.SecurityIdentifier]('S-1-5-32-544')).Translate([System.Security.Principal.NTAccount]).Value"
worked for me. Just a question of changing the innermost double-quotes to singles around the SID.
Alternatively, escape them with a backslash
powershell -command "([System.Security.Principal.SecurityIdentifier](\"S-1-5-32-544\")).Translate([System.Security.Principal.NTAccount]).Value"
Here is a short VBScript script that uses WMI to do the conversion for you:
Dim SID
SID = WScript.Arguments.Item(0)
Dim SWbemServices, SWbemObject
Set SWbemServices = GetObject("winmgmts:root/CIMV2")
Set SWbemObject = SWbemServices.Get("Win32_SID.SID='" & SID & "'")
WScript.Echo SWbemObject.ReferencedDomainName & "\" & SWbemObject.AccountName
You would of course need to capture this script's output from your shell script (batch file).
You're actually really close. What you want to do is this:
powershell -command "& {([System.Security.Principal.SecurityIdentifier]('S-1-5-32-544')).Translate([System.Security.Principal.NTAccount]).Value}"
I tested this using the Get-WmiObject cmdlet. In a standard, but elevated cmd shell I entered:
powershell -command "& {get-wmiobject win32_operatingsystem}"
At that point the wmi object data as returned by powershell was written to the console. You can also load the command into a variable like so:
set wmi=powershell -command "& {get-wmiobject win32_operatingsystem}"
If you call the variable %wmi% there's a delay before it prints. The command itself is in the variable so everytime you call the variable it'll execute the powershell code and return the result.
An alternative answer is to use a base64 encodedcommand switch.
#ECHO OFF
powershell -encodedcommand "KABbAFMAeQBzAHQAZQBtAC4AUwBlAGMAdQByAGkAdAB5AC4AUAByAGkAbgBjAGkAcABhAGwALgBTAGUAYwB1AHIAaQB0AHkASQBkAGUAbgB0AGkAZgBpAGUAcgBdACgAIgBTAC0AMQAtADUALQAzADIALQA1ADQANAAiACkAKQAuAFQAcgBhAG4AcwBsAGEAdABlACgAWwBTAHkAcwB0AGUAbQAuAFMAZQBjAHUAcgBpAHQAeQAuAFAAcgBpAG4AYwBpAHAAYQBsAC4ATgBUAEEAYwBjAG8AdQBuAHQAXQApAC4AVgBhAGwAdQBlAA=="
PAUSE
When decoded, you'll see it's the OP's original snippet (with the double quotes preserved). Maybe overkill for the OP, but useful for dev's with larger scripts. Plus my original answer was identical to someone elses, so I had to edit.
powershell.exe -EncodedCommand
Accepts a base-64-encoded string version of a command. Use this parameter
to submit commands to Windows PowerShell that require complex quotation
marks or curly braces.

How to call a SQL script from within another SQL script?

i want to call a series of .sql scripts to create the initial database structure
script1.sql
script2.sql
etc.
is there any way of doing this without sqlcmd or stored procedures or any other kind of code that is not sql ?
just inside a .sql file.
you could try this:
exec master..xp_cmdshell 'osql -E -ix:\path\filename.sql'
osql must be in the path, the full filename must be known, and logins have to be set up correctly (options -E or -U)
Sure. Just create a little app that pulls in all the .sql files you want and executes them. Do it in VB.NET as follows:
Sub ExecuteSqlScript(FilePath As String)
Dim Script As String
Dim FileNumber As Integer
Dim Delimiter As String
Dim aSubscript() As String
Dim Subscript As String
Dim i As Long
Delimiter = ";"
FileNumber = FreeFile
Script = String(FileLen(FilePath), vbNullChar)
' Grab the scripts inside the file
Open FilePath For Binary As #FileNumber
Get #FileNumber, , Script
Close #FileNumber
' Put the scripts into an array
aSubscript = Split(Script, Delimiter)
' Run each script in the array
For i = 0 To UBound(aSubscript) - 1
aSubscript(i) = Trim(aSubscript(i))
Subscript = aSubscript(i)
CurrentProject.Connection.Execute Subscript
Next i
End Sub
Example from: http://snipplr.com/view/3879/run-sql-script-from-external-file/
There's no reason to exclude stored procedures. You don't need to include "any other kind of code that is not sql", plus
EXEC someothersp
which will be required (or its equivalent) in any other solution.
What's your reason for excluding them? I would sure think it beats writing code in yet another language.

Resources