空列表时保护 foreach 循环

Ste*_*teB 11 powershell

使用 Powershell v2.0 我想删除任何早于 X 天的文件:

$backups = Get-ChildItem -Path $Backuppath | 
                Where-Object {($_.lastwritetime -lt (Get-Date).addDays(-$DaysKeep)) -and (-not $_.PSIsContainer) -and ($_.Name -like "backup*")}

foreach ($file in $backups)
{
    Remove-Item $file.FullName;
}
Run Code Online (Sandbox Code Playgroud)

但是,当 $backups 为空时,我得到: Remove-Item : Cannot bind argument to parameter 'Path' because it is null.

我试过了:

  1. 保护 foreach if (!$backups)
  2. 保护移除项 if (Test-Path $file -PathType Leaf)
  3. 保护移除项 if ([IO.File]::Exists($file.FullName) -ne $true)

这些似乎都不起作用,如果在列表为空时防止进入 foreach 循环的推荐方法怎么办?

jsc*_*ott 21

使用 Powershell 3,该foreach语句不会重复,$null并且不再出现 OP 描述的问题。

来自Windows PowerShell 博客文章的新 V3 语言功能

ForEach 语句不会遍历 $null

在 PowerShell V2.0 中,人们常常惊讶于:

PS> foreach ($i in $null) { 'got here' }

got here

当 cmdlet 不返回任何对象时,通常会出现这种情况。在 PowerShell V3.0 中,您不需要添加 if 语句来避免迭代 $null。我们会为您处理这些。

对于 PowerShell,$PSVersionTable.PSVersion.Major -le 2请参阅以下原始答案。


您有两种选择,我主要使用第二种。

检查$backups没有$null。一个简单If的循环可以检查不$null

if ( $backups -ne $null ) {

    foreach ($file in $backups) {
        Remove-Item $file.FullName;
    }

}
Run Code Online (Sandbox Code Playgroud)

或者

初始化$backups为空数组。这避免了您在上一个问题中提出的“迭代空数组”问题的歧义。

$backups = @()
# $backups is now a null value array

foreach ( $file in $backups ) {
    # this is not reached.
    Remove-Item $file.FullName
}
Run Code Online (Sandbox Code Playgroud)

抱歉,我没有提供集成您的代码的示例。请注意Get-ChildItem包装在数组中的cmdlet。这也适用于可以返回$null.

$backups = @(
    Get-ChildItem -Path $Backuppath |
        Where-Object { ($_.lastwritetime -lt (Get-Date).addDays(-$DaysKeep)) -and (-not $_.PSIsContainer) -and ($_.Name -like "backup*") }
)

foreach ($file in $backups) {
    Remove-Item $file.FullName
}
Run Code Online (Sandbox Code Playgroud)