PS D:\PShell> Get-Command -All -ParameterName 'stream' | Format-Table -AutoSize -Wrap
CommandType Name ModuleName
----------- ---- ----------
Cmdlet Add-Content Microsoft.PowerShell.Management
Cmdlet Clear-Content Microsoft.PowerShell.Management
Cmdlet Get-Content Microsoft.PowerShell.Management
Cmdlet Get-Item Microsoft.PowerShell.Management
Cmdlet Out-String Microsoft.PowerShell.Utility
Cmdlet Remove-Item Microsoft.PowerShell.Management
Cmdlet Set-Content Microsoft.PowerShell.Management
Todos os cmdlet acima devem funcionar bem com fluxos de dados alternativos associados a um arquivo, uma pasta ou um disco se você souber um nome de fluxo . Infelizmente, Get-ChildItem
cmdlet não está listado, pois não permite o parâmetro -Stream
. Por outro lado, pode-se enumerar fluxos de dados alternativos arquivo usando Get-Item
para FileSystem que diz sobre o parâmetro -Stream
:
Gets the specified alternate NTFS file stream from the file. Enter the
stream name. Wildcards are supported. To get all streams, use an
asterisk (*
). This parameter is not valid on folders.
Sem usar um utilitário externo como streams.exe
do Sysinternals , você pode enumerar todos os dados alternativos fluxos de dados na linha de comando usando o comando dir /R
(Vista e superior) (e analisar a saída de . cmd /D /C dir /R
no PowerShell ).
Infelizmente, dir /R
não funciona junto com a opção /B
. Além disso,
-
dir /R /A:-D
retorna todos os fluxos (arquivos de dados regulares e nomes de anúncios) para arquivos,
-
dir /R /A:D
retorna todos os fluxos (nomes de pasta e ADS) para pastas, exceto pasta / disco raiz,
-
dir /R
retorna todos os nomes (regulares e ADSs) para arquivos e pastas exceto pasta / disco raiz .
Escrevi dois scripts .BAT
que analisam dir /R
e podem formatar a saída como CSV
:
-
ADSdisk.bat [/CSVformat]
retorna nomes de anúncios para todos os discos ativos (locais) e
-
ADSdir.bat [drive:][path][filename] [/S] [/A[[:]attributes]] [/CSVformat]
retorna apenas os nomes de anúncios correspondentes aos parâmetros DIR
.
Exemplo de uso no PowerShell :
PS D:\PShell> . D:\bat\ADSdisk.bat /CSVformat
"streamName",streamSize,"filePath"
"ADS_disk_root.txt",36,"D:\"
# comment: ADS on D:\ "..:ADS_disk_root.txt:$DATA"
# comment: no ADS on F:\
# comment: no ADS on C:\
# comment: no ADS on E:\
PS D:\PShell> (. D:\bat\ADSdisk.bat /CSVformat) | ConvertFrom-Csv
streamName streamSize filePath
---------- ---------- --------
ADS_disk_root.txt 36 D:\
PS D:\PShell> (. D:\bat\ADSdir.bat d:\ba* /CSVformat) | ConvertFrom-Csv
streamName streamSize filePath
---------- ---------- --------
alternate.data.stream.txt 46 d:\BAsoftwarelist.csv
alternate.data.stream.txt 23 d:\bat
PShell.txt 34 d:\bat
star.bat 12 d:\bat
star.txt 23 d:\bat
PS D:\PShell>
ADSdisk.bat
script :
@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "_keyword=Directory"
set "_CSVformat="
set "_firstLine="
set _filePath=%*
if defined _filePath (
for %%G in ( %_filePath% ) do (
if /I %%G == /CSVformat (
set _filePath=%_filePath:/CSVformat=%
set "_CSVformat=/CSVformat"
)
)
)
set "_property=DeviceID^,DriveLetter^,DriveType^,FileSystem^,SystemName"
for /F "skip=1 tokens=1-4,*" %%G in ('
wmic volume where "FileSystem LIKE '_%%' and DriveLetter LIKE '_:'" get %_property%
') do (
if not "%%H"=="" (
rem echo(# comment: %%H %%I %%J %%G
set "_subFolder="
set "_subDisk=%%~H\"
for /F "delims=" %%g in ( 'dir /B /A:D /A /O:-N "%%~H\"') do set "_subFolder=%%~g"
if defined _subFolder (
call :findADSroot
if not defined _fileName (
call echo(# comment: no ADS on %%_subDisk%%
) else (
call echo(# comment: ADS on %%_subDisk%% "%%_fileName%%"
)
) else (
echo(# comment: no subfoler under "%%~H\"
)
)
)
ENDLOCAL
goto :eof
:findADSroot
set "_pass="
set "_filePath=%_subDisk%%_subFolder%"
rem echo(# comment: ===testing=== "%_filePath%\"
set "_fileName="
for /F "tokens=1,*" %%G in ('
dir /-C /R /S /A "%_filePath%" ^| findstr /I /R "\.\.:.*:\$DATA ^.%_keyword%"
') do (
set "_fileSize="
if "%%~G"=="%_keyword%" (
if defined _pass goto :eof
for /F "tokens=1,*" %%g in ("%%~H") do set "_fileRoot=%%~h"
set /A _pass +=1
) else (
set "_fileSize=%%~G"
set "_fileName=%%~H"
)
if defined _fileSize call :outputDisk
)
goto :eof
:outputDisk
if defined _CSVformat (
REM csv output:
if not defined _firstLine echo "streamName",streamSize,"filePath"
for /F "tokens=1-3 delims=:" %%g in ("%_fileName%") do (
echo "%%~h",%_fileSize%,"%_subDisk%"
)
) else (
REM alternative output: streamSize,"streamFullPath"
echo %_fileSize% "%_subDisk%%_fileName:~2%"
)
set /A _firstLine += 1
goto :eof
ADSdir.bat
script :
@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
set "_keyword=Directory"
set "_CSVformat="
set "_firstLine="
set _filePath=%*
if defined _filePath (
for %%G in ( %_filePath% ) do (
if /I %%G == /CSVformat (
set _filePath=%_filePath:/CSVformat=%
set "_CSVformat=/CSVformat"
)
)
)
if not defined _filePath set "_filePath=/S "%CD%""
call :findADS
ENDLOCAL
goto :eof
:findADS
for /F "tokens=1,*" %%G in ('
dir /-C /R %_filePath% ^| findstr /I /R ":.*:\$DATA ^.%_keyword%"
') do (
set "_fileSize="
if "%%~G"=="%_keyword%" (
for /F "tokens=1,*" %%g in ("%%~H") do set "_fileRoot=%%~h"
call :backslash
) else (
set "_fileSize=%%~G"
rem for /F "tokens=1,*" %%g in ("%%~G") do
set "_fileName=%%~H"
call :testdots
)
if defined _fileSize call :output
)
goto :eof
:backslash
set "_backslash=%_fileRoot:~-1%"
if "%_backslash%"=="\" (set "_backslash=") else set "_backslash=\"
rem echo %~0 %_fileRoot:~-1%==%_backslash%
rem pause
goto :eof
:testdots
rem "." = a folder itself
if "%_fileName:~0,2%"==".:" set "_fileSize="
rem ".." = parent folder
if "%_fileName:~0,3%"=="..:" set "_fileSize="
goto :eof
:output
if defined _CSVformat (
REM csv output:
if not defined _firstLine echo "streamName",streamSize,"filePath"
for /F "tokens=1-3 delims=:" %%g in ("%_fileName%") do (
echo "%%~h",%_fileSize%,"%_fileRoot%%_backslash%%%~g"
)
) else (
REM alternative output: streamSize,"streamFullPath"
echo %_fileSize% "%_fileRoot%%_backslash%%_fileName%"
)
set /A _firstLine += 1
goto :eof