通过PowerShell执行带环境引用的SSIS包时遇异常求助
问题:PowerShell执行SSIS包时触发类型加载异常
尝试通过PowerShell执行带有环境引用的SSIS包,编写的脚本如下:
$null = [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Management.IntegrationServices") $null = [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Management.Sdk.Sfc") $ConnectionString = "Data Source=" + $LocalSQLServer $SSISConnection = New-Object System.Data.SqlClient.SqlConnection $SSISConnection.ConnectionString = $ConnectionString $SSISConnection.Credential = $LocalSQLCredential $SSIS = New-Object Microsoft.SqlServer.Management.IntegrationServices.IntegrationServices $SSIS.Connection = New-Object Microsoft.SqlServer.Management.Sdk.Sfc.SqlStoreConnection $SSISConnection $SSISCatalog = $SSIS.Catalogs["SSISDB"] $SSISFolder = $SSISCatalog.Folders[$TargetFolderName] $SSISProject = $SSISFolder.Projects[$ProjectName] $SSISPackage = $SSISProject.Packages[$PackageName] $SSISEnvironmentReference = $SSISProject.References | Where-Object {$_.Name -eq $EnvironmentName} #Get the environment reference $SSISPackage.Execute("False", $SSISEnvironmentReference)
执行后抛出如下异常:
System.Management.Automation.MethodInvocationException:调用“Execute”方法传入2个参数时发生异常:“Microsoft.SqlServer.Management.IntegrationServices.PackageInfo的类型初始值设定项引发了异常。” ---> System.TypeInitializationException:Microsoft.SqlServer.Management.IntegrationServices.PackageInfo的类型初始值设定项引发了异常。 ---> System.TypeInitializationException:Microsoft.SqlServer.Diagnostics.STrace.STraceSource的类型初始值设定项引发了异常。 ---> System.TypeLoadException:无法从程序集“System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”中加载类型“Microsoft.SqlServer.Server.SqlContext”。 at Microsoft.SqlServer.Diagnostics.STrace.STraceSource..cctor() --- 内部异常堆栈跟踪结束 --- at Microsoft.SqlServer.Diagnostics.STrace.STraceSource.get_TraceSources() at Microsoft.SqlServer.Diagnostics.STrace.TraceContext..ctor(String eventSourceName, String eventContext, String eventSubcontext) at Microsoft.SqlServer.Diagnostics.STrace.TraceContext.GetTraceContext(String eventSourceName, String eventContext, String eventSubcontext) at Microsoft.SqlServer.Diagnostics.STrace.TraceContext.GetTraceContext(String eventSourceName, String eventContext) at Microsoft.SqlServer.Management.IntegrationServices.PackageInfo..cctor() --- 内部异常堆栈跟踪结束 --- at Microsoft.SqlServer.Management.IntegrationServices.PackageInfo.ScriptCreateExecution(Boolean use32RuntimeOn64, EnvironmentReference reference) at Microsoft.SqlServer.Management.IntegrationServices.PackageInfo.Execute(Boolean use32RuntimeOn64, EnvironmentReference reference, Collection`1 setValueParameters, Collection`1 propetyOverrideParameters) at CallSite.Target(Closure , CallSite , Object , String , Object ) --- 内部异常堆栈跟踪结束 --- at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception) at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame) at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame) at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
即使传入$null作为第二个参数,仍会出现相同错误。
原因分析与解决方案
错误根源
这个异常不是第二个参数直接导致的,核心问题是**.NET框架无法加载Microsoft.SqlServer.Server.SqlContext类型**——该类型属于SQL Server CLR集成组件,通常由以下原因引发:
- 使用了过时的程序集加载方式(
LoadWithPartialName),导致加载了不兼容的SSIS管理组件版本; - 缺少对应SQL Server版本的SMO(SQL Server Management Objects)和SSIS管理组件;
- .NET框架版本与SQL Server组件不匹配。
解决步骤
1. 替换程序集加载方式,指定正确版本的组件
LoadWithPartialName已被.NET废弃,无法精确控制加载的程序集版本。改用Add-Type指定对应SQL Server版本的组件路径:
# 替换150为你的SQL Server版本号(2016=130,2019=150,2022=160) Add-Type -Path "C:\Program Files\Microsoft SQL Server\150\SDK\Assemblies\Microsoft.SqlServer.Management.IntegrationServices.dll" Add-Type -Path "C:\Program Files\Microsoft SQL Server\150\SDK\Assemblies\Microsoft.SqlServer.Management.Sdk.Sfc.dll"
2. 安装必要的SQL Server组件
确保运行PowerShell的机器安装了对应版本的:
- SQL Server Management Objects (SMO)
- Integration Services管理工具
可通过SQL Server安装介质或微软官网下载对应版本的客户端工具包。
3. 验证.NET框架版本兼容性
SQL Server 2017及以后版本要求使用.NET Framework 4.7.2或更高版本,检查并升级.NET框架至对应版本。
4. 替代方案:直接调用SSISDB存储过程执行包
如果上述方法无效,可以绕过SSIS管理对象,直接用Invoke-SqlCmd执行SSISDB的系统存储过程启动包:
$executionCmd = @" DECLARE @execution_id BIGINT; EXEC [SSISDB].[catalog].[create_execution] @package_name = N'$PackageName', @execution_id = @execution_id OUTPUT, @folder_name = N'$TargetFolderName', @project_name = N'$ProjectName', @use32bitruntime = 0, @reference_id = ( SELECT reference_id FROM [SSISDB].[catalog].[environment_references] WHERE environment_name = N'$EnvironmentName' AND project_id = ( SELECT project_id FROM [SSISDB].[catalog].[projects] WHERE project_name = N'$ProjectName' AND folder_id = ( SELECT folder_id FROM [SSISDB].[catalog].[folders] WHERE folder_name = N'$TargetFolderName' ) ) ); EXEC [SSISDB].[catalog].[start_execution] @execution_id; "@ Invoke-SqlCmd -ServerInstance $LocalSQLServer -Credential $LocalSQLCredential -Query $executionCmd
内容的提问来源于stack exchange,提问作者HiperiX
相关产品推荐
相关产品推荐

