我想从构建服务器清除日志文件,保留最近几天。我的进程创建的日志文件没有问题。这很好用:
$logFolders = Get-ChildItem $buildBase -Recurse -include logs -Attributes D
$logFolders | ForEach-Object { Get-ChildItem $_.fullname -filter *.log | where >{$_.lastwritetime -lt (get-date).adddays(-$purgeAfter) -and -not $_.psiscontainer} |% {remove-item $_.fullname -force} };
但是,构建工具生成的日志如下所示:
lrFR_WebHelp - Friday, February 28, 2014 [9.00 PM].mclog
Get-ChildItem $frReports\Reports -filter *.mclog | where {$_.lastwritetime -lt (get-date).adddays(-$purgeAfter) -and -not $_.psiscontainer}| % {write-host ("'" + $frReports + '\Reports' + '\' + $_ + "'") }
输出:
'D:\scratch\Reports\lrFR_WebHelp - Friday, February 28, 2014 [9.00 PM].mclog'
但是试图删除:
Get-ChildItem $frReports\Reports -filter *.mclog | where {$_.lastwritetime -lt (get-date).adddays(-$purgeAfter) -and -not $_.psiscontainer}| % {remove-item ("'" + $frReports + '\Reports' + '\' + $_ + "'") }
输出:
remove-item : Cannot find drive. A drive with the name ''D' does not exist.
At line:1 char:145
+ ... container}| % {remove-item ("'" + $frReports + '\Reports' + '\' + $_ + "'") }
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: ('D:String) [Remove-Item], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
更改为unix斜杠('/')或转义斜杠('\\')不会更改结果
此:
$filesToDelete = Get-ChildItem $frReports\Reports -filter *.mclog | where {$_.lastwritetime -lt (get-date).adddays(-$purgeAfter) -and -not $_.psiscontainer}
Push-Location -path D:\scratch\Reports
$filesToDelete | ForEach-Object {
$fname = ("'" + $_ + "'");
write-host $fname;
remove-item $fname -Force;
remove-item $_;
}
输出:
'lrFR_WebHelp - Friday, February 28, 2014 [9.00 PM].mclog'
'lrFR_WebHelp - Friday, March 14, 2014 [10.24 PM].mclog'
但不删除文件。
$fso = New-Object -ComObject Scripting.FileSystemObject
$buildBase = "D:\scratch";
$logFolders = Get-ChildItem $buildBase -Recurse -include Reports -Attributes D
$logFolders | ForEach-Object { Get-ChildItem $fso.GetFile($_.FullName).ShortPath -filter *.MCL | where {$_.lastwritetime -lt (get-date).adddays(-$purgeAfter) -and -not $_.psiscontainer}} #|% {write-host $_.fullname} };
输出:
Exception calling "GetFile" with "1" argument(s): "Exception from HRESULT: 0x800A0035 (CTL_E_FILENOTFOUND)"
At line:1 char:32
+ $logFolders | ForEach-Object { Get-ChildItem $fso.GetFile($_.FullName).ShortPath ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ComMethodTargetInvocation
在PowerShell中获取有关$ fso.GetFile的更多信息没有任何运气。谷歌这次让我失望了。
有人可以帮忙吗?我更喜欢纯粹的PowerShell解决方案,但对任何有效的方法都会感激不尽。
答案 0 :(得分:2)
您的问题是由文件名中的方括号引起的。当您将带有路径的字符串传递给Remove-Item
的(隐式)-Path
参数时,方括号将被解释为wildcard characters。因此,子字符串[9.00 PM]
将匹配M
,P
,9
,0
,点或空格的单个字符。您可以使用-LiteralPath
代替-Path
来通过更改此内容来避免此行为:
... | % { Remove-Item $_.FullName -Force }
进入这个:
... | % { Remove-Item -LiteralPath $_.FullName -Force }
但是,Remove-Item
接受管道输入,因此您可以完全放弃循环并直接从管道中读取项目:
... | Remove-Item -Force
这样Remove-Item
从Get-ChildItem
获取整个FileInfo
对象并自动执行The Right Thing™。
作为旁注:您可以通过删除循环来进一步简化代码,因为不仅Remove-Item
从管道读取,还Get-ChildItem
。像这样的东西应该可以正常工作:
$limit = (Get-Date).AddDays(-$purgeAfter)
Get-ChildItem $buildBase -Recurse -Include logs -Attributes D |
Get-ChildItem -Filter *.mclog |
Where-Object { $_.LastWriteTime -lt $limit -and -not $_.PSIsContainer } |
Remove-Item -Force