[玩转系统] PowerShell 和备用数据流的周五乐趣
作者:精品下载站 日期:2024-12-14 08:06:13 浏览:16 分类:玩电脑
PowerShell 和备用数据流的周五乐趣
我一直对交替数据流有着一种特殊的迷恋。这是一项已经存在很长时间的 NTFS 功能。该功能也称为 ADS,允许用户将数据写入文件的隐藏分支。您几乎可以在备用数据流中存储任何内容,而不会影响报告的文件大小。与任何事情一样,总是有可能受到虐待或更糟的情况。但我假设你有足够的安全措施。您无法禁用 ADS,所以也许我们可以用它做一些有用的事情。
寻找流
第一步是学习如何识别文件中的备用数据流。您可以使用 Get-Item 和 Streams 参数。幸运的是,该参数接受通配符。
流 :$DATA 是文件内容的默认流。您会在每个文件上找到它。这是一个包含第二个数据流的文件。
我将这个简单的 PowerShell 脚本放在一起,以便更轻松地识别额外的备用数据流。
#requires -version 5.1
Param([string]$Path = "*.*")
Get-Item -Path $path -stream * | Where-Object {$_.stream -ne ':$DATA'} |
Select-Object @{Name="Path";Expression = {$_.filename}},
Stream,@{Name="Size";Expression={$_.length}}
获取流内容
我可以看到这些文件有备用数据流。但它们里面有什么?我们看看吧。
Stream 参数不接受通配符,因此您需要提前知道名称。没问题。我将使用我的脚本。
C:\scripts\Get-AlternateDataStream.ps1 .\*.db | Select Path,Stream,@{Name="Content";Expression={Get-Content $_.path -stream $_.stream}}
您可以轻松地将我的代码转换为 PowerShell 函数。
创建备用数据流
要创建您自己的备用数据流,您可以使用其他内容 cmdlet。
dir *.zip | Set-Content -Stream "source" -value "over the rainbow"
我们可以存储什么样的独立于文件内容的信息?版本号怎么样?
set-content .\Get-AboutOnline.ps1 -Stream version -Value "0.9.0"
或者也许是作者信息?
set-content .\Get-AboutOnline.ps1 -Stream author -Value "Jeff Hicks"
添加此信息不会更改文件内容,也不会更改文件大小。但它会更新 LastModfiedTime。
清除流
您可以轻松清除流的内容。
clear-content .\vm.db -Stream secret
溪流本身什么也没有留下。要完全删除流,请使用Remove-Item。
remove-item .\vm.db -Stream secret
使用备用数据流编写脚本
有了这些信息,为什么不构建一些工具来通过我们的 PowerShell 脚本使用备用数据流呢?我围绕 Set-Content 编写了一个包装函数来添加版本备用数据流。
Function Set-VersionStream {
[cmdletbinding(SupportsShouldProcess)]
Param(
[Parameter(
Position = 0,
Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
HelpMessage = "Specify a file path."
)]
[ValidateScript({ (Test-Path $_) -AND ((Get-Item $_).psprovider.name -eq 'FileSystem') })]
[Alias("fullname")]
[string[]]$Path,
[parameter(Mandatory, HelpMessage = "Specify a version string")]
[alias("version")]
[string]$Value,
[Parameter(HelpMessage = "Specify the name of the version stream. The default is 'versionInfo'.")]
[string]$Stream
)
Begin {
Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($myinvocation.mycommand)"
if (-Not ($psboundparameters.containskey["Stream"])) {
$psboundparameters.Add("Stream", "versionInfo")
}
} #begin
Process {
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Adding version $value to stream $($psboundparameters['Stream']) in $Path"
Set-Content @psboundparameters
} #process
End {
Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($myinvocation.mycommand)"
} #end
} #close Set-VersionStream
默认流名称是 versionInfo,但您可以指定其他名称或修改代码。
我可以对作者信息做类似的事情。
Function Set-AuthorStream {
[cmdletbinding(SupportsShouldProcess)]
Param(
[Parameter(
Position = 0,
Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
HelpMessage = "Specify a file path."
)]
[ValidateScript({ (Test-Path $_) -AND ((Get-Item $_).psprovider.name -eq 'FileSystem') })]
[Alias("fullname")]
[string[]]$Path,
[parameter(Mandatory, HelpMessage = "Specify an author string")]
[alias("author")]
[string]$Value,
[Parameter(HelpMessage = "Specify the name of the author stream. The default is 'authorInfo'")]
[string]$Stream
)
Begin {
Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($myinvocation.mycommand)"
if (-Not ($psboundparameters.containskey["Stream"])) {
$psboundparameters.Add("Stream", "authorInfo")
}
} #begin
Process {
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Adding author $value to stream $($psboundparameters['Stream']) in $Path"
Set-Content @psboundparameters
} #process
End {
Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($myinvocation.mycommand)"
} #end
} #close Set-AuthorStream
该函数接受管道输入,因此我可以快速在多个文件上设置它。
dir *.ps1 | Set-AuthorStream -Value "Jeff Hicks"
由于我有一个命令来设置该值,因此使用一个命令来获取该值可能会很方便,并且可以做的不仅仅是给我一个简单的字符串。
Function Get-AuthorStream {
[cmdletbinding()]
Param(
[Parameter(
Position = 0,
Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
HelpMessage = "Specify a file path."
)]
[ValidateScript({ (Test-Path $_) -AND ((Get-Item $_).psprovider.name -eq 'FileSystem') })]
[Alias("fullname")]
[string[]]$Path,
[Parameter(HelpMessage = "Specify the name of the author stream. The default is 'authorInfo'")]
[string]$Stream
)
Begin {
Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($myinvocation.mycommand)"
$splat = @{
ErrorAction = "Stop"
}
if ($psboundparameters.containskey["Stream"]) {
$splat.Add("Stream", $psboundparameters.containskey["Stream"])
}
else {
$splat.Add("Stream", "authorInfo")
}
} #begin
Process {
foreach ($item in $path) {
$splat['Path'] = Convert-Path $item
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Getting author stream $($psboundparameters['Stream']) from $item"
Try {
$info = Get-Content @splat
[pscustomobject]@{
Path = $splat.path
AuthorInfo = $info
}
}
Catch {
Write-Warning "The stream $Stream was not found on $path"
}
}
} #process
End {
Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($myinvocation.mycommand)"
} #end
} #close get-AuthorStream
但是,由于我可以在备用数据流中存储的内容没有限制,为什么不存储更丰富的内容呢?看起来像这样的东西:
我编写了一个概念验证函数,将此信息作为 JSON 存储在备用数据字符串中。
Function Set-AuthorStreamJson {
[cmdletbinding(SupportsShouldProcess)]
Param(
[Parameter(
Position = 0,
Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
HelpMessage = "Specify a file path."
)]
[ValidateScript({ (Test-Path $_) -AND ((Get-Item $_).psprovider.name -eq 'FileSystem') })]
[Alias("fullname")]
[string[]]$Path,
[parameter(Mandatory, HelpMessage = "Specify an author name")]
[string]$Author,
[parameter(Mandatory)]
[string]$Company,
[parameter(Mandatory)]
[string]$Version,
[string]$Comment,
[Parameter(HelpMessage = "Enter the creation tile. It will saved as a UTC formatted string")]
[datetime]$Created = (Get-Date),
[Parameter(HelpMessage = "Specify the name of the author stream. The default is 'authorInfo'")]
[string]$Stream
)
Begin {
Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($myinvocation.mycommand)"
$splat = @{
ErrorAction = "Stop"
}
if ($psboundparameters.containskey["Stream"]) {
$splat.Add("Stream", $psboundparameters["Stream"])
}
else {
$splat.Add("Stream", "authorInfo")
}
$json = [PSCustomObject]@{
Author = $author
Company = $company
Version = $version
Created = "{0:u}" -f $created
Comment = $comment
} | ConvertTo-Json
} #begin
Process {
foreach ($item in $Path) {
$splat["Path"] = Convert-Path $item
$splat["Value"] = $json
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Adding author information for $author to stream $($splat['Stream']) in $item"
write-verbose $json
Set-Content @splat
}
} #process
End {
Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($myinvocation.mycommand)"
} #end
} #close Set-AuthorStreamJson
该流是一个 JSON 字符串,我可以将其转换为对象。或者我可以使用 PowerShell 函数。
Function Get-AuthorStreamJson {
[cmdletbinding()]
Param(
[Parameter(
Position = 0,
Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
HelpMessage = "Specify a file path."
)]
[ValidateScript({ (Test-Path $_) -AND ((Get-Item $_).psprovider.name -eq 'FileSystem') })]
[Alias("fullname")]
[string[]]$Path,
[Parameter(HelpMessage = "Specify the name of the author stream. The default is 'authorInfo'")]
[string]$Stream
)
Begin {
Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($myinvocation.mycommand)"
$splat = @{
ErrorAction = "Stop"
}
if ($psboundparameters.containskey["Stream"]) {
$splat.Add("Stream", $psboundparameters["Stream"])
}
else {
$splat.Add("Stream", "authorInfo")
}
} #begin
Process {
foreach ($item in $path) {
$splat['Path'] = Convert-Path $item
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Getting author stream $($splat.stream) from $item"
Try {
$info = Get-Content @splat
$out = $info | ConvertFrom-Json
$out | Add-Member -MemberType NoteProperty -Name Path -Value $splat.path -PassThru
}
Catch {
Write-Warning "The stream $($splat.stream) was not found on $path"
}
}
} #process
End {
Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($myinvocation.mycommand)"
} #end
} #close get-AuthorStreamJson
该函数将为缺少流的文件显示警告,因此我在本示例中抑制警告消息。
最后,添加标签怎么样?
Function Add-TagStream {
[cmdletbinding(SupportsShouldProcess)]
Param(
[Parameter(
Position = 0,
Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
HelpMessage = "Specify a file path."
)]
[ValidateScript({ (Test-Path $_) -AND ((Get-Item $_).psprovider.name -eq 'FileSystem') })]
[Alias("fullname")]
[string[]]$Path,
[parameter(Mandatory, HelpMessage = "Specify a set of tags")]
[alias("tag")]
[string[]]$Value,
[Parameter(HelpMessage = "Specify the name of the Tags stream. The default is 'tags'.")]
[string]$Stream
)
Begin {
Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($myinvocation.mycommand)"
if (-Not ($psboundparameters.containskey["Stream"])) {
$psboundparameters.Add("Stream", "tags")
}
} #begin
Process {
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Adding Tags $($value -join ',') to stream $($psboundparameters['Stream']) in $Path"
Set-Content @psboundparameters
} #process
End {
Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($myinvocation.mycommand)"
} #end
} #close Add-Tagstream
使用此命令可以轻松添加标签。
dir *.csv,*.db | Add-TagStream -tag "data","company"
当然,我想要一种简单的方法来获取标签流。
Function Get-TagStream {
[cmdletbinding()]
Param(
[Parameter(
Position = 0,
Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName,
HelpMessage = "Specify a file path."
)]
[ValidateScript({ (Test-Path $_) -AND ((Get-Item $_).psprovider.name -eq 'FileSystem') })]
[Alias("fullname")]
[string[]]$Path,
[Parameter(HelpMessage = "Specify the name of the tag stream. The default is 'tags'")]
[string]$Stream
)
Begin {
Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($myinvocation.mycommand)"
$splat = @{
ErrorAction = "Stop"
}
if ($psboundparameters.containskey["Stream"]) {
$splat.Add("Stream", $psboundparameters["Stream"])
}
else {
$splat.Add("Stream", "tags")
}
} #begin
Process {
foreach ($item in $path) {
$splat['Path'] = Convert-Path $item
Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Getting tags stream $($splat['Stream']) from $item"
Try {
$info = Get-Content @splat
[pscustomobject]@{
Path = $splat.path
Tags = $info
}
}
Catch {
Write-Warning "The stream $($splat['Stream']) was not found on $path"
}
}
} #process
End {
Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($myinvocation.mycommand)"
} #end
} #close Get-TagStream
使用此命令,可以轻松根据标签查找文件。
如何使用备用数据流是没有止境的,欢迎您使用我的代码作为框架。我的功能应该被视为概念验证,而不是生产就绪。
局限性
但在你兴奋之前,交替数据流是有限制的。此功能仅在 Windows 和 NTFS 格式的驱动器上受支持。如果将包含备用数据流的文件从一个 NTFS 驱动器复制到另一个 NTFS 驱动器,则这些流也应该复制。但如果将文件复制到非 NTFS 驱动器,您将丢失流。
如果您备份或归档文件,您还可能会丢失备用数据流。然而,值得研究一下设置。我使用 WinRar,该应用程序有一个保存文件流的设置。
最后,如果您与 OneDrive 或 DropBox 等云服务同步文件,预计会丢失备用数据流。我无法找到任何方法来配置这些服务以包含备用数据流。如果你知道一种方法,我很想听听。
概括
我希望您会发现这一点很有趣,并积极思考如何利用此功能。正如我希望您已经看到的那样,围绕备用数据流构建 PowerShell 工具并不那么困难。如果您发现 ADS 的用途,希望您告诉我。
顺便说一句,除了 PowerShell 之外,您还可以使用 SysInternals 中的 Streams.exe 实用程序来列出和删除备用数据流。
享受这个乐趣,并请使用非生产文件进行测试。享受。
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag