powershell 为什么“获取子项文件|获取文件哈希”的工作?

pbpqsu0x  于 2022-12-23  发布在  Shell
关注(0)|答案(3)|浏览(125)

我对Bash比Powershell更熟悉,有时我会被后者的对象模型搞糊涂。
查看documentation of Get-FileHash,似乎有3种指定输入的方式:

  • 获取文件哈希[-路径]
  • 获取文件哈希[-文本路径]
  • 获取文件哈希[-输入流]

前两个文件名,第三个数据流。
现在,Get-ChildItem -File似乎输出System.IO.FileInfo对象,从Get-Member的内容判断:

$ Get-ChildItem -File | Get-Member
TypeName: System.IO.FileInfo

然而Get-ChildItem -File | Get-FileHash管道工作正常,我的问题是,允许将System.IO.FileInfo转换为Get-FileHash所期望的输入类型的机制是什么?

yrwegjxp

yrwegjxp1#

PowerShell cmdlet输出的**System.IO.FileInfo/System.IO.DirectoryInfo示例具有.PSPath属性**[*],该属性包含示例的完全限定路径,即以PS提供程序名称为前缀的完整文件系统路径(例如Microsoft.PowerShell.Core\FileSystem::C:\windows)。

*文件处理 * cmdlet(如Get-FileHash)具有别名为-PSPath*-LiteralPath参数

由于-LiteralPath参数(通常)按属性名称 * 接受来自管道的输入,因此具有.PSPath属性的输入对象将自动通过PSPath参数别名绑定到该属性
顺便说一句:

  • 文件处理cmdlet还有一个**-Path**参数,该参数将其参数解释为wildcard expressions,而不是文本路径。
  • 当您通过管道将路径 * 字符串 * 传输到这样的cmdlet时,它们绑定到-Path,这特别意味着它们确实被解释为通配符-虽然这通常不重要,因为大多数文本路径不包含通配符元字符,但包含[]的路径却包含通配符元字符,这会被误解;为了避免这种误解,需要将它们转义为[`和]`,如this answer所示。
  • 由于 * Windows PowerShell * 中的错误(已在 * PowerShell(Core)7 +* 中修复),Get-FileHash尤其不接受通过管道 * 的字符串-请参阅this answer了解详细信息。
    • 如何发现**此行为:
  • 通过online help topic

  • 方案方面:
  • 注意:Get-Help Get-FileHash -Parameter LiteralPath | Select-Object name, aliases, pipelineinput也适用于 * 这种 * 情况,但这种方法通常仅限于基于MAML的帮助文件附带的目标命令,即使是那些附带的命令,其帮助文件也可能与实际命令定义 * 不同步 *。
& {
  Get-Command $args[0] | % Parameters | % $args[1] |
  Select-Object Name, Aliases, @{
    n = 'Accepts pipeline input';
    e = { $(if ($_.Attributes.ValueFromPipeline) { 'by value' }), $(if ($_.Attributes.ValueFromPipelineByPropertyName) { 'by property name' }) -join ', ' -replace '^, ' }
  }
} Get-FileHash LiteralPath

输出:

Name        Aliases      Accepts pipeline input
----        -------      ----------------------
LiteralPath {PSPath, LP} by property name

[*]是PowerShell的文件系统提供程序添加了此属性和其他属性。* 所有 * PowerShell providers都以这种方式修饰其输出项,如 * registry * 提供程序输出的Microsoft.Win32.RegistryKey示例。基础. NET类型 * 不 * 具有此属性。有关详细信息,请参见this answer

laik7k3q

laik7k3q2#

从关于函数高级参数文档的 ValueFromPipelineByPropertyName 参数部分:
ValueFromPipelineByPropertyName参数表示参数接受管道对象属性的输入。对象属性必须与参数具有相同的名称或别名。
例如,如果函数具有ComputerName参数,并且管道对象具有ComputerName属性,则ComputerName属性的值将分配给函数的ComputerName参数。

更新:最初链接了错误的源代码文件。正确的Get-FileHash source code is here。由于@mklement0***正确回答了***,Get-ChildItemcmdlet 输出了具有PSPath属性的对象,因此可以正常工作。

w7t8yxp5

w7t8yxp53#

它看起来像是使用了pspath属性。

dir there | select pspath | get-filehash

Algorithm  Hash                                                                Path
---------  ----                                                                ----
SHA256     44723DD4D0E0D46A3C7FA8ACA254B61C27B6B5789F96177E82C80700409F1535    C:\users\...

相关问题