我正在编写一个PowerShell脚本,删除除最近X个文件夹以外的所有文件夹,不包括名为Data的文件夹。我收集要删除的文件夹的声明如下:
$folders1 = Get-ChildItem $parentFolderName |
? { $_.PSIsContainer -and $_.Name -ne "Data" } |
sort CreationTime -desc |
select -Skip $numberOfFoldersToKeep
foreach ($objItem in $folders1) {
Write-Host $webServerLocation\$objItem
Remove-Item -Recurse -Force $parentFolderName\$objItem -WhatIf
}
当我传递的$numberOfFoldersToKeep
少于起始目录$parentFolderName
中的文件夹数时,这很有用。例如,在我的目标文件夹中有5个子目录,这可以按预期工作:
myScript.ps1 C:\StartingFolder 3
但是如果我要传递大量文件夹来跳过,我的语句似乎会返回$parentFolderName
本身的值!所以这不起作用:
myScript.ps1 C:\StartingFolder 15
由于skip变量超过了Get-ChildItem
集合中的项目数,因此脚本会尝试删除C:\StartingFolder\
,这根本不是我预期的。
我做错了什么?
答案 0 :(得分:2)
试试这个:
$folders1 = Get-ChildItem $parentFolderName |
? { $_.PSIsContainer -and $_.Name -ne "Data" } |
sort CreationTime -desc |
select -Skip $numberOfFoldersToKeep
if ($folder1 -neq $null)
{
foreach ($objItem in $folders1) {
Write-Host $($objItem.fullname)
Remove-Item -Recurse -Force $objItem.fullname -WhatIf
}
}
答案 1 :(得分:1)
我给了@ C.B.可以肯定答案,但还有另一种解决问题的方法,就是使用@( ... )
语法将Get-ChildItem的输出强制转换为数组。
$folders1 = @(Get-ChildItem $parentFolderName |
? { $_.PSIsContainer -and $_.Name -ne "Data" } |
sort CreationTime -desc |
select -Skip $numberOfFoldersToKeep)
foreach ($objItem in $folders1) {
Write-Host $webServerLocation\$objItem
Remove-Item -Recurse -Force $parentFolderName\$objItem -WhatIf
}
这将返回一个长度为零的数组,因此不会执行foreach语句的主体。
正如C.B.在上面的评论中指出的那样,问题是如果你将null
集合传递给PowerShell中的foreach语句,那么 foreach语句的主体将被执行一次。
这对我来说完全不直观,来自.NET背景。显然,这对许多其他人来说也不直观,因为在MSDN上有针对此行为的错误报告:https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=281908&SiteID=99
显然,此错误已在PowerShell V3中修复。