SqlPackage seems to escape right square bracket ( ] ) in variable value passed to .dacpac - dacpac

I'm passing a variable to my .dacpac but the text received is not what I passed. Example command:
sqlpackage /v:TextTest="abc]123" /Action:Publish /SourceFile:"my.dacpac" /TargetDatabaseName:MyDb /TargetServerName:"."
My variable $(TextTest) comes out as "abc]]123" instead of the original "abc]123".
Is there anything I can do to prevent SqlPackage from corrupting my input variables before they are passed to the .dacpac scripts?

Unfortunately, I don't think there is a good answer. This appears to be a very old bug. I'm seeing references to this issue going back 10 years.
Example A: https://web.archive.org/web/20220831180208/https://social.msdn.microsoft.com/forums/azure/en-US/f1d153c2-8f42-4148-b313-3449075c612f/sql-server-database-project-sqlcmd-variables-with-closing-square-brackets
They mention a "workaround" in the post, but they link to a Microsoft Connect issue which no longer exists and is not available on archive.org.
My best guess is that the "workaround" is to generate the deploy script rather than publishing, and then manually modify the variable value in the script...which is not really a workaround if you are working on a build/release pipeline or any sort of automation.
I tried testing this to see if it would make any difference using Microsoft.SqlServer.Dac.DacServices.Publish() directly (via dbatools PowerShell module), but unfortunately the problem exists there as well.
I also tested it against every keyboard accessible symbol and that is the only character it seems to have a problem with.
Another option, though still not great, is to generate the deployment script, then execute it using SQLCMD.EXE.
So for example this would work:
sqlpackage /Action:Script `
/DeployScriptPath:script.sql `
/SourceFile:foobar.dacpac `
/TargetConnectionString:'Server=localhost;Database=foobar;Uid=sa;Password=yourStrong(!)Password' `
/p:CommentOutSetVarDeclarations=True
SQLCMD -S 'localhost' -d 'foobar' -U 'sa' -P 'yourStrong(!)Password' `
-i .\script.sql `
-v TextTest = "abc]123" `
-v DatabaseName = "foobar"
/p:CommentOutSetVarDeclarations=True - This setting is key, otherwise SQLCMD will be overridden by what's in the file. Just make sure you specify ALL variables, and not just the one you need. So open the file to look at what is commented out and make sure you are supplying what is needed.
It's not a great option...but it's at least scriptable and doesn't require manual intervention.

Related

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

How to query Maya in script for supported file translator plugins?

I'm trying to specify an FBX file in MEL using the command
file -f -pmt 0 -options "v=0;" -typ "FBX" -o
on one computer this works great. On another, it fails but DOES work if I use
-typ "Fbx"
I think I'd like to query for the supported translators in my script, then either select the correct one or report an error. Is this possible? Am I mis-diagnosing the problem?
MEL has a command called pluginInfo. You could write a simple function that will return the proper spelling based on that. pluginInfo -v -query "fbxmaya"; will provide the version of the fbx plugin. I haven't used MEL in a while so I'm not gonna try to make this perfect but maybe something like if(pluginInfo -v -query "fbxmaya") ) string fbxType = "FBX" else( string fbxType = "Fbx"). Then just plug that var into file -f -pmt 0 -options "v=0;" -typ $fbxType -o.
It might be a different version of fbx. You'd have to provide another line which determines the version of fbx on that particular machine and pipes in the correct spelling.

Keep user env variables executing gksu

I have a program in c/gtk which is opened with gksu. The problem is that when I get the environment variable $HOME with getenv("HOME") it returns "root" obviously. I would like to know if there is a way to know who was the user that executed the gksu or the way to get his environmental variables.
Thanks in advance!
See the man page. Use gksu -k command... to preserve the environment (in particular, PATH and HOME).
Or, like Lewis Richard Phillip C indicated, you can use gksu env PATH="$PATH" HOME="$HOME" command... to reset the environment variables for the command. (The logic is that the parent shell, the one run with user privileges, substitutes the variables, and env re-sets them when superuser privileges have been attained.)
If your application should only be run with root privileges, you can write a launcher script -- just like many other applications do. The script itself is basically
#!/bin/sh
exec gksu -k /path/to/your/application "$#"
or
#!/bin/sh
exec gksu env PATH="$PATH" HOME="$HOME" /path/to/your/application "$#"
The script is installed in /usr/bin, and your application as /usr/bin/yourapp-bin or /usr/lib/yourapp/yourapp. The exec means that the command replaces the shell; i.e. nothing after the exec command will ever be executed (unless the application or command cannot be executed at all) -- and most importantly, there will not be an extra shell in memory while your application is begin executed.
While Linux and other POSIX-like systems do have a notion of effective identity (defining the operations an application may do) and real identity (defining the user that is doing the operation), gksu modifies all identities. In particular, while getuid() returns the real user ID for example for set-UID binaries, it will return zero ("root") when gksu is used.
Therefore, the above launch script is the recommended method to solve your problem. It is also a common one; run
file -L /usr/bin/* /usr/sbin/* | sed -ne '/shell/ s|:.*$||p' | xargs -r grep -lie launcher -e '^exec /'
to see which commands are (or declare themselves to be) launcher scripts on your system, or
file -L /bin/* /sbin/* /usr/bin/* /usr/sbin/* | sed -ne '/shell/ s|:.*$||p' | xargs -r grep -lie gksu
to see which ones use gksu explicitly. There is no harm in adopting a known good approach.. ;)
you could assign the values of these environment vars to standard variables, then execute gksu exporting the vars after gkSU... By defining these after the gkSU using && to bind together your executions, so that you essentially execute using cloned environment variables...
A better question is why do this at all? I realize you are wanting to keep some folders, but am not sure why as any files created as root, would have to be globally writable, probably using umask, or you would have to manually revise permissions or change ownership... This is such a bad Idea!
Please check out https://superuser.com/questions/232231/how-do-i-make-sudo-preserve-my-environment-variables , http://www.cyberciti.biz/faq/linux-unix-shell-export-command/ & https://serverfault.com/questions/62178/how-to-specify-roots-environment-variable

How do I test a manual check in check_mk / Nagios

My organization is using Nagios with the check_mk plugin to monitor our nodes. My question is: is it possible run a manual check from the command line? It is important, process-wise, to be able to test a configuration change before deploying it.
For example, I've prepared a configuration change which uses the ps.perf check type to check the number of httpd processes on our web servers. The check looks like this:
checks = [
( ["web"], ALL_HOSTS, "ps.perf", "Number of httpd processes", ( "/usr/sbin/httpd", 1, 2, 80, 100 ) )
]
I would like to test this configuration change before committing and deploying it.
Is it possible to run this check via the command line, without first adding it to main.mk? I'm envisioning something like:
useful_program -H my.web.node -c ps.perf -A /usr/sbin/httpd,1,2,80,100
I don't see any way to do something like this in the check_mk documentation, but am hoping there is a way to achieve something like this.
Thanks!
that is easy to check.
Just make your config changes and then run:
cmk -nv HOSTNAME.
That (-n) will try run everything and return (-v) the output.
So can see the same results like later in the GUI.
List the check
$check_mk -L | grep ps.perf
if it listing ps.perf then run following command,
$check_mk --checks=ps.perf -I Hostname

has anyone faced this error "Error: No valid counters" using type perf?

Has anyone faced this error, Error: No valid counters, using typeperf utility while writing it to SQL database. I have tried variety of different things but every time I try to write it in SQL database using counters in a file it fails with the No valid counters error.
The command was executed in the following fashion:
C:\>typeperf -cf "E:\DBA\CounterCollector\counters_eg.txt" -si 15 -sc 10 -f SQL -o SQL:SQLServerDS!log5
The counters_eg.txt file contains:
"\\<computername>\PhysicalDisk(* *)\Avg. Disk Queue Length"
I am able to write in SQL database by specifying the counters individually at command prompt.
example:
C:\Windows\system32>typeperf -f SQL -o SQL:SQLServerDS!log4 "\\<computername>\PhysicalDisk(* *)\Avg. Disk Queue Length"
Note: I have replaced the server name by <computername>.
Include a double '%%', i.e.
typeperf "\\<remote-IP>\Process(*)\%% Processor Time" -sc 1
Figured it out:
After following the example from
https://www.simple-talk.com/sql/performance/collecting-performance-data-into-a-sql-server-table/
I kept on getting the same error message "Error: No valid counters". The counter.txt is exactly the same like the example provided by Feodor but when I put the counter names on the command line individually, they get processed successfully. The problem I was getting was when I tried to run the entire syntax.
Instead of using what Feodor used:
"TYPEPERF -f SQL -s ALF -cf “C:\CounterCollect\Counters.txt” -si 15 -o SQL:SQLServerDS!log1 -sc 4",
I tweaked it a little bit (after looking at the second example from http://technet.microsoft.com/en-us/library/cc753182.aspx) and finally it WORKED! It is a matter of switching the parameters.
After following the demo by Feodor, I used this below syntax, and it worked for me. I am using SQL Server 2012 and here is the command:
TYPEPERF -cf "C:\PerfMonCollect\Counters.txt" -si 5 -sc 4 -f SQL -o SQL:SQLdatasource!log1".
Your counters list may be damaged. Run perfmon GUI utility and make sure that you are able to see the counters in there.
make sure your file name is correct. counters.txt NOT counters.txt.txt . show extensions then check the file name. also, you can try the RUN command and paste your target to the text file and see if it works.
I had the same issue and it drove me crazy.
I had this error now and solved it by adding the user running typeperf to local administrators group on the servers that threw the error.
I was getting this error on a server(Windows Server 2012 R2) I had admin rights on, I had to manually build performance counters and it was sorted. Here's the link https://support.microsoft.com/en-us/help/2554336/how-to-manually-rebuild-performance-counters-for-windows-server-2008-6
The problem is that the file should contain only file names, without " quote marks.
Removing all " from counterlist resolved the issue for me.

Resources