Powershell - List all alternate data stream information from one directory

12.2k Views Asked by At

My end goal here is to cd to a directory in powershell and then list all the alternate data stream files, then output all their content to a CSV.

I currently have the first two parts scripted:

cd c:\users\profilename\downloads\
gci -recurse | % { gi $_.FullName -stream * } | where stream -ne ':$Data'

To open an example data stream file, open cmd, cd to a directory, then run:

dir /r

After this, grab the zone identified name of one of the files and run this command without the :$data.

Example before removing :$Data

notepad test.docx:Zone.Identifier:$Data

After removing(run this command):

notepad test.docx:Zone.Identifier

How would I go about taking the output of the second command and using the PSPath field to open each of these files and then output all the contents in to one CSV file?

Any help is greatly appreciated.

3

There are 3 best solutions below

1
On

I think this might be close to what you want:

$files = gci -recurse | % { gi $_.FullName -stream * } | where stream -ne ':$Data' | select filename,stream,@{'name'='identifier';"e"={"$($_.filename)$($_.stream)"}}

Broken into multi-lines for legibility:

$files = Get-ChildItem -Recurse | 
    Where-Object { Get-Item $_.FullName -Stream * } | 
    Where-Object {$_.Stream -ne ':$Data'} | 
    Select-Object -Properties filename, stream, @{'name'='identifier';"e"={"$($_.filename)$($_.stream)"}}
0
On

Presuming your are after the Stream content:

## Q:\Test\2018\11\19\SO_53380498.ps1
Pushd $ENV:USERPROFILE\Downloads
Get-ChildItem -Recurse | ForEach-Object {
  Get-Item $_.FullName -Stream *
} | Where-Object Stream -ne ':$Data' | 
      Select-Object FileName,Stream,
        @{n='CreationTime';e={(Get-Item $_.FileName).CreationTime}},
        @{n='LastWriteTime';e={(Get-Item $_.FileName).LastWriteTime}},
        @{n='Content';e={gc "$($_.FileName):$($_.Stream)"}} |
          Export-Csv Streams.csv -NoTypeInformation

Shorted output of the generated Streams.csv file
(date format depends on locale/user settings):

> gc .\Streams.csv
"FileName","Stream","CreationTime","LastWriteTime","Content"
"C:\Users\LotPings\Downloads\2018-06-27-raspbian-stretch.zip","Zone.Identifier","2018-07-29 22:13:03","2018-07-29 22:16:41","[ZoneTransfer] ZoneId=3"

If your final destination for the csv supports multiline fields, you could do -join "`n" on the content.

0
On

As ADS may contain binary data, I would not dump it into a text file, especially not into a formatted text file like CSV. To view the content of ADS, you can display a hexdump of its content, e. g.:

Get-ChildItem -Recurse | Get-Item -Stream * | ? {$_.Stream -ne ':$DATA'} | % {
  Write-Host "`n`n$($_.FileName):$($_.Stream)" -NoNewline
  Get-Content -LiteralPath $_.FileName -Stream $_.Stream -Raw | Format-Hex
}

This solution will also work for UNC paths, like paths to a network share.