PowerShell foreach循环输出重定向至文件失败求助
问题:PowerShell foreach循环输出无法重定向到文件
问题场景
我尝试用以下PowerShell代码把foreach循环的输出写入文件:
PS C:\> foreach ( $dir in "c:\ProgramData", "c:\Program Files", "c:\Program Files (x86)" ) { echo "=> $dir :" ; dir -r -fo $dir 2>$null | % FullName | sls 'exe$' } > C:\temp\VDI_Exclustion_List.txt
错误现象
输出直接显示在控制台,同时报错:
> : The term '>' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At line:1 char:157 + ... ir :" ; dir -r -fo $dir 2>$null | % FullName | sls 'exe$' } > C:\temp ... + ~ + CategoryInfo : ObjectNotFound: (>:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException PS C:\> ls C:\temp\VDI_Exclustion_List.txt ls : Cannot find path 'C:\temp\VDI_Exclustion_List.txt' because it does not exist. At line:1 char:1 + ls C:\temp\VDI_Exclustion_List.txt + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (C:\temp\VDI_Exclustion_List.txt:String) [Get-ChildItem], ItemNotFoundException + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand PS C:\>
尝试过的方法及失败结果
- 替换
>为| Out-File C:\temp\VDI_Exclustion_List.txt,报错:
At line:1 char:138 + ... 6)" ) { dir -r -fo $dir 2>$null | % FullName | sls 'exe$' } | Out-Fil ... + ~ An empty pipe element is not allowed. + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : EmptyPipeElement PS C:\>
- 替换
>为6>&1 | Out-File C:\temp\VDI_Exclustion_List.txt,报错:
PS C:\> foreach ( $dir in "c:\ProgramData", "c:\Program Files", "c:\Program Files (x86)" ) { echo "=> $dir :" ; dir -r -fo $dir 2>$null | % FullName | sls 'exe$' } 6>&1 | Out-File C:\temp\VDI_Exclustion_List.txt ...... 6>&1 : The term '6>&1' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At line:1 char:157 + ... :" ; dir -r -fo $dir 2>$null | % FullName | sls 'exe$' } 6>&1 | Out-F ... + ~~~~ + CategoryInfo : ObjectNotFound: (6>&1:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException PS C:\>
期望结果是输出能写入C:\temp\VDI_Exclustion_List.txt,但文件始终未创建。
解决方法
问题核心:PowerShell中,独立的foreach语句(不是ForEach-Object cmdlet)不能直接在语句结尾使用重定向或管道。以下是两种可行方案:
方案1:用子表达式$()包裹foreach循环
子表达式会执行内部代码并收集所有输出,之后即可正常重定向或管道输出:
$(foreach ( $dir in "c:\ProgramData", "c:\Program Files", "c:\Program Files (x86)" ) { "=> $dir :" # 直接输出字符串,等价于Write-Output,会进入输出流 Get-ChildItem -Recurse -Force $dir 2>$null | Select-Object -ExpandProperty FullName | Select-String 'exe$' }) > C:\temp\VDI_Exclustion_List.txt
注意:如果用
Write-Host输出字符串,内容不会被重定向,因为它直接输出到主机控制台,不属于PowerShell的标准输出流。
方案2:改用ForEach-Object cmdlet(管道式循环)
把foreach语句改成管道驱动的ForEach-Object,可以直接在管道末尾添加重定向或Out-File:
"c:\ProgramData", "c:\Program Files", "c:\Program Files (x86)" | ForEach-Object { "=> $_ :" Get-ChildItem -Recurse -Force $_ 2>$null | Select-Object -ExpandProperty FullName | Select-String 'exe$' } > C:\temp\VDI_Exclustion_List.txt
额外提示
- 代码中
dir是Get-ChildItem的别名,%是ForEach-Object的别名,sls是Select-String的别名,使用全称可提升代码可读性。 - 确保
C:\temp目录存在,否则会报错路径不存在,可先执行New-Item -Path C:\temp -ItemType Directory -Force创建目录。
内容的提问来源于stack exchange,提问作者SebMa
相关产品推荐
相关产品推荐

