有没有办法从使用PowerShell的SSIS目录中的软件包中获取Package XML,但是没有下载和解压缩项目?我想在XML文档中搜索某些字符串。
################################
########## PARAMETERS ##########
################################
$SsisServer = ".\sql2016"
############################
########## SERVER ##########
############################
# Load the Integration Services Assembly
$SsisNamespace = "Microsoft.SqlServer.Management.IntegrationServices"
[System.Reflection.Assembly]::LoadWithPartialName($SsisNamespace) | Out-Null;
# Create a connection to the server
$SqlConnectionstring = "Data Source=" + $SsisServer + ";Initial Catalog=master;Integrated Security=SSPI;"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection $SqlConnectionstring
# Create the Integration Services object
$IntegrationServices = New-Object $SsisNamespace".IntegrationServices" $SqlConnection
# Check if connection succeeded
if (-not $IntegrationServices)
{
Throw [System.Exception] "Failed to connect to server $SsisServer "
}
#############################
########## CATALOG ##########
#############################
# Create object for SSISDB Catalog
$Catalog = $IntegrationServices.Catalogs["SSISDB"]
# Check if the SSISDB Catalog exists
if (-not $Catalog)
{
Throw [System.Exception] "SSISDB catalog doesn't exist!"
}
##########################
########## LOOP ##########
##########################
foreach ($Folder in $Catalog.Folders)
{
Write-Host $Folder.Name
foreach ($Project in $Folder.Projects)
{
Write-Host " - " $Project.Name
foreach ($Package in $Project.Packages)
{
Write-Host " - " $Package.Name
# HOW TO GET PACKAGE XML???
# Not working:
# Exception calling "Serialize" with "1" argument(s):
# "The parameter 'sink.Action' is invalid."
#$sb = New-Object System.Text.StringBuilder
#$sw = New-Object System.IO.StringWriter($sb)
#$writer = New-Object System.Xml.XmlTextWriter($sw)
#$xml = $Package.Serialize($writer)
}
}
}
答案 0 :(得分:3)
我没有运气尝试此代码的纯对象模型版本,因为我得到了error
使用“1”参数调用“Serialize”的异常:“参数'sink.Action'无效。”
超!在尝试通过托管对象模型进入项目之后,我试图通过TSQL路由。我们只需要模拟对SSISDB.catalog.get_project
的调用并将其传递给文件夹和项目名称
Function Get-ProjectsTsql
{
param
(
[Microsoft.SqlServer.Management.IntegrationServices.CatalogFolder] $folder
, [string] $serverName = "localhost\dev2016"
)
# we want to build an execute procedure call that looks like this
# exec [SSISDB].[catalog].[get_project] @folder_name=N'FolderName',@project_name=N'ProjectName'
$connectionString = [String]::Format("Data Source={0};Initial Catalog=msdb;Integrated Security=SSPI;", $serverName)
$connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
$integrationServices = New-Object Microsoft.SqlServer.Management.IntegrationServices.IntegrationServices($connection)
# The one, the only SSISDB catalog
$catalog = $integrationServices.Catalogs["SSISDB"]
#Instance of ProjectInfo
foreach ($proj in $folder.Projects)
{
$projName = $proj.Name
$folderName = $folder.Name
$zipOut = "C:\tmp\$projName.zip"
$query = "exec [SSISDB].[catalog].[get_project] @folder_name=N'$folderName',@project_name=N'$projName'"
# Write-Host $query
$command = New-Object System.Data.SqlClient.SqlCommand
$command.CommandText = $query
$command.Connection = $connection
$projectBinary = $command.ExecuteScalar()
[System.IO.File]::WriteAllBytes($zipOut,$projectBinary)
}
}
Function Get-CatalogFolders
{
param
(
[string] $serverName = "localhost\dev2012"
)
$connectionString = [String]::Format("Data Source={0};Initial Catalog=msdb;Integrated Security=SSPI;", $serverName)
$connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
$integrationServices = New-Object Microsoft.SqlServer.Management.IntegrationServices.IntegrationServices($connection)
# The one, the only SSISDB catalog
$catalog = $integrationServices.Catalogs["SSISDB"]
$catalogFolders = $catalog.Folders
return $catalogFolders
}
$serverName = "localhost\dev2016"
# Identify all the folders on the server
foreach ($folder in Get-CatalogFolders $serverName)
{
# Save out all the projects to their zip files
Get-ProjectsTsql $folder $serverName
}
这是我用.zip扩展名保存的ispac(因为它只是一个zip)。要获取包xml,您需要解压缩文件,找到您的包并从那里开始
答案 1 :(得分:2)
虽然该线程已有几个月的历史,但我认为以下方法直接回答了原始问题。我遇到了类似的情况,我需要从SSISDB中的包访问XML,以作为新包的模板。好吧,在将项目字节读入我的脚本后,
var projectBytes = ssisServer.Catalogs["SSISDB"].Folders[SSISFolderName].Projects[SSISProjectName].GetProjectBytes();
可以通过从项目字节创建内存存档来绕过下载/解压缩。通过遍历存档条目直到找到正确的包(如果知道文件的索引更容易),最后一步是将存档条目读入流并将其传递给package.LoadFromXML方法。
Stream stream = new MemoryStream(projectBytes);
ZipArchive za = new ZipArchive(stream);
foreach (ZipArchiveEntry zipEntry in za.Entries)
{
if (zipEntry.FullName == SSISPackageName)
{
Package pkg = new Package();
StreamReader sr = new StreamReader(zipEntry.Open());
pkg.LoadFromXML(sr.ReadToEnd(), null);
break;
}
}
答案 2 :(得分:0)
如果目标是读取包中的数据并直接获取xml,那么包的XML代码实际上是作为二进制数据存储在SSISDB.internal.object_versions table.ref的object_data列中。[ 1]
您可以使用 GetSqlBinary 方法检索此数据。我已经看到了一个用于检索SSRS rdl文件的示例。见参考文献[2]有关代码的完整示例。
# New BinaryWriter; existing file will be overwritten.
$fs = New-Object System.IO.FileStream ($name), Create, Write;
$bw = New-Object System.IO.BinaryWriter($fs);
# Read of complete Blob with GetSqlBinary
$bt = $rd.GetSqlBinary(2).Value;
$bw.Write($bt, 0, $bt.Length);
$bw.Flush();
$bw.Close();
$fs.Close();
<强> 参考 强>