Run SSIS package using T-SQL under different account - sql-server

I normally run an SSIS package using a Sql Agent Job and a proxy user as described here: https://www.sqlservercentral.com/articles/run-an-ssis-package-under-a-different-account
I now need to run the same package using the same proxy user using T-SQL. I've been trying to use the [catalog].[create_execution] and [catalog].[start_execution] procedures to do this but there doesn't seem to be a way to specify a user.
How do I execute a package as a different user?
Is my best recourse the use of T-SQL to execute a SQL Agent Job that is configured to use the proxy user instead?

I don't know how agent actually works to make proxy users work - especially with regard to SSIS packages.
In a "normal" sql session say in SSMS, if I wanted to run a query as another user
EXECUTE AS USER = 'TurgidWizard';
SELECT USER_NAME() AS WhoAmI;
REVERT;
That code would allow me to impersonate you until I hit the REVERT call.
But, if you swap out calls to create_execution/start_execution you'll run into the same issue as trying to use a local sql server user runs into with using the methods in the SSISDB - it doesn't work. The methods in the SSISDB all run checks before they begin to ensure users have the correct access level and there isn't impersonation going on. Because once those methods start running, they themselves do impersonation so I guess that doesn't work well.
How can I run a package using tsql under a different account? I would start SSMS/sqlcmd under the credentials using RUNAS For example, the following will open a new command window as you.
runas /netonly /user:corpdomain.com\turgiwizard "cmd"
From there, things I do will be under the aegis of your user so I could run sqlcmd calls like
sqlcmd -S TheServer -d SSISDB -Q "EXECUTE catalog.create_execution ...;"
Mouse click will be Ctrl+Shift+right click executable.
Your SSMS install location is version dependent but try various ten digit increments of 140 in the following path
C:\Program Files (x86)\Microsoft SQL Server\140\Tools\Binn\ManagementStudio\Ssms.exe
The downside for me with regard to runas is that I could not automate getting my credentials passed into it. I've seen articles about use auto hot key and such but never had any luck with it.
Cleanest/easiest approach for something that needs to run regularly is to use sql agent with a proxy, or you could use Windows Task Scheduler and create it as the target user. One off executions, I'd likely use the runas approach.

Related

SQL Server Job - RunAs for T-SQL

I am trying to create make a user Credential appear in RunAs when I select T-SQL as my job step. However, the user account didn't appear.
Following the steps here, I managed to create RunAs but when I select T-SQL, it didn't show up.
Create Credentials for our Windows Service Account
https://learn.microsoft.com/en-us/sql/relational-databases/security/authentication-access/create-a-credential?view=sql-server-ver15
Assign Job Run As at Step Level.
https://learn.microsoft.com/en-us/sql/ssms/agent/configure-a-user-to-create-and-manage-sql-server-agent-jobs?view=sql-server-ver15
Can't find any T-SQL in the subsystem
https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-grant-proxy-to-subsystem-transact-sql?view=sql-server-ver15
Any ideas on how I can get RunAs appear in T-SQL ? Under Proxies, how can I add new SubSystem ?
Thanks.
I don't believe you can add subsystems to the list of Proxies.
SQL Agent hasn't really had any love in quite sometime, so while Run As appears as a dropdown option when you first create a step with the default T-SQL command type, if you cycle to something else and then back to T-SQL you will see Run As is no longer an option (it's grayed out).
This means T-SQL will be executed as the Service Account that the Agent service runs under...
...Unless you impersonate another user!

alternative to xp_cmdshell bcp?

Is there an alternative to xp_cmdshell BCP to write to a file from MSSQL?
Some context: This is to be built into a stored procedure called by an external program. I do not have the luxury to work through executable files, export functions of ssms, or any such things which require more than the calling of this stored procedure.
The reason; there's a lot of odd stuff on this server to do with user rights, and I'm not the SA. I cannot create the ##xp_cmdshell_proxy_account## (let alone assign credentials to it), and xp_cmdshell 'whoami' returns a user noone has ever seen or heard from. I've tried creating a new user based on an existing windows user and granting xp_cmdshell execute rights to it, but this still did nothing. I'm not sure if I don't have the rights or if it's something else.
So long story short, I'm fed up with trying to get this to work on this environment and am looking for an alternative. Is there one?
Write a SQL Agent Job and kick it off with sp_start_job. You can control the identity the job uses with a SQL Agent Proxy.
Or write an SSIS package, deploy it to the SSIS Catalog and run it from your stored procedure.

Executing SSRS report via a console application though a SQL Server Agent job

I have a SSRS solution that contains 20 reports all of which utilise a shared data source called "DataWarehouse". This datasource has been configured to use Windows Authentication. These reports have been deployed to a server.
I have a requirement where I need to be able to automatically run these reports once a data warehouse has completed loading overnight. Sometimes the warehouse load might take 5 hrs, sometimes it might take 10 and so I don't want schedule these reports at a particular time using reporting services, I want the warehouse load to determine when its done and trigger the reports.
Now, I have a mechanism to do this:
I have written a c# console application that accepts a report name and a file path which runs the report and saves it do wherever it needs to.
I have an SSIS package that executes the console application from (i). I use an SSIS package because the DBA where I work will not enable xp_cmdshell.
I have an agent job that runs the SSIS package when the warehouse load completes.
Now if I run the SSIS package on my local machine (as me) the package executes successfully and the report is generated and saved. When I deploy the SSIS package to the server and try and run it through the agent job it fails with the following error:
System.Web.Services.Protocols.SoapException: The permissions granted to user 'NT SERVICE\SQLSERVERAGENT' are insufficient for performing this operation. ---> Microsoft.ReportingServices.Diagnostics.Utilities.AccessDeniedException: The permissions granted to user 'NT SERVICE\SQLSERVERAGENT' are insufficient for performing this operation.
at Microsoft.ReportingServices.Library.ReportExecution2005Impl.LoadReport (String Report, String HistoryID, ExecutionInfo2& executionInfo)
at Microsoft.ReportingServices.WebServer.ReportExecutionService.LoadReport (String Report, String HistoryID, ExecutionInfo& executionInfo)
My initial guess was that this means the SSIS job gets executed as 'NT SERVICE\SQLSERVERAGENT' and this user does not have access to run reports on the report server. So I jumped on to the report server and tried adding NT SERVICE\SQLSERVERAGENT as a user who could run reports but I was still getting errors. Can anybody help me figure how I can get this working?
Thanks
This will help you execute the SSIS package in the command prompt, and you can run the package on the server in scheduled tasks from the batch file (you may need special permissions to run a batch file in scheduled tasks). What you will want to do is create a windows batch file to allow you to automatically run the SSIS package via Command Prompt and you will need to use Dtexec. Here is what your batch file will look like:
#ECHO OFF
Some comment about what the package is doing
Dtexec /f "C:\some\file\path\YourPackage.dtsx
Then once you save the notepad as a windows batch file you will be able to open the batch file and it will run your package in the Command Prompt. I hope this helps
I edited the console application to connect to the SSRS server as a specific user. I've added what I did below incase its useful to somebody else.
To do this I created a file called account.config which just contained the username on the first line and password on the secondline:
MyUser
MyPassword
Then in my console application I have the following code:
// Read in the config file and add the lines to a list
List<string> accountDetails = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "account.config")).ToList();
ReportExecutionService myReportExecutionService = new ReportExecutionService();
// Add the credentials
// accountDetails[0] is the username, accountDetails[1] is the password
myReportExecutionService.Credentials = new NetworkCredential(accountDetails[0], accountDetails[1]);

Run an SSIS package remotely and programatically

Problem
I have developed an SSIS package for an ETL process, which I have deployed successfully to a remote server. I have windows and SQL logins for this server, but not admin. The data that this ETL process loads is generated on a different machine on a different domain early in the morning each day (i.e. before I get to work) and needs to be automatically loaded after the data generation process as soon as possible.
Currently, I manually run the ETL package in SSMS, and authenticate this by spoofing the windows user credentials on the remote server by launching SSMS with runas.exe. This is currently okay since we are in early development, but this is obviously not an acceptable solution in production. Hence, I would like to automate this process, since a) the data is extremely time sensitive and b) manually running this process is a PITA.
How should I go about automating execution of the ETL package such that:
Execution happens immediately after the data is available, and
No user input is required from me e.g. to enter passwords?
Attempted solutions
Scheduling a SQL server agent job on a schedule is not an option, because of the time sensitivity. (Also my sysadmin seems to have not enabled/disabled the SQL server agent)
Continuing to use runas.exe is not an option either, as the /netonly flag, which is required, and the /savecred flag, which would prevent the need for manual password entry, are mutually exclusive.
sqlcmd.exe can be scripted to run with a SQL user and password (bad practice putting passwords in plain text, I know) but then running a stored procedure that calls the SSIS package fails, as windows authentication is required to run the package.
I would strongly advice you to ask for working SQL Agent and create an Agent Job to run the package. This way has a lot of advantages:
Native Windows user credentials management with proxy accounts
You can configure specific values for package/project parameters, connection managers via SSMS interface
You can use environment references of SSIS 2012 and above, and manage it via SSMS as well
Job can be started on schedule or manually from SQL command. Thus you can automate package start.
In a nutshell - it is much easier to manage and you do not disclose user credentials needed to run the package - you might even do not know it.
For the alternative - you can try PsExec from SysInternals tools. It allows to start program on another computer explicitly specifying username and password as psexec \\server -u user -p password .... However, I would opt against it.

is it possible execute a perl script with admin rights or as a specific user?

I'm writing a perl script in which I've to shutdown my mssql server ,do some operation and then I've to restart it.I know 1 way is to use netstat to stopt the service but I cann't use that. So I tried installing DBI and DBD::ODBC module.
More info here :Shutdown MSSQL server from perl script DBI
But when I trying to shutdown my server using this command
$dbh->prepare("SHUTDOWN WITH NOWAIT ");
It's not working for me :
I got this response from the community
SHUTDOWN permissions are assigned to members of the sysadmin and serveradmin fixed server roles, and they are not transferable. I'd consider it unlike(hopefully) that perl is run with this rights.
So please tell me is there a way to run the above command as these users ? or what can I do other than this . Note that I have a constraint tha tI cann't simply stop it as windows service.
If the scripts are executed through a web browser then the user executing the scripts will be defined by the web server. It will probably not be a good idea to fiddle with this user. Just leave things as they are.
What you can do is to create a Perl script that is being run by a privileged user on a consistent basis with CRON.
This script being run by CRON can check for specific content like a file which has been written by a script where the user executing the script has lesser privileges.
So the way it could work is as follows:
You execute browser.cgi through a browser to do a specific task.
browser.cgi writes instructions to a file.
Every 1 minute priveleged.cgi executes via CRON. (The root user could execute priveleged.cgi)
priveleged.cgi reads the file browser.cgi has written for instructions and starts and stops services according to the instructions.

Resources