2017-05-04 86 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