列出SSIS包中所有“执行SQL任务”的SqlStatementSource

时间:2012-04-18 02:41:02

标签: xml powershell ssis

我想在SSIS包中列出所有“执行SQL任务”的SqlStatementSource。通过引用相关,它显示SQLPSX的ssis包可能有助于解决此任务。 但是,当我尝试执行以下过程时:

import-module SSIS
$package = Get-ISPackage -path "xxx.dtsx"

我的powershell返回错误消息:

“无法删除包含错误0xC0014037的程序包保护”程序包已使用密码加密。密码未指定或不正确。“。这发生在CPackage :: LoadFromXML方法中。”

它显示我应该导入密码来解密包以检索数据,但是我应该在哪里输入密码?或者我有什么其他方便的解决方案来解决这个问题。

最佳, 大卫

4 个答案:

答案 0 :(得分:1)

不是说这是最好的解决方案,而是要尝试的东西。而不是试图通过SSIS获取信息,为什么不通过文件本身。 DTSX文件是XML格式,PowerShell可以很好地处理这些类型的文件。

我在我的一个dtsx文件上试过这个并且能够返回信息:


[xml]$package = Get-Content C:\Myfile.dtsx
$package.Executable.Executable | 
   Select -ExpandProperty ObjectData | 
      Select -ExpandProperty SqlTaskData | 
         Select SqlStatementSource

由于某种原因,我收到InvalidArgument错误,说它无法找到属性“SqlTask​​Data”。我相信这是因为它击中了我在包中的数据流任务,它没有属性/属性。这就是我的意思,因为它可能不是完美的解决方案,所以我不提供任何保证。有一点需要指出的是,我没有将我的软件包设置为通过密码加密。

<强>更新

您可以尝试使用SQLPSX that include a library进行SSIS。

答案 1 :(得分:1)

我没有安装SQLPSX,但我可以告诉你如何在没有它的情况下解密包。重要的是将包密码分配给应用程序,以便它可以解密包。

给定这样的包,每个执行sql任务都有一个SELECT N AS test语句 execute sql everwhere

以下脚本将解密保存为EncryptAllWithPassword的包,并具有各种任务,其中一些嵌入在各种容器中。无论如何,它都不是美丽的PowerShell,但它可以完成任务。

[Reflection.Assembly]::LoadWithPartialName("Microsoft.SQLServer.ManagedDTS") | out-null

Function ProcessExecutable
{
    param
    (
    [Microsoft.SqlServer.Dts.Runtime.Executable]$item
    )

    $t = $item.GetType()
    if ($t.Name -eq "TaskHost")
    {
        #$th = New-Object Microsoft.SqlServer.Dts.Runtime.Task
        #$es = New-Object Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ExecuteSQLTask
        $th = [Microsoft.SqlServer.Dts.Runtime.TaskHost]$item
        try
        {
            $es = [Microsoft.SqlServer.Dts.Tasks.ExecuteSQLTask.ExecuteSQLTask]$th.InnerObject
            Write-Host($es.SqlStatementSource)
        }
        catch
        {
        }
    }
    elseif ($t.Name -eq "Sequence")
    {
        $sequence = [Microsoft.SqlServer.Dts.Runtime.Sequence]$item
        foreach ($subitem in $sequence.Executables)
        {
            ProcessExecutable $subitem
        }
    }
    elseif ($t.Name -eq "ForLoop")
    {
        $sequence = [Microsoft.SqlServer.Dts.Runtime.ForLoop]$item
        foreach ($subitem in $sequence.Executables)
        {
            ProcessExecutable $subitem
        }
    }
    elseif ($t.Name -eq "ForEachLoop")
    {
        $sequence = [Microsoft.SqlServer.Dts.Runtime.ForEachLoop]$item
        foreach ($subitem in $sequence.Executables)
        {
            ProcessExecutable $subitem
        }
    }    
}


$app = New-Object Microsoft.SqlServer.Dts.Runtime.Application
$app.PackagePassword = "password"
$packagePath = "C:\sandbox\SSISHackAndSlash\SSISHackAndSlash\Encrypted.dtsx"
$package = $app.LoadPackage($packagePath, $null)

foreach($item in $package.Executables)
{
    ProcessExecutable $item
}

输出继电器

SELECT 1 AS test
SELECT 2 As test
SELECT 5 AS test
SELECT 4 AS test
SELECT 3 AS test

答案 2 :(得分:0)

您通常使用DTEXEC来运行加密包,如下所示:

DTExec.exe /FILE "C:\Package1.dtsx" /DECRYPT password@1.

/ FILE表示包在文件系统上。您可以将/ SQL用于SQl Server数据库上的包,如果它位于文件存储

,则使用/ DT

此外,如果您在BIDS上打开包,则系统会提示您输入密码

答案 3 :(得分:0)

在搜索了有关如何列出所有SSIS组件的在线信息后,我发现编写C#程序可能是解决问题的最佳解决方案。因此,下面我写了一个VS 2008兼容程序来完成我的任务。 下面编写了将列出所有SSIS相关组件的程序,并将结果写入excel文件。该解决方案将为您节省大量时间点击VS 2008中显示的组件以逐个查看组件属性。由于我不是C#专家,因此该程序可能编码不好。但至少它有效!

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Excel = Microsoft.Office.Interop.Excel;
using System.Reflection;
using Microsoft.SqlServer.Dts.Runtime;
using Microsoft.SqlServer.Dts.Pipeline;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;


namespace Project1
{
    public class SSISFinder
    {

        public static void Main()
        {
            // Set ssis app
            Microsoft.SqlServer.Dts.Runtime.Application ssisApp = new Microsoft.SqlServer.Dts.Runtime.Application();
            ssisApp.PackagePassword = "admin_monkey4ccc";

            // Loading dtsx package
            Package pkg = ssisApp.LoadPackage("D:\\SummaryETL.dtsx", null);

            // Open Excel Sheet
            Excel.Application oXL = new Excel.Application();
            Excel.Workbook oWB;
            Excel.Worksheet oSheet;            
            string fileName = "D:\\test.xls";
            oWB = oXL.Workbooks.Add(Missing.Value);
            oSheet = (Excel.Worksheet)oWB.ActiveSheet;

            // List data flow package
            List<DtsContainer> containers = FindExecutablesByType((IDTSSequence)pkg, "PIPELINE");
            int counter = 1;

            foreach (DtsContainer exec in containers)
            {
                TaskHost th = exec as TaskHost;
                MainPipe pipe = (MainPipe)th.InnerObject;

                foreach (IDTSComponentMetaData100 comp in pipe.ComponentMetaDataCollection)
              {
                  if (comp.Description == "OLE DB Source")
                  {
                      oSheet.Cells[counter, 1] = comp.Description;
                      oSheet.Cells[counter, 2] = th.Properties["Name"].GetValue(th).ToString();
                      oSheet.Cells[counter, 3] = comp.Name;                      
                      oSheet.Cells[counter, 4] = comp.CustomPropertyCollection["SqlCommand"].Value;
                      Console.WriteLine("  Component Name = " + comp.Name);
                      counter++;
                  }
                  else if (comp.Description == "OLE DB Destination")
                  {
                      oSheet.Cells[counter, 1] = comp.Description;
                      oSheet.Cells[counter, 2] = th.Properties["Name"].GetValue(th).ToString();
                      oSheet.Cells[counter, 3] = comp.Name;                      
                      oSheet.Cells[counter, 4] = comp.CustomPropertyCollection["OpenRowset"].Value;
                      Console.WriteLine("  Component Name = " + comp.Name);
                      counter++;
                  }
              }

            }

            oWB.SaveAs(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
    Excel.XlSaveAsAccessMode.xlShared, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            oWB = null;

            oXL.Quit();
            oXL = null;

        }

        static List<DtsContainer> FindExecutablesByType(IDTSSequence sequence, string typeName)
        {
            string typeNameUpper = typeName.ToUpper();
            List<DtsContainer> matchingExecutable = new List<DtsContainer>();
            foreach (Executable e in sequence.Executables)
            {
                if (e.GetType().ToString().ToUpper().Contains(typeNameUpper))
                {


                    matchingExecutable.Add((DtsContainer)e);
                }
                if (e is TaskHost)
                {
                    TaskHost taskHost = (TaskHost)e;

                    if ((typeNameUpper.Contains("DATA FLOW")
                                || typeNameUpper.Contains("DATAFLOW")
                                || typeNameUpper.Contains("MAINPIPE")
                                || typeNameUpper.Contains("PIPELINE")
                                ) && taskHost.InnerObject is IDTSPipeline100
                       )
                    {
                        matchingExecutable.Add((DtsContainer)e);
                    }
                    else if (taskHost.InnerObject.GetType().ToString().ToUpper().Contains(typeNameUpper))
                    {
                        matchingExecutable.Add((DtsContainer)e);
                    }
                }
                if (e is IDTSSequence)
                {
                    matchingExecutable.AddRange(FindExecutablesByType((IDTSSequence)e, typeNameUpper));
                }
            }
            return matchingExecutable;
        }
    }
}