【问题标题】:else not being executed within foreachelse 不在 foreach 中执行
【发布时间】:2016-05-19 00:11:56
【问题描述】:

我正在尝试编写以下脚本,该脚本会检查文件夹中的一组文件,如果它们存在,请将它们移动到“存档”文件夹。如果没有,请将错误消息写入屏幕和日志文件。

文件移动正常,因此 IF 的第一部分工作正常,但如果没有文件可移动,else 应该启动并输出错误....但事实并非如此。

variables.ps1:

#----- define parameters -----#
#----- Treat All Errors as Terminating -----#
$ErrorActionPreference = "Stop" 
#----- Set count to 0 -----#
$count = 0
#----- get current date ----#
$Now = Get-Date
#----- define amount of days ----#
$Days = "0"
#----- define folder where files are located ----#
$SourceFolder = "C:\HG1\Test\Files"
#----- define folder where files are to be moved to ----#
$DestFolder = "C:\HG1\Test\Files\Archive"
#----- define folder where files are to be moved to ----#
$LogPath = "C:\HG1\archive.log"
#----- define extension ----#
$Extension = "*.log"
#----- define LastWriteTime parameter based on $Days ---#
$LastWrite = $Now.AddDays(-$Days)

#----- get files based on lastwrite filter and specified folder ---#
$Files = Get-Childitem $SourceFolder -Include $Extension -Recurse | Where {$_.LastWriteTime -le "$LastWrite"}

archive_files.ps1

#----- Call variables file variables.ps1 - MUST BE IN SAME LOCATION AS SCRIPT ----#
. ./variables.ps1

foreach ($File in $Files)
    {
    if ($File -ne $NULL)
        {
        move-item -path $File.FullName -destination $DestFolder
        Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t INFO: Archived File $File")
        }
    else
        {
        write-host "ERROR: No files to archive" -ForegroundColor "Red"
        Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t ERROR: No files to archive")
        }
    } 
Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t INFO: ***Archiving script completed successfully***")

任何帮助将不胜感激。

【问题讨论】:

  • $File 永远不会为空,至少它将是一个字符串。您可以使用Test-Path检查现有文件,如本问题所示:stackoverflow.com/questions/1732250/…
  • 如果$Files 中没有文件,则简单地跳过foreachelse 不应该与您的代码一起运行。
  • 您是否要查看$sourcefolder 的所有子文件夹并根据.log 文件的存在对这些文件夹执行操作?
  • 不,我只是想在 C:\HG1\Test\Files 中查找任何 *.log 文件。如果存在任何 .log 文件,请将它们移动到 C:\HG1\Test\Files\Archive。如果不存在 .log 文件,则显示该错误。我认为 Test-Path 将成为答案,只需要尝试一下就可以让它工作。抱歉,在 PowerShell 方面,我是一个巨大的 N00b。
  • @dankellys - 我不认为Test-Path 是答案。您只是想看看$Files 是否为空,无需为此测试路径。

标签: powershell powershell-4.0


【解决方案1】:
#----- Call variables file variables.ps1 - MUST BE IN SAME LOCATION AS SCRIPT ----#
. ./variables.ps1


if ($File)
    {
     foreach ($File in $Files)
     {
        move-item -path $File.FullName -destination $DestFolder
        Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t INFO: Archived File $File")
     }

    }
else
    {
    write-host "ERROR: No files to archive" -ForegroundColor "Red"
    Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t ERROR: No files to archive")
    }

Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t INFO: ***Archive script completed successfully***")

这里,

  • Foreach each 不会处理 $null 值 所以如果值不为空,则包含 foreach
  • 如果不输入 $null 值,则不需要“-ne $null”

希望这对你有用,

问候,

Kvprasoon

【讨论】:

  • 很好,已修复。我唯一需要改变的是if ($file) 必须是if ($files)。谢谢!
【解决方案2】:

您应该使用Test-Path cmdlet 来检查文件是否存在:

foreach ($File in $Files)
    {
    if (Test-Path $File)
        {
        move-item -path $File.FullName -destination $DestFolder
        Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t INFO: Archived File $File")
        }
    else
        {
        write-host "ERROR: No files to archive" -ForegroundColor "Red"
        Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t ERROR: No files to archive")
        }
    } 
Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t INFO: ***Archiving script completed successfully***")

【讨论】:

  • 我认为这不是 OP 代码的意图。我认为他想测试$Files 是否为空,而不是每个$File 是否存在。
  • 你可能是对的。然后我们需要整个脚本......无论如何,仍然想告诉他他可以使用Test-Path cmdlet 来检查文件是否存在
  • 我认为错误消息"ERROR: No files to archive" 是对这个的放弃。
  • 不确定。他可能有一个包含要删除的文件列表的文本文件。在这种情况下,我的回答会对他有所帮助。无论如何,我们需要整个脚本。
  • 您正在使用Get-ChildItem cmdlet。这将为您提供来自$SourceFolder 的所有文件,因此任何迭代都不会为您提供包含不存在文件的路径。
【解决方案3】:

你的逻辑倒过来了。

$Files 中的每个 $File 总是something,但$Files 集合本身可能是空的:

if(-not $Files)
{
    foreach($File in $Files)
    {
        Move-Item -Path $File.FullName -Destination $DestFolder
        Add-Content $LogPath -Value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t INFO: Archived File $File")
    }
}
else
{
    Write-Host "ERROR: No files to archive" -ForegroundColor "Red"
    Add-Content $LogPath -Value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t ERROR: No files to archive")
}

Add-Content $LogPath -value ("$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) `t INFO: ***Archiving script completed successfully***")

【讨论】:

  • 谢谢,但是当没有要处理的 .log 文件时仍然会遇到同样的问题。 else 被忽略,脚本在将“2016-05-18 15:58:21 INFO: *Archiving script completed successfully”写入日志文件后刚刚结束。没有“错误:没有要归档的文件”消息的迹象
猜你喜欢
  • 2013-01-18
  • 1970-01-01
  • 2021-02-14
  • 1970-01-01
  • 2020-03-20
  • 1970-01-01
  • 2012-07-18
  • 1970-01-01
  • 2023-03-26
相关资源
最近更新 更多