2014-01-29 44 views
4

我正在尋求如何使用powershell腳本中的特定參數調用cmd的幫助。到目前爲止,我寫的是下面的內容,但它給了我一個錯誤消息,說$ _cmd不被識別。如何使用powershell腳本中的參數調用可執行文件

我想將日期和日期傳遞給一個EXE ...從你可以看到的日期需要今天 - 1和迄今爲止應該是現在。可執行文件的路徑是D:\ DataService,這就是爲什麼我在腳本中儘早設置路徑的原因。

Write-Host "Get data from service" 

$path ="D:\DataService" 

Push-Location $path 
$Date = Get-Date 
$DateFrom = $Date.ToString("yyyy-MM-dd HH:mm:ss") 
$DateTo = $Date.AddDays(-1).ToString("yyyy-MM-dd") 
$_cmd = "ReportGen.exe -ReportType Data -DateFrom $DateFrom $DateTo" 

%$_cmd% 

有什麼建議嗎?

回答

8

請勿製作命令字符串。使用時只需調用運算符(&):

Write-Host 'Get data from service' 

$path = 'D:\DataService' 

Push-Location $path 

$Date  = Get-Date 
$DateFrom = $Date.ToString('yyyy-MM-dd HH:mm:ss') 
$DateTo = $Date.AddDays(-1).ToString('yyyy-MM-dd') 

& ReportGen.exe -ReportType Data -DateFrom $DateFrom $DateTo 
+0

調用操作符在這裏是不必要的 - 只有當命令是別的東西時,比如變量。 –

+1

@JasonShirk它可能不是必要的,但它也不會傷害,並且我認爲每當你調用外部程序時使用它都是很好的風格。 –

+0

當然,添加/刪除'&'不會改變外部命令的運行方式。操作員可能會傷害腳本的可讀性,特別是對於任何額外語法可能令人困惑的新手而言。 –

3

您想按照以下注釋使用Invoke-Expression

Invoke-Expression $_cmd 

原創評論,這是錯誤的:

你嘗試把一個符號在前面。例如:

& $_cmd 

不確定爲什麼要使用%字符。

+2

但問題是,你能不能帶參數字符串中,因爲PowerShell中解釋整個字符串作爲名稱的命令。實際上,這就是調用操作符'&'的主要用途:指示PowerShell將後面的整個字符串解釋爲命令的名稱,而不僅僅是第一個標記(如果指定命令的路徑有空格)。 ** Invoke-Expression **計算字符串,就好像在命令提示符下輸入一樣。 –

+1

嘗試以下方法來查看不同之處:'$ c ='gci c:\'',然後'&$ c' - 失敗,因爲'gci c:\'不是命令的名稱。現在嘗試'$ c ='gci'',然後是'&$ c c:\' - 這可以工作(並且'&$ c'會列出當前目錄)。 –

+0

我想你的意思是'&$ c c:\'不''c $:'但現在我明白了。 – jgritty

2

%$_cmd%看起來像是PowerShell和cmd語法的混合體。這個%沒有特別的意義。 PowerShell將其解釋爲命令的字面名稱,這當然不會被識別。要執行字符串的內容,使用

Invoke-Expression $_cmd 

但是,如果ReportGen.exe是在路徑只會工作,而CMD甚至沒有動手,因爲你沒有任何地方叫它。如果由於某種原因,如你所說,你特別想用cmd執行該命令,你應該在開始時加cmd /ccmd /k。但是,你甚至都不需要分配給一個字符串,你可以直接調用CMD:

cmd /c ReportGen.exe -ReportType Data -DateFrom $DateFrom $DateTo 

/c意味着CMD將執行命令後退出。 /k表示命令執行後,cmd提示符將保持打開狀態。您可能想要/c,以便在執行腳本後返回到PowerShell提示符。

+0

Invoke-Expression應避免,請參閱我的博客文章:http://blogs.msdn.com/b/powershell/archive/2011/06/03/invoke-expression-considered-harmful.aspx –

+0

此外 - 調用cmd是不必要的。 –

1

我會這樣做。

$CustomProcess = New-Object System.Diagnostics.ProcessStartInfo 
$CustomProcess.FileName = "ReportGen.exe" 
$CustomProcess.arguments = "-ReportType Data -DateFrom $DateFrom $DateTo" 
[System.Diagnostics.Process]::Start($CustomProcess) 
2

有幾件事。一,停止使用寫主機。老實說,讓這是你最後一次使用它(除非你真的需要它 - 並知道你爲什麼需要它)。相反,使用Write-Output - 即使您知道您的腳本將在控制檯中運行。其次,您還可以考慮使用Start-Process cmdlet及其參數-ArgumentList。

+3

我不同意。有很多情況下,**寫主機**是可取的,許多情況下,它沒有什麼區別。作爲一個經驗法則,使用** Write-Host **向用戶顯示信息性消息,並使用** Write-Output **獲得您希望能夠用於其他內容的結果(pipe to another command or a文件或分配給變量)。任何來自Unix背景的人都可能認爲你應該總是默認使用** Write-Output **,但PowerShell的對象管道方向常常使它成爲信息消息的錯誤選擇。 –

+0

我同意@AdiInbar。 ** Write-Host **優於** Write-Output **的情況很多。事實上,除非你確切知道你在做什麼,否則你可能不應該使用** Write-Output **。當捕獲函數,PowerShell Job,PSSession等的輸出時,這可能會導致意想不到的結果。僅僅因爲您閱讀Jeffrey Snover的博客文章並不一定意味着該建議可以普遍應用。 –

+0

謝謝您的信息。我一定會對這個話題做更多的研究......而且我聽起來就像我知道那麼多。我不得不承認,看到一個寫入輸出如何導致意外結果的例子,我很感興趣。 – tommymaynard

2

你$ DateFrom和$ DateTo似乎是倒退,因爲你正在$ DateTo設置爲昨天。所以,除非你從今天到昨天,否則你可能需要調整。此外,您可以指定起始日期,但只需在最後加上日期,不確定是否需要指定它的內容,或者如果兩個日期都是同一參數的一部分。至於運行帶有參數的命令,使用Invoke-Command帶參數的逗號分隔這樣:

Invoke-Command -FilePath "D:\DataService\ReportGen.exe" -ArgumentList '-ReportType Data','-DateFrom $DateFrom','$DateTo' 
相關問題