【问题标题】:Powershell For-Loop throws MissingVariableNameAfterForeachPowershell For-Loop 抛出 MissingVariableNameAfterForeach
【发布时间】:2020-01-23 12:34:57
【问题描述】:

为什么我收到以下错误“MissingVariableNameAfterForeach”:

powershell.exe -NoProfile -ExecutionPolicy Bypass -Command "foreach($file in Get-ChildItem C:){((Get-Date)-$file.LastWriteTime).ToString('dd')}"

该命令应该打印出从今天开始的最后一个文件/文件夹写入 C:\

【问题讨论】:

    标签: powershell cmd foreach zabbix


    【解决方案1】:

    来自帮助文本:

    PS C:\> powershell.exe /?
    
    If the value of Command is a script block, the script block must be enclosed
    in braces ({}). You can specify a script block only when running PowerShell.exe
    in Windows PowerShell.
    

    试试这个:

    powershell.exe -NoProfile -ExecutionPolicy Bypass -Command {Get-ChildItem C: | ForEach-Object{($_.LastWriteTime).ToString('dd')}}
    

    【讨论】:

    • 嘿,谢谢,它是这样工作的。但仍然是一个问题:当我从 Zabbix Server 运行命令时,它不起作用。我不知道为什么。但由于这不是我的问题,所以您的回答完全正确并且有效。谢谢。
    • 请参阅上面的帮助文本“您只能在 Windows PowerShell 中运行 PowerShell.exe 时指定脚本块”。 - 可能为什么 Zabbix 不起作用?不知道 Zabbix 是如何工作的,但运行脚本文件可能比运行命令块更好?
    【解决方案2】:

    如果您将 Get-ChildItem 括在括号中,您的命令将起作用。

    powershell.exe -NoProfile -ExecutionPolicy Bypass -Command ^
        "foreach($file in (Get-ChildItem C:)){((Get-Date)-$file.LastWriteTime).ToString('dd')}"
    

    【讨论】:

    • 嗯,没错。两个答案都有效。我用 zabbix 尝试了 lit's。在那里不起作用,但在本地它可以正常工作。
    • 在Zabbix中运行报错信息还是一样吗?
    • 可能和PowerShell版本有关,@lit,我隐约记得ToString,这样使用,早期版本输出错误
    • 是的,可能是,但考虑到它在同一个PowerShell中本地工作,在同一个服务器上......
    【解决方案3】:

    我可能已经理解了您的问题,因为现有的答案似乎没有提供我认为您正在寻找的信息。

    虽然这些示例并未具体回答您在标题中提出的问题,但它们旨在输出我认为您正在寻找的内容。

    因此,这是我的 尝试:

    @"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile -Command^
     "Get-ChildItem -Path 'C:\'|Sort-Object -Property LastWriteTime|"^
     "Select-Object -Last 1|Format-Table -AutoSize -Property Name,"^
     "@{Name='DaysOld';Expression={[Int]$((Get-Date)-$_.LastWriteTime).TotalDays}}"
    @Pause
    

    显然是 版本,成为话题:

    "%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile -Command "Get-ChildItem -Path 'C:\'|Sort-Object -Property LastWriteTime|Select-Object -Last 1|Format-Table -AutoSize -Property Name,@{Name='DaysOld';Expression={[Int]$((Get-Date)-$_.LastWriteTime).TotalDays}}"
    



    以防万一这只是我的误解,也许这个 可能对你有用:
    @"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile -Command^
     "Get-ChildItem -Path 'C:\'|Sort-Object -Property LastWriteTime -Descending|"^
     "Format-Table -AutoSize -Property Name,"^
     "@{Name='DayInMonth';Expression={($_.LastWriteTime).ToString('dd')}},"^
     "@{Name='DaysOld';Expression={[Int]$((Get-Date)-$_.LastWriteTime).TotalDays}}"
    @Pause
    

    版本:

    "%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile -Command "Get-ChildItem -Path 'C:\'|Sort-Object -Property LastWriteTime -Descending|Format-Table -AutoSize -Property Name,@{Name='DayInMonth';Expression={($_.LastWriteTime).ToString('dd')}},@{Name='DaysOld';Expression={[Int]$((Get-Date)-$_.LastWriteTime).TotalDays}}"
    



    在这两种情况下,您都会注意到,因为我没有运行 PowerShell 脚本,因此无需规定执行策略。命令应该像直接在 PowerShell 窗口中运行一样工作。

    【讨论】:

    • 您好,我尝试了您的两个示例。不幸的是,两者都不起作用。我收到错误“UnexpectedToken for”-Command。它可能与引号有关。即使我删除它们,它也会引发减法错误......它说没有发现 op_Subtraction 重载。为了您的信息,我运行MS Win Server 2012 R2 服务器上的命令。是的,执行策略是正确的。谢谢
    • @user3166101,他们是否仅在 Zabbix 中失败,因为我可以向您保证它基于我的标准模板。它甚至在 Powershell 2.0 以及所有版本(但不包括 7.0)中都经过测试和工作,(我对预览和候选发布不感兴趣,所以在它达到普遍可用性之前,我不会测试 Powershell 7.0)。我没有用双引号提供答案,并希望您删除它们,实际上所有发布的答案都应首先按书面形式进行测试,(根据需要仅调整 -Path我怀疑您是否真的在检查根系统驱动器)。
    • @user3166101,您是否尝试过调整 Zabbix 代理等待响应的默认 3 秒?只是看看它是否需要更长的时间,从而导致您的问题。您能否在没有 Zabbix 的情况下测试 cmd.exe 中的命令,您还可以在两种环境中测试批处理文件版本,并提供反馈。此外,没有什么可以阻止您将所提供的解决方案作为 Powershell 脚本进行测试,很明显,执行策略已放回原处。在我看来,代码很好,您的问题在于 Zabbix。从技术上讲,这是一个软件问题,而不是编程问题。
    • 好的,我确实测试了 cmd/batch 版本。 CMD 版本正在 shell 中工作。正如我所看到的,它提供了比我的东西更好的格式。两个版本的批处理版本都不起作用(使用 -NoProfile 和 -ExecutionPolicy Bypass -File ....)。 Zabbix 仍然无法正常工作。我现在将尝试从 Zabbix 将其作为脚本运行。对于使用 Zabbix 的任何人,此链接可能会有所帮助:zabbix.com/forum/zabbix-troubleshooting-and-problems/… 我稍后会报告我的结果。
    • @user3166101,-File 选项是当你运行一个 powershell 脚本时,(.ps1),你只是在运行一个 powershell 命令,所以不需要它,只需像我一样使用-Command 选项,然后像我一样将该命令括在双引号中。我不知道 Zabbix 是否完全按原样运行命令,或者是否将其作为一个或多个参数传递,但应该保留这些双引号,以防止任何潜在的毒字符在传递期间影响事物。当然你可以从 Zabbix 运行一个批处理文件,例如UserParameter=WHATEVER,FULLPATH\FILENAME.bat
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-06
    • 2020-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多