Why would a job call a batch file with dtexec.exe instead of just calling the SSIS package directly? I've inherited a SQL 2012 server with a number of jobs that call SSIS packages. 

Instead of the more obvious solution (calling them directly from a "SSIS Package" job step), these jobs use a CmdExec step to call a batch file, which contains a single line:

dtexec.exe /FILE "D:\path\PackageName.dtsx"


Why would the previous DBA have done this? Permissions? Personal preference? 

And why the double hop? If you wanted to use dtexec.exe, couldn't you just put that command directly in the job step?

I know there can sometimes be an issue with 32-bit vs 64-bit dependencies in packages, if there are MS Office components used in the package. How can I figure out if that's what is going on here?
Before SQL Server 2012 and the project deployment model, the only way to run an SSIS package from the context of SSMS was either a SQL Agent job or xp_cmdshell. 

SQL Agent is calling DTEXEC.exe as it has a special parameter /X86 that is only respected when passed from SQL Agent. Otherwise, you'll want to specify the explicit path to your dtexec.exe to control whether it's a 32 vs 64 bit operation. 


  This option is only used by SQL Server Agent. This option is ignored if you run the dtexec utility at the command prompt.


Option A

That could be a reason why they use a batch file to kick off the SSIS packages. They want to ensure the correct dtexec is being used to run the package. Shamless self promotion on determining whether it's 32 vs 64 http://billfellows.blogspot.com/2015/02/is-my-ssis-package-running-in-32-or-64.html Also https://stackoverflow.com/a/13092260/181965

Option B

Another reason I've seen batch scripts used as they didn't use configuration (file, table, whatever) but wanted to get a different behaviour per environment. Assuming I had a ConnectionString variable in my SSIS package and the design time value was Dev but now I'm in production, one way to change that value is to always set the property when we run, psuedocode is

dtexec.exe /file MyPackage /SET ConnectionString;Prod


If I'm lazy, I could use the same job definition of across all my environments but change the contents of the /SET value as need be. I don't see it being that useful but some people view tasks with varying degrees of difficulty.

The above doesn't have to be just for /SET. They can set logging or anything else up really. Maybe they want to log the output to an execution log because they didn't know SSIS supports that natively. There might be /REP EWIP &gt; CurrentRun.txt in the dev batch file but production only have /REP E

Option C

Another reason would be the illusion of security. At a former employer, they used the batch script approach to run SSIS packages. Developers were not granted access to SQL Agent. xp_cmdshell - oh hell no to that. Nor could we be trusted to log onto the pre-production boxes (Load, stage, UAT) but we still had the need to run SSIS packages on demand. 

So, after a few weeks of submitting urgent request tickets every time the packages need run, they created a pair of stored procedures that provided a gated package execution experience. RunSSISPackage and RunSSISPackage32 which would take the name of the package to be run. For every package we created, they would create a batch script that ran it. Lots of busy work for all parties but at the time it was the only way they were letting us run packages. The procedures used xp_cmdshell and EXECUTE AS to allow us to run the packages as they would be - with full sysadmin rights. By the way, when you allow people to deploy SSIS packages without auditing, they could add an Execute SQL Task in there that adds the developer group into the sysadmin role. I think. Maybe. Hypothetically.

Option D

Not SQL Agent. I've seen other scheduling tools used at clients that weren't SQL Agent. The support for SSIS specifically has been spotty but they've all supported batch files so perhaps you have some Enterprise scheduler that wasn't compatible with SSIS.

Otherwise, if it's just dtexec.exe /file foo.dtsx ... I got nothing