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

时间:2013-04-15 13:17:40

标签: 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命令时是否存在一些细微差别?

2 个答案:

答案 0 :(得分:6)

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

您可以使用以下命令查看:

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

因此,当您查看成功绑定的跟踪时,您将看到Literal路径绑定到以Microsoft.PowerShell.Core\FileSystem::开头的属性,即PsPath。因此,仔细检查比较管道到Get-Member时的对象属性,您将看到有效的那个具有这些注释属性,而使用New-Object创建的属性不具有 -

  • PSChildName
  • PSDrive来
  • PSIsContainer
  • PSParentPath
  • PSPath
  • PSProvider

查看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'

答案 1 :(得分:-1)

请记住,New-Object只是创建了一个PowerShell对象的实例......它没有写任何文件。使用

Test-Path $path 

表明该文件尚不存在。因此,添加一些代码来实际创建文件然后分配给它,将不会产生错误。

Test-Path $path

$stream = [System.IO.StreamWriter] $path
1..10 | % {
      $stream.WriteLine($s)
}
$stream.close()

$newfile = Get-Content $path

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

我们分配回$ newfile,因为它是一个引用。如果我们在事后创建文件,它不会自动更新。

相关问题