Powershell:所有新对象都不是平等的吗?

标签 powershell

我正在为 powershell 上的演示文稿编写一些简短的演示脚本,当然我自己的一个简单演示让我感到困惑。此演示的目的是展示在 powershell 中创建对象的不同方法。这是我的代码:

$file = ls 'C:\temp' | Where-Object {$_.Extension -eq '.txt'}
$file.FullName
$path = 'C:\temp\jdh.txt'
$newfile = New-Object -TypeName System.IO.FileInfo -ArgumentList $path
$newfile.FullName

$file.GetType()
$newfile.GetType()
$file
$newfile

$file | Get-Content | out-null
$newfile | Get-Content | out-null

简单吧?通过不同的方法创建两个 FileInfo 对象并读取它们。输出显示文件是相同的:
C:\temp\jdh.txt
C:\temp\jdh.txt

IsPublic IsSerial Name                                     BaseType                                                                               
-------- -------- ----                                     --------                                                                               
True     True     FileInfo                                 System.IO.FileSystemInfo                                                               
True     True     FileInfo                                 System.IO.FileSystemInfo                                                               

LastWriteTime : 4/10/2013 3:38:29 PM
Length        : 46046
Name          : jdh.txt


LastWriteTime : 4/10/2013 3:38:29 PM
Length        : 46046
Name          : jdh.txt

但是,当 Get-Content 尝试读取 $newfile 对象时,我收到以下错误:
Get-Content : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the 
input and its properties do not match any of the parameters that take pipeline input.
At line:16 char:12
+ $newfile | Get-Content | out-null
+            ~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (C:\temp\jdh.txt:PSObject) [Get-Content], ParameterBindingException
    + FullyQualifiedErrorId : InputObjectNotBound,Microsoft.PowerShell.Commands.GetContentCommand

所以我在错误中注意到它说 PSObject 让我感到困惑,因为在我的输出中似乎 $newfile 是一个 FileInfo 对象。所以我想做的下一个合乎逻辑的事情是将 $newfile 类型转换为类型 [System.IO.FileInfo]。这产生了同样的错误,除了现在而不是 PSObject 它显示 FileInfo 作为类型。那么,如果 $file 和 $newfile 看起来相同并且 get-content 在 $file 上工作,我怎么会收到该错误?使用 new-object 命令时是否有一些细微的差别?

最佳答案

我跟踪了使用 New-Object 创建的对象的绑定(bind)。问题是 Get-Content无法绑定(bind)到 FileInfo 上的任何属性信息对象。

您可以使用以下命令进行检查:

Trace-Command -psHost -Name ParameterBinding {$newFile | gc}
Trace-Command -psHost -Name ParameterBinding {$file | gc}

因此,当您查看成功绑定(bind)的跟踪时,您会看到 Literal path 绑定(bind)到以 Microsoft.PowerShell.Core\FileSystem:: 开头的属性。这是 PsPath。因此,仔细检查比较管道时的对象属性 Get-Member你会看到一个有效的具有这些注释属性,而使用 New-Object 创建的那个具有这些注释属性。才不是 -
  • PSChildName
  • PSDrive
  • PSIContainer
  • PSParentPath
  • PSPath
  • 提供者

  • 看看Get-Content cmdlet参数我们可以看到LiteralPath别名为 PsPath :
    (Get-Command -Name Get-Content).ParameterSets
    
      Parameter Name: LiteralPath
        ParameterType = System.String[]
        Position = 0
        IsMandatory = True
        IsDynamic = False
        HelpMessage =
        ValueFromPipeline = False
        ValueFromPipelineByPropertyName = True
        ValueFromRemainingArguments = False
        Aliases = {PSPath}
        Attributes =
          System.Management.Automation.AliasAttribute
          System.Management.Automation.ParameterAttribute
    

    如果您将属性添加到 New-Object已创建 FileInfo它会起作用:
    $newFile | Add-Member -MemberType NoteProperty -Name PsPath -Value 'Microsoft.PowerShell.Core\FileSystem::C:\temp\jdh.txt'
    

    关于Powershell:所有新对象都不是平等的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16016166/

    相关文章:

    powershell - Docker-无法使用Powershell运行ASP.NET Core API,但可以在Visual Studio中运行

    powershell -and 运算符与测试路径语法错误

    powershell - Azure 网站 - 使用 PowerShell 或跨平台 CLI 配置 SSL 绑定(bind)

    powershell - switch 语句中多个值的 PowerShell 语法是什么?

    powershell - 使用 PowerShell 创建机器人 channel 注册

    powershell - 从 Powershell 运行 New-EC2Tag 需要对哪些资源执行哪些政策操作?

    php - 无法使用PHP的shell_exec执行powershell脚本功能

    c# - 在从 C# 调用的 PowerShell Core 中安装 Az

    powershell - 如何通过 api 获取 Azure Devops/TFS 中特定构建中使用的变量

    powershell - Azure DSC。 Windows Server 2016 的 HA Active Directory 域 Controller 问题