表达式仅允许作为管道的第一个元素

mee*_*eep 9 powershell

我是写作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@address.com"
$ToAddress = "email@address.com"
$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)}
}   
Run Code Online (Sandbox Code Playgroud)

Kyl*_*Mit 8

当您尝试从管道链中执行独立的代码块时,会出现此错误.

就像一个不同的例子,想象使用jQuery这个代码:

$("div").not(".main").console.log(this)
Run Code Online (Sandbox Code Playgroud)

每个dot(.)都会将数组链接到下一个函数中.在上面的函数中,它打破了console因为它并不意味着有任何值传入.如果我们想要从链接中断出来执行一些代码(可能在链中的对象上 - 我们可以这样做each:

$("div").not(".main").each(function() {console.log(this)})
Run Code Online (Sandbox Code Playgroud)

解决方案是powershell是完全相同的.如果要单独针对链中的每个项运行脚本,可以使用ForEach-Object或使用别名(%).

想象一下,你在Powershell中有以下功能:

$settings | ?{$_.Key -eq 'Environment' } | $_.Value = "Prod" 
Run Code Online (Sandbox Code Playgroud)

最后一行无法执行,因为它是一个脚本,但我们可以ForEach一样修复它:

$settings | ?{$_.Key -eq 'Environment' } | %{ $_.Value = "Prod" }
Run Code Online (Sandbox Code Playgroud)


man*_*lds 5

当您在管道的接收端使用表达式而无法从管道接收对象时,基本上会发生此错误。

如果你做这样的事情,你会得到错误:

$a="test" | $a
Run Code Online (Sandbox Code Playgroud)

甚至这个:

"test" | $a
Run Code Online (Sandbox Code Playgroud)

我不知道为什么到处都在尝试管道。我建议您学习有关 Powershell 流水线的基础知识。你接近它是错误的。另外,我认为您可以参考下面的链接来查看如何发送邮件,应该很简单,没有您使用管道添加的复杂性:http : //www.searchmarked.com/windows/how-to-send -an-email-using-a-windows-powershell-script.php

  • 我喜欢烟斗,但我发现它被过度使用了。尤其是在脚本内部。我一直在命令提示符下使用管道,但我很少在脚本中使用它。 (2认同)
  • @EBGreen - 我认为真正的问题只有当你不真正了解发生了什么时。例如,您可以使用`$a | write-host` 而不是 `write-host $a`。是的,有时它被过度使用。编写单行代码很好,但很难维护其他人必须阅读和维护的脚本。 (2认同)
  • 是的,即使它们在脚本中完全正确地使用,我也只是认为这是一个良好习惯的问题(无论如何对我自己来说)继续并在脚本中尽可能地明确。这意味着更少的管道和显式 cmdlet 名称而不是别名。 (2认同)