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

问题描述

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

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

$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

但是,当我将$myList替换为环境变量$env:yourList

$myPath = "C:\temp\"
$env:yourList = 'Folder1', '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

解决方法

环境变量始终是单个字符串 ,因此您不能在其中存储 array (或任何其他数组) [string]以外的其他数据类型。

  • 注意:这超出了PowerShell的控制范围:环境变量是系统级功能。

PowerShell 赋值 [1] 上的输入数组进行字符串化,这意味着使用空格作为分隔符将数组元素连接起来(或者,如果已定义,则分隔符存储在首选项变量$OFS中,这就是为什么数组'Folder1','Folder2','Folder3'变成单个字符串的原因
'Folder1 Folder2 Folder3'


如果您确实确实需要一个 environment 变量来存储您的数组-通常仅在将值传达给子进程时才需要-您必须选择一个-在 assignment 上的字符串表示形式,您可以在 reading 变量上将其重新转换为数组;例如:

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

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

[1]正如Doug Maurer所指出的那样,此自动字符串转换 any 尚未为{ {1}},例如[string](分配字符串$env:yourList = 42)。换句话说:您分配给环境变量的任何内容都会自动转换为(单个)字符串。