在PowerShell中检查路径是文件夹还是文件

Ste*_*ell 6 powershell

我正在尝试编写一个PowerShell脚本,该脚本将遍历值列表(文件夹或文件路径),然后首先删除文件,然后删除空文件夹。

到目前为止,我的脚本是:

[xml]$XmlDocument = Get-Content -Path h:\List_Files.resp.xml
$Files =  XmlDocument.OUTPUT.databrowse_BrowseResponse.browseResult.dataResultSet.Path
Run Code Online (Sandbox Code Playgroud)

现在,我尝试测试变量中的每一行,以查看它是否是文件,然后首先将其删除,然后遍历并删除子文件夹和文件夹。这只是一个干净的过程。

我不太想让这下一个工作,但我认为我需要类似的东西:

foreach ($file in $Files)
{
    if (! $_.PSIsContainer)
    {
        Remove-Item $_.FullName}
    }
}
Run Code Online (Sandbox Code Playgroud)

下一部分可以清理子文件夹和文件夹。

有什么建议么?

Ali*_*cia 24

我找到了一个解决这个问题的方法:使用Test-Path参数-FileType等于的cmdletLeaf检查它是否是一个文件或Container检查它是否是一个文件夹:

# Check if file (works with files with and without extension)
Test-Path -Path 'C:\Demo\FileWithExtension.txt' -PathType Leaf
Test-Path -Path 'C:\Demo\FileWithoutExtension' -PathType Leaf

# Check if folder
Test-Path -Path 'C:\Demo' -PathType Container
Run Code Online (Sandbox Code Playgroud)

演示

我最初在这里找到了解决方案。官方参考在这里

  • 这完全是一个**灾难**的答案,“Container”和“Leaf”担心regkeys不是目录或文件! (5认同)
  • 正如 [@muhammad-murad-haider](/sf/answers/4767758831/) 所说,唯一正确的方法是 `(get-item "C:\somefolder").PSIsContainer` (2认同)

Muh*_*der 11

我们可以使用get-item命令并提供路径。然后您可以检查PSIsContainer(布尔)属性,该属性将确定提供的路径是否针对文件夹或文件。例如

$target = get-item "C:\somefolder" # or "C:\somefolder\somefile.txt"
if($target.PSIsContainer) {
# it's a folder
}
else { #its a file }
Run Code Online (Sandbox Code Playgroud)

希望这对未来的访客有所帮助。


Jos*_*efZ 6

我认为你的$Files对象是一个字符串数组:

PS D:\PShell> $Files | ForEach-Object {"{0} {1}" -f $_.Gettype(), $_}
System.String D:\PShell\SO
System.String D:\PShell\SU
System.String D:\PShell\test with spaces
System.String D:\PShell\tests
System.String D:\PShell\addF7.ps1
System.String D:\PShell\cliparser.ps1
Run Code Online (Sandbox Code Playgroud)

不幸的是,该属性无法在字符串PSIsContainer对象上找到,而是在文件系统对象上找到,例如

PS D:\PShell> Get-ChildItem | ForEach-Object {"{0} {1}" -f $_.Gettype(), $_}
System.IO.DirectoryInfo SO
System.IO.DirectoryInfo SU
System.IO.DirectoryInfo test with spaces
System.IO.DirectoryInfo tests
System.IO.FileInfo addF7.ps1
System.IO.FileInfo cliparser.ps1
Run Code Online (Sandbox Code Playgroud)

要从字符串获取文件系统对象:

PS D:\PShell> $Files | ForEach-Object {"{0} {1}" -f (Get-Item $_).Gettype(), $_}
System.IO.DirectoryInfo D:\PShell\SO
System.IO.DirectoryInfo D:\PShell\SU
System.IO.DirectoryInfo D:\PShell\test with spaces
System.IO.DirectoryInfo D:\PShell\tests
System.IO.FileInfo D:\PShell\addF7.ps1
System.IO.FileInfo D:\PShell\cliparser.ps1
Run Code Online (Sandbox Code Playgroud)

尝试下一个代码片段:

$Files | ForEach-Object 
  {
    $file = Get-Item $_               ### string to a filesystem object
    if ( -not $file.PSIsContainer)
        {
            Remove-Item $file}
        }
  }
Run Code Online (Sandbox Code Playgroud)


Pet*_*orf 4

考虑以下代码:

$Files = Get-ChildItem -Path $env:Temp

foreach ($file in $Files)
{
    $_.FullName
}

$Files | ForEach {
    $_.FullName
}
Run Code Online (Sandbox Code Playgroud)

ForEach-Object第一个 foreach 是用于循环的 PowerShell 语言命令,第二个 ForEach 是完全不同的 cmdlet的别名。

在 中ForEach-Object$_指向循环中的当前对象(从$Files集合中通过管道传入),但在第一个 foreach 中$_没有任何意义。

在 foreach 循环中使用循环变量$file

foreach ($file in $Files)
{
    $file.FullName
}
Run Code Online (Sandbox Code Playgroud)