I'm trying to redirect a foreach loop output to a file with the following powershell code :
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
but the output is displayed on stdout and I get this error :
> : 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], ItemNotFoundEx
ception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
PS C:\>
First, I tried replacing the >
redirection by | Out-File C:\temp\VDI_Exclustion_List.txt
but that did not work :
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:\>
Then I tried replacing the >
redirection by 6>&1 | Out-File C:\temp\VDI_Exclustion_List.txt
(found here) but that did not work either :
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:\>
I expect the output to be inside the file C:\temp\VDI_Exclustion_List.txt but the file is not even created.
As you've already found, flow control statements can't be used in place of commands or value expressions - but you can wrap them in a scriptblock and then redirect the output from invoking that instead:
& {
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
That being said, you don't actually need a loop here!
You can pipe your input data directly to Get-ChildItem
, the files discovered by Get-ChildItem
can in turn be piped to Where-Object
to filter on their extension, at which point we can grab the FullName
property value from each resulting subset of files with the ForEach-Object
command:
"c:\ProgramData", "c:\Program Files", "c:\Program Files (x86)" |Get-ChildItem -Recurse -File -Force |Where-Object Extension -eq '.exe' |ForEach-Object FullName |Set-Content C:\temp\VDI_Exclustion_List.txt