在Remove-Item中使用Variable返回“名称为'E'的驱动器不存在”

时间:2016-08-10 06:18:04

标签: powershell

我一直在编写一个脚本,用于搜索“Archive”文件夹中的特定文件夹,然后将其拉链。文件夹成功压缩后,我希望将其删除。

但是,我遇到了Remove-Item cmdlet返回错误的问题“当我使用foreach命令和变量时,”名称为'E'的驱动器不存在“

如果我使用变量手动运行Remove-Item命令,则不会发生问题。

请让我知道为什么会这样,以及如何阻止它发生。

以下是代码:

# Get list of archive folders
$ArchiveFolders = Get-ChildItem \*\*\* |
                  ?{ $_.PSIsContainer } |
                  Where-Object{ $_.Name -eq "_Archived"} | select FullName

# For each archive folder check which subfolders exist within it
foreach ($folder in $ArchiveFolders) {
  (Get-ChildItem $folder.FullName | ?{ $_.PSIsContainer } | select FullName | ConvertTo-Csv -NoTypeInformation) |
    Select-Object -Skip 1 |
    Add-Content -Path e:\scripts\subfolders.csv
}

# Get list of Subfolders
$ArchiveSubFolders = Get-Content e:\scripts\subfolders.csv

# Select each Subfolder
foreach ($subfolder in $ArchiveSubFolders){
  # Move each subfolder to a 7z Archive with the highest compression rate available
  $pinfo = New-Object System.Diagnostics.ProcessStartInfo
  $pinfo.FileName = "7z.exe"
  $pinfo.RedirectStandardError = $true
  $pinfo.RedirectStandardOutput = $true
  $pinfo.UseShellExecute = $false
  $pinfo.Arguments = "a -mx=9 -t7z $subfolder.7z $subfolder"
  $p = New-Object System.Diagnostics.Process
  $p.StartInfo = $pinfo
  $p.Start() | Out-Null
  $p.WaitForExit()

  # Check Archive was created successfully and then delete the subfolder
  if ($p.ExitCode -eq "0") {
    Remove-Item -Path $subfolder -Force -Recurse
  } else {
    Write-Host "$subfolder has not been deleted"
  }
}

1 个答案:

答案 0 :(得分:1)

PowerShell CSV导出/转换会在字段周围添加双引号。由于您通过$('input[type="number"]').on('propertychange change keyup input paste', function(){ console.log('change'); }); 读取了CSV输出,因此在导入时会保留双引号,因此您可以获得路径Get-Content而不是"E:\foo"。这可能适用于构造外部命令,但它不适用于PowerShell cmdlet,因为没有驱动器E:\foo(带有前导双引号)。将引号作为值的一部分通常是一个坏主意。你最好不要在没有qoutes的情况下保留这些值,并在需要的地方添加引号。

"E:

话虽如此,您甚至不需要大部分代码。您可以通过将原始路径表达式更改为$ArchiveSubFolders = foreach ($folder in $ArchiveFolders) { Get-ChildItem $folder.FullName | Where-Object { $_.PSIsContainer } | Select-Object -Expand FullName } 来获取所需的子文件夹,然后使用该\*\*\*\_Archived\*运行一个Get-ChildItem。我还建议放弃System.Diagnostics.Process方法并改为使用调用运算符(&)。

Get-ChildItem '\*\*\*\_Archived\*' | Where-Object {
  $_.PSIsContainer
} | Select-Object -Expand FullName | ForEach-Object {
  & 7z.exe a -mx=9 -t7z "$_.7z" "$_"
  if ($LastExitCode -eq 0) {
    Remove-Item -Path $_ -Force -Recurse
  } else {
    Write-Host "$subfolder has not been deleted"
  }
}