使用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; }
但是,当$ backups为空时,我得到: Remove-Item : Cannot bind argument to parameter 'Path' because it is null.
我试过了:
if (!$backups)
保护foreach if (Test-Path $file -PathType Leaf)
保护Remove-Item if ([IO.File]::Exists($file.FullName) -ne $true)
保护Remove-Item 这些似乎都没有工作,如果推荐的方式来防止如果列表是空的foreach循环被input呢?
使用Powershell 3, foreach
语句不会覆盖$null
,OP所描述的问题不再发生。
从Windows PowerShell博客文章新的V3语言function :
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
请参阅以下原始答案。
你有两个select,我主要使用第二个选项。
检查$backups
是否为$null
。 一个简单的If
循环可以检查$null
if ( $backups -ne $null ) { foreach ($file in $backups) { Remove-Item $file.FullName; } }
要么
将$backups
初始化为一个空数组。 这样可以避免在上一个问题中询问的“迭代空数组”问题的含糊性。
$backups = @() # $backups is now a null value array foreach ( $file in $backups ) { # this is not reached. Remove-Item $file.FullName }
对不起,我忽略了提供一个集成你的代码的例子。 请注意包装在数组中的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 }
我知道这是一个旧post,但我想指出,ForEach-Object cmdlet不会遇到与使用ForEach关键字相同的问题。 因此,您可以将DIR的结果传递给ForEach,只需使用$ _引用该文件,如:
$backups | ForEach{ Remove-Item $_ }
你实际上可以通过pipe道转发Dir命令本身,甚至避免分配variables:
Get-ChildItem -Path $Backuppath | Where-Object { ($_.lastwritetime -lt (Get-Date).addDays(-$DaysKeep)) -and ` (-not $_.PSIsContainer) -and ($_.Name -like "backup*") } | ForEach{ Remove-Item $_ }
为了便于阅读,我添加了换行符。
我了解一些人喜欢ForEach / In为了可读性。 有时ForEach对象可能会变得有点毛,特别是如果你嵌套,因为它很难遵循$ _引用。 无论如何,对于这样的小型手术来说,这是完美的。 许多人也认为它更快,但我发现只是稍微。
我已经开发了一个解决scheme,通过运行查询两次,一次获取文件,一次通过投掷get-ChilItem来返回一个数组来计算文件(在事实似乎不工作之后,将$ backups转换为数组) 。
至less它按预期工作(性能不应该成为问题,因为永远不会有十几个文件),如果有人知道单一查询解决scheme,请张贴它。
$count = @(Get-ChildItem -Path $zipFilepath | Where-Object {($_.lastwritetime -lt (Get-Date).addDays(-$DaysKeep)) -and (-not $_.PSIsContainer) -and ($_.Name -like $partial + "*")}).count; if ($count -gt 0) { $backups = Get-ChildItem -Path $zipFilepath | Where-Object {($_.lastwritetime -lt (Get-Date).addDays(-$DaysKeep)) -and (-not $_.PSIsContainer) -and ($_.Name -like $partial + "*")}; foreach ($file in $backups) { Remove-Item $file.FullName; } }
使用以下来评估数组是否有任何内容:
if($backups.count -gt 0) { echo "Array has contents" } else { echo "Array is empty" }
如果variables不存在,Powershell将简单地将其评估为false,所以不需要检查它是否存在。