无法使用环境变量使用 Powershell 过滤目录

Cannot filter Directories with Powershell using an environment variable

我在尝试过滤环境变量数组中设置的目录列表时遇到意外行为。

当我 运行 此代码使用局部变量时,我得到了预期的结果:

$myPath = "C:\temp\"
$myList = 'Folder1', 'Folder2', 'Folder3'
Write-Host "myList: $myList" 
Get-ChildItem -Recurse $myPath | Where-Object { $_.PSIsContainer } | Where-Object { $_.Name -in $myList } | Select-Object FullName

myList: Folder1 Folder2 Folder3

FullName
--------
C:\temp\Folder1
C:\temp\Folder2
C:\temp\Folder3

但是,当我用环境变量 $env:yourList

替换 $myList
$myPath = "C:\temp\"
$env:yourList = 'Folder1', 'Folder2', 'Folder3'
Write-Host "yourList: $env:yourList"
Get-ChildItem -Recurse $myPath | Where-Object { $_.PSIsContainer } | Where-Object { $_.Name -in $env:yourList } | Select-Object FullName

Get-ChildItem 的结果为空

yourList: Folder1 Folder2 Folder3
.

正如您从上面的输出中看到的,$env:yourList 中设置的值打印出来与 $myList 中设置的相同,所以 环境变量有什么特别之处 导致它们在 Where-Object 标准中被不同地处理?

顺便说一句,当使用 -Include 而不是 Where-Object 时会发生相同的行为,即:

Get-ChildItem -Path $myPath -Recurse -Include $env:yourList -Directory

一个环境变量总是一个单个字符串,所以你不能存储arrays 其中(或 [string] 以外的任何其他数据类型)。

  • 注意:这不在 PowerShell 的控制范围内:环境变量是一个 system-level 功能。

PowerShell stringifies assignment[1] 上的输入数组,这意味着加入以 space 作为分隔符的数组元素(或者,如果已定义,分隔符存储在首选项变量 $OFS 中),这就是数组 'Folder1', 'Folder2', 'Folder3' 变成单个字符串
的原因 'Folder1 Folder2 Folder3'.


如果您确实需要一个 environment 变量来存储您的数组 - 通常只需要将值传递给 子进程 -你必须在赋值上为它选择一个single-string表示,你可以re-convert到reading[=47=上的数组] 变量;例如:

# Assuming the array elements contain no newlines, use newlines
# to separate them.
$env:yourList = ('Folder1', 'Folder2', 'Folder3') -join "`n"

# Later, re-convert the single-string representation to an array.
$env:yourList -split "`n"

[1] 正如 Doug Maurer 指出的那样,这个 自动 to-string 转换 发生在 any RHS 还不是 [string] 类型,例如 $env:yourList = 42(分配字符串 '42')。换句话说:您分配给环境变量的任何内容都会自动转换为(单个)字符串。