我想列出所有的SqlStatementSource在SSIS包“执行SQL任务”。 通过参考相关的,它显示SQLPSX的SSIS包可能有助于解决这个任务。 然而,当我尝试做以下步骤:
import-module SSIS
$package = Get-ISPackage -path "xxx.dtsx"
我的PowerShell返回的错误信息:
“无法移除封装保护,错误0xC0014037”包进行加密密码。 密码未指定,或者是不正确的。“这发生在在CPackage :: LoadFromXML方法。”
它表明我应该输入密码解密包来获取数据,但在那里我应该把密码? 或者有没有其他方便的解决方案为我解决这个问题。
最好,大卫
您通常使用DTEXEC运行加密的包是这样的:
DTExec.exe /FILE "C:\Package1.dtsx" /DECRYPT password@1.
/ FILE意味着程序包是在文件系统上。 你可以使用/ SQL到SQL Server数据库或/ DT上的包,如果它是在文件存储
此外,如果你打开出价的包,你应该提示输入密码
不,这是最好的解决办法,但一些尝试。 而不是试图去通过SSIS获得为什么不通过文件本身去的信息。 DTSX文件是XML格式和PowerShell起到很好用这些类型的文件。
我想这对我的DTSX文件中的一个,并能返回信息:
[xml]$package = Get-Content C:\Myfile.dtsx
$package.Executable.Executable |
Select -ExpandProperty ObjectData |
Select -ExpandProperty SqlTaskData |
Select SqlStatementSource
出于某种原因,我得到一个错误InvalidArgument说,它不能找物业“SqlTaskData”。 我相信这是从它击中数据流任务我都在包,它不具有属性/属性。 这就是我的意思是,它可能不是完美的解决方案,所以我不提供担保。 有一点需要指出的是,我没有我的包设置为通过密码进行加密。
更新
您可以尝试SQLPSX,包括一个图书馆的SSIS。
我没有安装SQLPSX但我可以告诉你如何解密包,没有它。 做最重要的事情是包密码分配给应用程序,以便它可以解密包。
给定一个包这样每个执行SQL任务有一个语句SELECT N AS test
下面的脚本将解密保存为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
搜索有关如何列出所有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;
}
}
}