我正在为一个关于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命令时是否存在一些细微差别?
答案 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
创建的属性不具有 -
查看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,因为它是一个引用。如果我们在事后创建文件,它不会自动更新。