Powershell 使用remove-item cmdlet时找不到路径
我编写了一个简单的PowerShell脚本,它将目录备份到Powershell 使用remove-item cmdlet时找不到路径,powershell,Powershell,我编写了一个简单的PowerShell脚本,它将目录备份到C:\,然后在备份文件夹的期限=X天时删除任何备份文件夹 由于某些原因,当我使用删除项cmdlet时,我得到一个删除项:找不到路径“C:\Windows\system32\[Sub Folder name]”,因为它不存在错误 以下是片段: $TargetFolder = "C:\Folder\" $Folders = get-childitem -path $TargetFolder foreach ($Fold
C:\
,然后在备份文件夹的期限=X天时删除任何备份文件夹
由于某些原因,当我使用删除项
cmdlet时,我得到一个删除项:找不到路径“C:\Windows\system32\[Sub Folder name]”,因为它不存在
错误
以下是片段:
$TargetFolder = "C:\Folder\"
$Folders = get-childitem -path $TargetFolder
foreach ($Folder in $Folders)
{
remove-item $Folder -recurse -force
}
在$TargetFolder=“C:\Folder\”
中,有几个子文件夹。
示例:C:\Folder\SubfolderA
,C:\Folder\SubfolderB
,等等
当我为
$Folder
执行写入主机
时,它会正确地列出子文件夹a
,子文件夹B
等,因此我不清楚为什么会出现找不到路径
错误。尝试在完整路径上执行删除项,例如
$TargetFolder = "C:\Folder\"
$Folders = get-childitem -path $TargetFolder
foreach ($Folder in $Folders)
{
remove-item $TargetFolder$Folder -recurse -force
}
似乎您希望在目录LastWriteTime的基础上执行此操作,但在Get ChildItem上没有提到-directory
[cmdletbinding()]
Param()
$TargetFolder = "C:\Users\lit\Documents"
$Folders = Get-ChildItem -Path $TargetFolder -Directory
$Days = 80
foreach ($Folder in $Folders) {
if ($Folder.LastWriteTime -lt (Get-Date).AddDays(-$Days)) {
Write-Verbose "Deleting directory $($Folder.FullName)"
Remove-Item -WhatIf "$($Folder.FullName)" -Recurse -Force
}
}
tl;dr
要确保Remove Item
正确标识由Get ChildItem
返回的目录对象(类型为[System.IO.DirectoryInfo]
):
- 将对象作为参数传递时,在Windows PowerShell(不再在PowerShell Core中)中,必须使用
。全名
命令才能可靠工作:
-LiteralPath
并不是严格需要的,但考虑到删除项$Folder,它是更可靠的选择。FullName
隐式绑定到-Path
参数,该参数将其参数解释为通配符表达式;通常情况下,这没有什么区别,但它可以
- 使用管道时,可以按原样传递对象
Get-ChildItem -Directory | Remove-Item ...
.FullName
的惊人需求是一种设计怪癖的结果;由此产生的行为及其含义如下所述;已在中提出解决方案
并包含解决方案的补充部分(此后,礼仪师的回答被修改为提供完整的解决方案):
- 要限制
返回目录(文件夹)的内容,必须使用Get ChildItem
(PSv3+)-Directory
- 要在将文件系统对象作为转换为字符串的参数传递给
时明确标识该对象,必须指定其完整路径Remove object
- 注意:下面描述的仅限文件名的字符串化仅影响Windows PowerShell幸运的是,问题已在PowerShell核心中得到修复
- 在本例中,假定
包含一个$Folder
对象,该对象由[System.IO.DirectoryInfo]
返回,Get ChildItem
是最简单的(但通过在$Folder.FullName
前面加上前缀来构造路径也很有效)$TargetPath
- 在Windows PowerShell中,即使
是一个$Folder
对象,但它确实包含完整的路径信息,当转换为字符串时,它在情况下只能扩展到其目录名(最后的路径组件)-这取决于[System.IO.DirectoryInfo]
-有关详细信息,请参阅。[System.IO.DirectoryInfo]的方式获得了
和
实例,即:[System.IO.FileInfo]
如果调用
时未使用路径参数或通过作为目录的路径参数,则输出对象将字符串化为其文件/目录名Get ChildItem
简单示例:
产生$d=(GetChildItem-目录$HOME)[0];例如,“$d”
,而不是联系人
C:\Users\jdoe\Contacts
- 相反,如果您通过管道将这些对象传递到
,PowerShell将使用完整路径删除项
- 相反,如果您通过管道将这些对象传递到
- 重要信息:如果您确实将目标文件夹作为参数传递,而忽略了指定完整路径,而目标文件夹不在同一位置,则名称可能因此被解释为相对于当前位置,并且您将得到一个
错误-如您所见-或者更糟,如果您的当前位置(目录)中碰巧存在同名的文件夹,则可能会删除该文件夹找不到路径
Get ChildItem
返回的文件夹对象管道化到Remove Item
来避免完整路径问题,这还可以实现更优雅的单管道解决方案(PSv3+):
删除
-WhatIf
以执行实际删除操作。那么为什么要这样做?为什么不删除Item-Recurse-Force$targetfolder?我不想删除$targetfolder中的所有内容。我只想删除已达到特定期限的备份文件夹。这是剧本@4c74356b41code$Now=Get Date$Days=“5”$TargetFolder=“C:\Folder\”$LastWrite=$Now.AddDays($Days)$Folders=Get childitem-path$TargetFolder |其中{$\.psContainer-eq$true}其中{$$$.LastWriteTime-le“$LastWrite”}foreach($Folders中的文件夹){Remove Item-path$Folder Recurse-Force}
code`好的,首先要使用get-childitem-directory,以避免另一个管道。另外,直接调用$now.adddays(获取日期).adddays也没有意义。另外,尝试在应该删除的项目中使用$folder.fullname。在我看来,你提供的代码示例只讲述了你想做的事情的一半,而且,如果你展示了整个图片,你可能会得到更好的帮助;实际上,PowerShell变量通常不需要双引号作为参数(除非它们嵌入到双引号字符串中),即使它们包含spac
Get-ChildItem -Directory | Remove-Item ...
$TargetFolder = "C:\Folder"
$Days = 5
Get-ChildItem -Directory $TargetFolder |
Where-Object LastWriteTime -lt (Get-Date).Date.AddDays(-$Days) |
Remove-Item -WhatIf -Force -Recurse