2011-08-22 59 views
7

我是在PowerShell中編寫新東西,但這是我試圖完成的。只允許表達式作爲流水線的第一個元素

  1. 我想比較兩個excel文件的日期,以確定是否比另一個更新。
  2. 我想在沒有excel的計算機上將文件從csv轉換爲xls。只有上述聲明爲真,最初的xls文件已被複制。
  3. 我想將新轉換後的xls文件複製到另一個位置
  4. 如果文件已經打開,它將無法複製,因此我想發送有關此操作成功或失敗的電子郵件警報。

這是我遇到問題的腳本。錯誤是「表達式只被允許作爲管道的第一個元素。」我知道這是關於電子郵件的操作,但我不知道如何用所有這些變量手動寫出來。可能有更多的錯誤,但我現在沒有看到它們。感謝您的幫助,我很感激!當您使用上了管道的接收端的表現時,它不能從管道接收對象

$CSV = "C:filename.csv" 
$LocalXLS = "C:\filename.xls" 
$RemoteXLS = "D:\filename.xls" 
$LocalDate = (Get-Item $LocalXLS).LASTWRITETIME 
$RemoteDate = (Get-Item $RemoteXLS).LASTWRITETIME 
$convert = "D:\CSV Converter\csvcnv.exe" 
if ($LocalDate -eq $RemoteDate) {break} 
else { 
& $convert $CSV $LocalXLS 
$FromAddress = "[email protected]" 
$ToAddress = "[email protected]" 
$MessageSubject = "vague subject" 
$SendingServer = "mail.mail.com" 
$SMTPMessage = New-Object System.Net.Mail.MailMessage $FromAddress, $ToAddress, $MessageSubject, $MessageBody 
$SMTPClient = New-Object System.Net.Mail.SMTPClient $SendingServer 
$SendEmailSuccess = $MessageBody = "The copy completed successfully!" | New-Object System.Net.Mail.SMTPClient mail.mail.com $SMTPMessage 
$RenamedXLS = {$_.BaseName+(Get-Date -f yyyy-MM-dd)+$_.Extension} 

Rename-Item -path $RemoteXLS -newname $RenamedXLS -force -erroraction silentlycontinue 
If (!$error) 
    { $SendEmailSuccess | copy-item $LocalXLS -destination $RemoteXLS -force } 
Else 
    {$MessageBody = "The copy failed, please make sure the file is closed." | $SMTPClient.Send($SMTPMessage)} 
} 
+2

我不知道到底是什麼你正試圖完成這一行:$ SendEmailSuccess = $ MessageBody =「複製成功完成!」 |新對象System.Net.Mail.SMTPClient mail.mail.com $ SMTPMessage但我想這是錯誤的罪魁禍首。 – EBGreen

+1

@meep - 不要編輯出內容。那麼根本沒有問題。即使你已經弄明白了,這對未來的訪問者也是有用的。附加您的修改。 – manojlds

回答

4

這個錯誤基本上發生。

$a="test" | $a 

甚至這樣:

"test" | $a 

我不知道爲什麼到處都試圖管

,如果你這樣做你會得到錯誤。我建議你學習有關Powershell流水線的基礎知識。你正在接近錯誤。另外,我認爲你可以參考下面的鏈接來看看如何發送郵件,應該是直截了當的,沒有你用管道添加的複雜性:http://www.searchmarked.com/windows/how-to-send-an-email-using-a-windows-powershell-script.php

+2

我喜歡這個菸斗,但是我覺得它會被過度使用。特別是在腳本中。我一直在命令提示符下使用管道,但我很少在腳本中使用它。 – EBGreen

+2

@EBGreen - 我認爲真正的問題只有當你不明白髮生了什麼。例如,你可以使用'$ a | write-host'而不是'write-host $ a'。是的,有時它被過度使用。很高興寫一行,但很難維護其他人必須閱讀和維護的腳本。 – manojlds

+2

是的,即使它們在劇本中的使用完全正確,我仍然認爲它只是一個良好習慣(無論如何)的問題,然後在劇本中儘可能地明確。這意味着更少的管道和明確的cmdlet名稱而不是別名。 – EBGreen

5

當你試圖執行一個獨立的來自管道鏈內的代碼塊。

正如不同示例中,設想使用jQuery此代碼:

$("div").not(".main").console.log(this) 

每個點(.)將鏈中的陣列到下一個功能。在上面的函數中,這與console打破,因爲它並不意味着有任何值傳入。如果我們想從鏈中斷開執行一些代碼(可能在鏈中的對象 - 我們可以這樣做each像這樣:

$("div").not(".main").each(function() {console.log(this)}) 

的解決方案是PowerShell是相同的。如果你想在你的鏈運行鍼對每個項目單獨的腳本,你可以使用ForEach-Object或它的別名(%)。

假設您在PowerShell中的以下功能:

$settings | ?{$_.Key -eq 'Environment' } | $_.Value = "Prod" 

最後一行不能被執行,因爲它是一個腳本,但we can fix that with ForEach這樣的:

$settings | ?{$_.Key -eq 'Environment' } | %{ $_.Value = "Prod" } 
相關問題