2017-05-04 21 views
0

我已经对如何从SSIS运行参数化的PS脚本做了大量的研究。我遇到了运行参数化脚本的问题。 PS脚本如下,如果我硬编码参数到它的行为与预期的脚本:通过SSIS执行参数化的powershell脚本执行进程任务(使用UNC)

Param ([string]$filepath,[string]$filename) 

$Path = $filepath 
$InputFile = (Join-Path $Path $filename) 
$Reader = New-Object System.IO.StreamReader($InputFile) 

While (($Line = $Reader.ReadLine()) -ne $null) { 
    If ($Line -match 'FILE\|([^\|]+)') { 
     $OutputFile = "$($matches[1]).txt" 
    } 
    Add-Content (Join-Path $Path $OutputFile) $Line 
} 

运行在SSIS执行过程中的任务,我想通过表达来构建Arguments命令如下:

"-ExecutionPolicy ByPass -File " + @[User::vPSScriptLocation] + " " + @[User::vFilePath]+ " "+ @[User::vFileName] 

计算表达式给出如下:

-ExecutionPolicy ByPass -File \\WorkDirectory\Script.ps1 \\transfer datafile.data 

在执行时,任务失败。该名为.ps1从工作目录中删除,SSIS提供了以下错误代码:

Error: 0xC0029151 at Execute powershell script, Execute Process Task: In Executing "C:\Windows\System32\WindowsPowerShell\v1.0\PowerShell.exe" "-ExecutionPolicy ByPass -File \\WorkDirectory\Script.ps1 \\transfer datafile.data" at "", The process exit code was "-196608" while the expected was "0". 

看起来像是得到一个空字符串,它不应该?任何指针赞赏。

+0

所以你的进程应该读取文件“\\传输\ datafile.data “?这不是一个有效的UNC路径。如果您运行错误中显示的代码,您的脚本是否可以正常工作?它看起来像它将所有参数作为一个字符串传递,但这可能只是如何写入错误。将不得不检查'-File'是否支持UNC。 [这个问题](http://stackoverflow.com/questions/35729192/ssis-powershell-script-execute)得到你的错误试图使用UNC路径的文件。 – Matt

+0

它应该读取\\ WorkDirectory \ Script.ps1,它又不是UNC。我也尝试在语音标记中传递参数,但得到相同的结果。它可能是UNC,尽管它非常奇怪的行为是从读取位置删除ps1文件。 – TJB

+0

“\\ WorkDirectory \ Script.ps1”不是一个有效的路径,所以我认为powershell不知道你想要运行什么。这应该是一个相对路径或什么?我敢打赌你没有一个名为WorkDirectory的服务器,这是PowerShell将要寻找的。在您的脚本中应该发生同样的问题,这正是我在尝试指出的那种情况下建立的类似路径无效的情况。 – Matt

回答

0

OK这样看来我不能叫UNC路径此使用执行进程任务来执行,我决定与这让我创造附加到​​参考脚本任务中执行此一个PowerShell实例。这远非我理想的解决方案,因为我真的想调用.ps1文件,但看起来这是我唯一的解决方案,因为我需要使用UNC路径。

我打造的PS脚本我DTS变量,然后实例,实现了预期的结果中执行它:

public void Main() 
    { 
     string filepath = Dts.Variables["User::vUNCPath"].Value.ToString(); 
     string filename = Dts.Variables["User::vFileName"].Value.ToString(); 
     string searchterm = Dts.Variables["User::vSearchTerm"].Value.ToString(); 
     bool fireAgain = true; 

     // Build powershell script 
     string script = "$Path = \""+filepath+"\";"+ 
         "$InputFile = (Join-Path $Path \""+ filename+"\");" + 
         "$Reader = New-Object System.IO.StreamReader($InputFile);" + 
         "While (($Line = $Reader.ReadLine()) -ne $null) {" + 
         "If ($Line -match '"+searchterm+"') { "+ 
         "$OutputFile = \"$($matches[1]).txt\"};" + 
         "Add-Content (Join-Path $Path $OutputFile) $Line}"; 

     Dts.Events.FireInformation(0, "Info", "Powershell script built: " + script, String.Empty, 0, ref fireAgain); 

     try 
     { 
      // Create instance to run script 
      using (PowerShell psinstance = PowerShell.Create()) 
      { 
       //Assign built script to this instance 
       psinstance.AddScript(script); 

       //Run powershell script 
       psinstance.Invoke(); 

      } 

      Dts.TaskResult = (int)ScriptResults.Success; 
     } 
     catch (Exception ex) 
     { 
      Dts.Events.FireError(0, "Error", ex.Message, String.Empty, 0); 
      Dts.TaskResult = (int)ScriptResults.Failure; 
     } 
    } 
0

如果你正在运行的脚本作为PS1-文件,像这样的PARAM块,你执行呼叫应命名他们的名字的参数:

"-ExecutionPolicy ByPass -File " + @[User::vPSScriptLocation] + " -filepath " + @[User::vFilePath]+ " -filename "+ @[User::vFileName] 

这应该这样做,如果你使用有效的文件路径和文件名。

如果不起作用,请尝试将脚本编写为函数,并在PowerShell控制台中尝试。你作为一个函数脚本如下:

function SearchLines 
{ 
    Param (
    [string]$filepath, 
    [string]$filename 
) 
    $Path = $filepath 
    $InputFile = (Join-Path $Path $filename) 
    $Reader = New-Object System.IO.StreamReader($InputFile) 
    While (($Line = $Reader.ReadLine()) -ne $null) { 
    If ($Line -match 'FILE\|([^\|]+)') { 
     $OutputFile = "$($matches[1]).txt" 
    } 
    Add-Content (Join-Path $Path $OutputFile) $Line 
    } 
} 

用法:

SearchLines -filepath "\\your\unc\path\here" -filename "filename.txt" 

如果不适合你,请让我们知道你有哪些错误。

Thx。

UPDATE:根据您的意见

,我把你的功能,希望新的,它符合您的要求尽可能接近。该函数现在看起来是这样的:

function SearchLines 
{ 
    Param (
    [string]$InputFile 
) 
    $FileContent = Get-Content $InputFile 
    foreach($Line in $FileContent) 
    { 
    If ($Line -match 'FILE\|([^\|]+)') 
    { 
     $OutputFile = "$($matches[1]).txt" 
    }  
    Add-Content -Path $OutputFile -Value $Line 
    } 
} 

用法:

SearchLines -InputFile c:\your\path\to\your\file.log 

此功能,每行给出的文件中创建一个名为实际文件夹是什么写入行一个新的文件。 Cmdlet Join-Path只是将两个字符串相加,而不检查合理性。这就是为什么你可以简单地提交完整路径到你的文件,而不是在单独的参数中的路径和文件。

如果您需要inputfile的路径,将其设置为您outputfiles,您可以用这些行获得它:

$tmpPath = Get-Childitem $InputFullPath 
$Path = $tmpPath.Directory.FullName 

因为你没有解释究竟这个脚本应该做的,我希望你可以用它来得到你想要的东西。

问候

+0

第一次尝试给出与原始问题相同的错误。第二在控制台返回下面,这可能是我对PowerShell的知识缺乏... 术语“SearchLines”不被识别为cmdlet,函数,scr ipt文件或可操作程序的名称。检查名称的拼写,或者如果包含路径 ,请验证路径是否正确,然后重试。 – TJB

+0

在尝试使用它之前,将我的答案中的完整源代码复制并粘贴到PowerShell控制台中。如果你在你的脚本文件中使用它,你可以将它复制到你的脚本文件的开头,在参数块之后。 –

+0

确定使用它的说明“异常调用”.ctor“与”1“参数:找不到文件”\\ your \ unc \ path \ here \ - “”在第9行char 23 $ Reader = New-对象<<<< System.IO.StreamReader($ InputFile) – TJB