Json 当select失败时,为什么foreach在这里工作?

Json 当select失败时,为什么foreach在这里工作?,json,powershell,Json,Powershell,我已经在$Response变量中存储了来自RavenDB服务器的附件列表 [{"Size":3040,"Key":"attachments/deployments-7928/output-log","Metadata":{"ContentType":"text/xml"},"Etag":"02000000-0000-0014-0000-00000000A0D0"},{"Size":2524,"Key":"attachments/deployments-7927/output-log","Meta

我已经在
$Response
变量中存储了来自RavenDB服务器的附件列表

[{"Size":3040,"Key":"attachments/deployments-7928/output-log","Metadata":{"ContentType":"text/xml"},"Etag":"02000000-0000-0014-0000-00000000A0D0"},{"Size":2524,"Key":"attachments/deployments-7927/output-log","Metadata":{
"ContentType":"text/xml"},"Etag":"02000000-0000-0014-0000-00000000A0CF"},{"Size":530,"Key":"attachments/tasks-7842/output-log","Metadata":{"ContentType":"text/xml"},"Etag":"02000000-0000-0014-0000-00000000A0AA"}]
我想获取键值,以便获取附件

为什么我不能像这样选择键值

$Response | ConvertFrom-Json | Select Key
当我这样做时,所有的钥匙看起来都是空的

奇怪的是,当我使用Foreach时,它会起作用

$Response | ConvertFrom-Json | Foreach { $_.Key }
我看到:

attachments/deployments-7928/output-log
attachments/deployments-7927/output-log
attachments/tasks-7842/output-log
有什么区别


为什么不在这里选择工作?

如果您先将结果分配给一个变量,然后将其传递到
选择对象
,则该操作有效

$response = @'
    [{"Size":3040,"Key":"attachments/deployments-7928/output-log","Metadata":{"ContentType":"text/xml"},"Etag":"02000000-0000-0014-0000-00000000A0D0"},{"Size":2524,"Key":"attachments/deployments-7927/output-log","Metadata":{
    "ContentType":"text/xml"},"Etag":"02000000-0000-0014-0000-00000000A0CF"},{"Size":530,"Key":"attachments/tasks-7842/output-log","Metadata":{"ContentType":"text/xml"},"Etag":"02000000-0000-0014-0000-00000000A0AA"}]
'@

$ObjectList = $response | ConvertFrom-Json;

$ObjectList | Select-Object -Property Key;

因为convertfrom json不返回PSObject的数组,所以它返回一个数组system.object[]。数组没有“键”成员

 Write-Output '[{"Size":3040,"Key":"attachments/deployments-7928/output-log","Metadata":{"ContentType":"text/xml"},"Etag":"02000000-0000-0014-0000-00000000A0D0"},{"Size":2524,"Key":"attachments/deployments-7927/output-log","Metadata":{
"ContentType":"text/xml"},"Etag":"02000000-0000-0014-0000-00000000A0CF"},{"Size":530,"Key":"attachments/tasks-7842/output-log","Metadata":{"ContentType":"text/xml"},"Etag":"02000000-0000-0014-0000-00000000A0AA"}]' `
| convertfrom-json | get-member
输出

   TypeName: System.Object[]
   ...
请参见,它只有以下成员:

名称 计数
添加
地址
清除
克隆
比较
包含
复制到
等于
获取
GetEnumerator
GetHashCode
GetLength
GetLongLength
GetLowerBound
GetType
GetUpperBound
GetValue
IndexOf
初始化
插入
删除
移除
设置
设置值
ToString
项目
IsFixedSize
IsReadOnly
IsSynchronized
长度
长长度
排名
同步根

分配给变量将转换为TypeName:
System.Management.Automation.PSCustomObject

这有一个“关键”成员。Powershell内置的枚举感知功能可适当扩展此功能。

如果要避免中间变量赋值:

{$response | ConvertFrom-Json}.invokereturnasis() | select key

我承认这是真的,但似乎真的很奇怪。是否存在该行为的规范或引用?@iain elder我不知道为什么会这样,但powershell控制台用户可以从
get member
输出的顶行获取表达式或管道返回的类型。我已经为未来的读者更新了我的答案。我不知道这一点,所以谢谢你的选择,但它看起来比变量赋值更奇怪。InvokeReturnAsIs还有什么用?它确实有点晦涩难懂。我想不出还有什么好例子。它执行scrpt块并将结果作为PS对象流重新运行。还有{}.invoke()返回PS对象的集合,如果您需要集合而不是数组,这将非常有用。