通过Powershell进行SSIS项目部署 - 配置为使用Env变量的项目参数

时间:2018-03-02 20:26:59

标签: powershell deployment ssis

虽然我是Stackoverflow的长期用户,但这是我的第一个问题 我正在通过Powershell部署SSIS项目。我是高级.NET开发人员而不是DBA。我对SSIS包的部署知之甚少。

我已经通过几个博客/教程来获得我现在的理解,但仍然有些不妥。

我相信我正确设置了我的SSIS包。根据我的理解,连接管理器设置得恰当。我在下面发布了我的连接管理器的快照。请注意&#f; fx(项目)'在连接管理器描述旁边。

Connection Manager Snapshot

我有两个Powershell脚本。一个部署包,另一个设置环境变量和项目参数 我遇到的问题与项目执行时未选择的环境有关,尽管我建立了关系。因此我的项目参数看不到我的环境变量。

执行包时,我收到以下错误:

  

参数" FlatFileConnectionManager_ConnectionString"配置为使用环境变量,但未选择任何环境。检查"环境"复选框并指定要使用的环境,或指定参数的文字值。

     

参数" LocalHostAdventureWorksDW2012_ConnectionString"配置为使用环境变量,但未选择任何环境。检查"环境"复选框并指定要使用的环境,或指定参数的文字值。

Powershell部署脚本:

Add-Type -AssemblyName "Microsoft.SqlServer.Management.IntegrationServices, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"

$sqlInstance = "xxxxxxx"
$sqlConnectionString = "Data Source=$sqlInstance;Initial Catalog=master;Integrated Security=SSPI"
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection $sqlConnectionString
$isNamespace = "Microsoft.SqlServer.Management.IntegrationServices"

$catalogPwd = "xxxxxx"


$ssisServer = New-Object $ISNamespace".IntegrationServices" $sqlConnection


if ($ssisServer.Catalogs.Count -gt 0)             
{             
    $ssisServer.Catalogs["SSISDB"].Drop()             
}            


$catalog = New-Object $isNamespace".Catalog" ($ssisServer, "SSISDB" ,$catalogPwd  )
$catalog.Create()

$ssisCatalog = $ssisServer.Catalogs["SSISDB"]

$ssisFolderName = "PowerShell Demos"
$ssisFolderDescription = "Created with PowerShell"
$ssisFolder = New-Object Microsoft.SqlServer.Management.IntegrationServices.CatalogFolder($ssisCatalog, $ssisFolderName, $ssisFolderDescription)
$ssisFolder.Create()

$ssisProjectName = "TestProject"
[byte[]] $ssisProjectFile = [System.IO.File]::ReadAllBytes("C:\Users\xxxxx\Documents\Visual Studio 2010\Projects\DeployTest\TestProject\bin\Development\TestProject.ispac")
$ssisFolder.DeployProject($ssisProjectName, $ssisProjectFile)

Powershell环境和项目参数设置脚本:

Add-Type -AssemblyName "Microsoft.SqlServer.Management.IntegrationServices, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91"

$sqlInstance = "xxxxxxx"
$sqlConnectionString = "Data Source=$sqlInstance;Initial Catalog=master;Integrated Security=SSPI"
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection $sqlConnectionString
$ssisCatalog = "SSISDB"
$isNamespace = "Microsoft.SqlServer.Management.IntegrationServices"

$environmentName = "UPMVariables"
$projectName = "TestProject"
$folderName = "PowerShell Demos"

$integrationServices = New-Object "$isNamespace.IntegrationServices" $sqlConnection

$catalog = $integrationServices.Catalogs[$ssisCatalog]

$folder = $catalog.Folders.Item($folderName)

$environment = $folder.Environments[$environmentName]

if (!$environment)
{
    Write-Host "Creating environment ..." 
    $environment = New-Object "$isNamespace.EnvironmentInfo" ($folder, $environmentName, "testDescription")
    $environment.Create()             
}

# Adding variable to our environment
# Constructor args: variable name, type, default value, sensitivity, description

Write-Host "Adding environment variables ..." 
$eFlatFileConnectonString = $environment.Variables.Item("LocalHostAdventureWorksDW2012_ConnectionString")
if (!$eFlatFileConnectonString)
{

    $environment.Variables.Add("FlatFileConnectionManager_ConnectionString", [System.TypeCode]::String, "C:\newDestination\test.txt", $false, "FlatFile ConnectionString")

    $environment.Alter()

    $eFlatFileConnectonString = $environment.Variables.Item("LocalHostAdventureWorksDW2012_ConnectionString")        

}

$eAdvWorksConnectionString = $environment.Variables.Item("LocalHostAdventureWorksDW2012_ConnectionString")
if (!$eAdvWorksConnectionString)
{

     $environment.Variables.Add( "LocalHostAdventureWorksDW2012_ConnectionString", 
    [System.TypeCode]::String, "Data Source=xxxxxxx;Initial Catalog=AdventureWorksDW2012;Provider=SQLNCLI11.1;User Id=xxxx;Password=xxxxx;", $false, "LocalHostAdventureWorksDW2012 ConnectionString")

    $environment.Alter()

    $eAdvWorksConnectionString = $environment.Variables.Item("LocalHostAdventureWorksDW2012_ConnectionString")
} 


$project = $folder.Projects[$projectName]

$ref = $project.References.Item($environmentName, $folderName)

if (!$ref)
{
    # making project refer to this environment
    Write-Host "Adding environment reference to project ..."
    $project.References.Add($environmentName, $folder.Name)
    $project.Alter() 
}

$projectVariable = $project.Parameters[$eAdvWorksConnectionString.Name]
$project.Parameters[$eAdvWorksConnectionString.Name].Set("Referenced", $eAdvWorksConnectionString.Name) 

$projectVariable = $project.Parameters[$eFlatFileConnectonString.Name]           
$project.Parameters[$eFlatFileConnectonString.Name].Set("Referenced", $eFlatFileConnectonString.Name)            
$project.Alter()

我希望Stackoverflow上有人了解导致此问题的原因。提前感谢您的帮助和最好的问候!

*******澄清问题......更多信息*******

我了解如何手动部署,创建Sql Server环境变量并配置Project参数以通过SSMS引用Sql Server环境变量。我试图通过Powershell脚本了解如何这样做,无需人工干预。而且,虽然我可能会弄错,但我相信根据我所做的研究,可以自动执行此部署/设置。

当我的问题中包含的脚本执行时,会成功执行以下操作。

  • SSIS项目成功部署到SQL Server。请参阅以下快照。

    SSMS - Project Deployed

  • 脚本运行后会出现环境变量。通过右键单击环境变量对象可以看到环境变量,在本例中标题为“UPMVariables'”。由于Powershell脚本的以下部分,这些变量存在。

    $ environment.Variables.Add(     " LocalHostAdventureWorksDW2012_ConnectionString&#34 ;,     [System.TypeCode] :: String," Data Source = xxxxxxxx; Initial Catalog = AdventureWorksDW2012; Provider = SQLNCLI11.1; User Id = xxxx; Password = xxxxxx;",$ false," LocalHostAdventureWorksDW2012 ConnectionString")

    $ environment.Variables.Add(" FlatFileConnectionManager_ConnectionString",[System.TypeCode] :: String," C:\ newDestination \ test.txt",$ false,&#34 ; FlatFile ConnectionString")

    $ environment.Alter() $ eAdvWorksConnectionString = $ environment.Variables.Item(" LocalHostAdventureWorksDW2012_ConnectionString") $ eFlatFileConnectonString = $ environment.Variables.Item(" FlatFileConnectionManager_ConnectionString")

    Environment Variable Snapshot

  • 项目参数在部署后应该存在。这些项目参数是在创建SSIS项目期间创建的。

    Project Parameters visible in SSMS

  • 应该通过我在问题中包含的Powershell脚本中的以下代码建立Sql Server环境变量和SSIS项目之间的关系。

    $ project.References.Add($ environmentName,$ folder.Name)

    $ project.Alter()

  • 以下是我提问的挑战和原因。当您右键单击SSIS包并单击执行时(请参阅下面的第一张图片),必须手动检查环境变量复选框在包之前可以使用环境变量值。

    SSMS - Execute Package

    Environment Variable vs Parameter Dialogue

  • 手动单击“环境变量”复选框后,Sql Server环境变量可用于SSIS项目参数。这是脚本未建立的步骤。

    Environment Variable And Parameter Relationship Manually Established

  • 这是我尝试自动执行的步骤,因为手动检查无法管理环境变量复选框。这些SSIS包通过作业调度运行。

  • 顺便说一下,我读到的其中一个教程说你可以生成一个 用于建立Project之间关系的T-SQL脚本 单击参数和Sql Server环境变量 '执行包'左上角的脚本按钮对话。 请查看脚本的快照和“执行包”。 对话如下。我们可以从VSTS执行T-SQL脚本 最后一步,但不幸的是,运行此脚本没有导致 正在检查复选框。

TSQL

Declare @execution_id bigint

EXEC [SSISDB].[catalog].[create_execution] @package_name=N'Package.dtsx', 
@execution_id=@execution_id OUTPUT, @folder_name=N'PowerShell Demos', 
@project_name=N'TestProject', @use32bitruntime=False, @reference_id=1
Select @execution_id

DECLARE @var0 smallint = 1
EXEC [SSISDB].[catalog].[set_execution_parameter_value] @execution_id,  
@object_type=50, @parameter_name=N'LOGGING_LEVEL', @parameter_value=@var0

EXEC [SSISDB].[catalog].[start_execution] @execution_id
GO

Execute Dialogue Script Button

我希望这些额外的信息能够更深入地了解我所面临的问题。我真诚地感谢任何帮助!谢谢!

******更新03/06/2018 ******

可能是我的期望是错误的?我的理解是,我应该能够:

  1. 在SSDT(2012)中创建我的SSIS项目/包。这包括:

    一个。创建数据流任务

    B中。如果需要,创建连接管理器

    ℃。使用默认值设置参数...并在需要时将其标记为必需/敏感

    d。确保创建的参数的范围正确(即项目或包级别)

  2. 通过Powershell脚本部署SSIS包。这包括:

    一个。包部署到SQL Server

    B中。创建SQL Server环境变量

    ℃。在项目文件夹和Sql Server环境变量之间创建关系

    d。在创建的SQL Server环境变量和在SSDT

  3. 中创建的范围参数之间创建关系
  4. 通过作业调度程序运行程序包而不关心项目参数

  5. 我的挑战是创建SQL Server环境变量和范围参数之间的关系。 回顾昨天发布的T-SQL。

    Declare @execution_id bigint
    
    EXEC [SSISDB].[catalog].[create_execution] @package_name=N'Package.dtsx', 
    @execution_id=@execution_id OUTPUT, @folder_name=N'PowerShell Demos', 
    @project_name=N'TestProject', @use32bitruntime=False, @reference_id=1
    Select @execution_id
    
    DECLARE @var0 smallint = 1
    EXEC [SSISDB].[catalog].[set_execution_parameter_value] @execution_id,  
    @object_type=50, @parameter_name=N'LOGGING_LEVEL', @parameter_value=@var0
    
    EXEC [SSISDB].[catalog].[start_execution] @execution_id
    GO
    

    这是为包执行设置日志记录然后执行包。好东西,但它没有设置使用的范围参数 SQL Server环境变量 我在上一篇文章中发现的是一个T-SQL脚本,它首先在执行包之前设置参数。

    Execute Package T-SQL

    我知道你必须将object_type设置为30(包模式)或20(项目模式)执行。这很简单。

    您是否必须在执行时添加参数和值,如下所示?

    @parameter_name=N'pSourceDir'
    @parameter_value='c:\Temp'
    

    考虑到我们在SSDT中使用默认值创建范围参数,这似乎是多余的。然后Sql Server环境变量带值。这对我来说没有意义,因此我感到困惑。

    我希望有人能为我澄清这一点。 再次感谢Stackoverflow!

3 个答案:

答案 0 :(得分:1)

早上好Stackoverflow, 我昨天找到了问题的答案。它与环境变量无关,也与T-SQL无关。问题是Powershell脚本中的以下声明。

$projectVariable = $project.Parameters[$eAdvWorksConnectionString.Name]
$project.Parameters[$eAdvWorksConnectionString.Name].Set("Referenced", 
$eAdvWorksConnectionString.Name) 

$projectVariable = $project.Parameters[$eFlatFileConnectonString.Name]           

$project.Parameters[$eFlatFileConnectonString.Name].Set("Referenced", 
$eFlatFileConnectonString.Name)            
$project.Alter()

我认为上面的语句通过某种方式在Sql Server环境变量和项目参数之间建立了关系。我错了。令人困惑的部分是当脚本运行说某些事情不对时,我没有收到错误/反馈。这就是我联系Stackoverflow的原因。从未通过Powershell部署SSIS包,我对预期结果没有充分了解 上述方法建立项目参数,但不启用相应的Sql Server环境变量的使用,无需人工干预。 以下建立项目参数的方法确实可以在不需要人工干预的情况下使用Sql Server环境变量。

$projectVariable = $project.Parameters[$eAdvWorksConnectionString.Name]
$project.Parameters[$eAdvWorksConnectionString.Name].Set("Literal", 
$eAdvWorksConnectionString.value) 

$projectVariable = $project.Parameters[$eFlatFileConnectonString.Name] 
$project.Parameters[$eFlatFileConnectonString.Name].Set("Literal", 
$eFlatFileConnectonString.value)            
$project.Alter()

我在这里发布这些信息给其他正在尝试和我一样运动的人。 顺便说一下,我的初始问题中的Powershell脚本完美无误,除了我在这个答案中描述的异常。用我在本答案中描述的修正替换建立项目参数的方法。该脚本将部署SSIS包,建立项目参数和SQL Server环境变量之间的关系。然后,SSIS包可以在没有人工干预的情况下运行。 我希望这有助于未来的人。
感谢billinkc和postanote试图帮助...非常感谢! 最好的问候!

答案 1 :(得分:0)

在更多的情况下。如果你看到有关环境变量的事情尖叫,这在大多数情况下只意味着一些事情。

在Windows - 高级系统设置/环境变量中:

  1. 您尚未定义用户环境变量。
  2. 您尚未定义系统环境变量。
  3. 想想这就像试图运行Java的东西,没有先安装Java和设置JAVA_HOME系统变量而忘记将其添加到系统路径。您可以在脚本中手动或以编程方式执行此操作并预先暂存。

    [System.Environment]::SetEnvironmentVariable("EnvVarName", "EnvVarPath", "EnvVarTarget")
    
    https://msdn.microsoft.com/en-us/library/system.environment.setenvironmentvariable(v=vs.110).aspx
    
      

    参见这篇文章:

         

    SSIS包和配置表中的环境变量

         

    环境变量可以保存每台服务器上的服务器名称。   在配置管理器中,您将放置在环境的名称中   变量。环境变量不具有的值   传递给包的变量或连接。环境   variable保存服务器的名称。该值告诉包   在哪里查找配置表并读取配置   用于传递到包中的已配置值的表。

         

    您可以将环境变量视为指针   包。当您将包移动到另一个服务器时,它将寻找一个   环境变量。你的包裹在哪个服务器上并不重要   在跑。只要服务器具有名为的环境变量   正确的名称,它包含适当的服务器的名称,   包将正常运行。

         

    https://mikedavissql.com/2013/08/12/environment-variables-in-ssis-packages-and-configuration-tables

    另见这篇文章:

      

    Powershell错误设置SSIS包的环境变量   执行

         

    我的Powershell脚本执行SSIS包,但首先覆盖了一个   环境变量。 EnvironmentInfo对象上的Alter方法   失败并显示一般错误消息:"操作'更改'在对象上   [EnvironmentInfo [@Name =' MyVariable的']'执行期间失败。"

         

    我也尝试删除环境变量并更改   Project参数,但在Alter方法上收到相同的错误   项目对象。

         

    我怀疑这是1)使用32位版本的缺点   SQL Server 2012,或2)权限问题。

         

    我确保执行的Windows帐户具有完全权限   SSISDB数据库和SSIS目录项目以及子项   文件夹,环境等。

         

    Powershell error setting Environment variable for an SSIS package execution

    ****更新****

    IndyDev -

    由于我没有像我在评论中所说的那样使用SSIS部署环境,因此我回到了文档。这是一个SSIS特征交易,而不是PowerShell特有的任何内容。

      

    集成服务(SSIS)包和项目参数

         

    环境变量

         

    如果参数引用环境变量,则为文字值   从该变量通过指定的环境解析   引用并应用于参数。最后的文字参数   用于包执行的值称为   执行参数值。您为其指定环境参考   使用“执行”对话框执行

         

    <强> &GT;如果项目参数引用环境变量和   来自变量的文字值在执行时无法解析   使用设计值。未使用服务器值。

         

    https://docs.microsoft.com/en-us/sql/integration-services/integration-services-ssis-package-and-project-parameters

    还有一件事。 &#34;执行包时,必须手动单击环境变量复选框。&#34;,是否可以使用sendkeys与此对话框进行交互,尽管sendkeys可能有点挑剔。

    从我之前的SQL课程开始,我在SSIS主题上的注释显示......

    1. SSIS并不认为要知道使用哪种环境(即使 只存在一个)。所以,你想勾选方框并选择 正确的环境 - 运行包时总是如此 像这样点播。
    2. 您应该使用SQL代理作业来执行它,其中包含 job config,你看看这个方框。
    3. 在做环境部分时---

      1. 否则需要关闭并重新打开SSIS解决方案 环境变量不会反映到SSIS包中。
      2. 用户应具有管理员权限才能添加环境 变量

答案 2 :(得分:0)

您正在为部署,创建环境做所有事情。

这是您尝试运行生成错误的包的最后一步。

你有这个tsql

Declare @execution_id bigint

EXEC [SSISDB].[catalog].[create_execution] @package_name=N'Package.dtsx', 
@execution_id=@execution_id OUTPUT, @folder_name=N'PowerShell Demos', 
@project_name=N'TestProject', @use32bitruntime=False, @reference_id=1
Select @execution_id

DECLARE @var0 smallint = 1
EXEC [SSISDB].[catalog].[set_execution_parameter_value] @execution_id,  
@object_type=50, @parameter_name=N'LOGGING_LEVEL', @parameter_value=@var0

EXEC [SSISDB].[catalog].[start_execution] @execution_id

我们创建对项目/包的引用以供执行,并确定我们想要引用的环境(@reference_id = 1)

然后我们设置日志记录级别(set_execution_parameter_value)并运行它。剩下的是设置此执行的执行参数值以使用引用/环境值。

我没有方便提供那些set_execution_parameter_value的示例的项目,但您可以单击SSMS中的执行包向导,并在为这些连接管理器指定“使用环境值”后单击脚本到新窗口选项