【问题标题】:Powershell Select-Object's -Property parameterPowershell Select-Object 的 -Property 参数
【发布时间】:2011-07-21 21:05:58
【问题描述】:

我对 Select-Object cmdlet 的一些行为感到困惑。这是一个例子。

PS C:\> $object = get-item C:\windows\Temp
PS C:\> $time = $object.CreationTime
PS C:\> $time.GetType().FullName
System.DateTime
PS C:\> $result = Select-Object -InputObject $object -Property "CreationTime"
PS C:\> $result.GetType().FullName
System.Management.Automation.PSCustomObject
PS C:\>
PS C:\> $result.CreationTime.GetType().FullName
System.DateTime

注意CreationTime 的类型是System.DateTime,但是当我使用Select-Object 选择它时,返回的对象是System.Management.Automation.PSCustomObject 类型。它是一些以CreationTime 为属性的新对象。

让我们看看Select-Object 的帮助来解释这一点。

概要
选择一个对象或一组对象的指定属性...

这就是我想要的,属性本身……而不是带有属性的对象。但如果我们进一步阅读......

描述
...如果您使用 Select-Object 选择指定的属性,它会从输入对象中复制这些属性的值,并创建具有指定属性和复制值的新对象。

我不知道为什么这很有用,但它解释了返回的这个对象。

使用-ExpandProperty 而不是-Property 似乎赋予了属性本身

PS C:\> $result2 = Select-Object -InputObject $object -ExpandProperty "CreationTime"
PS C:\> $result2.GetType().FullName
System.DateTime

-ExpandProperty 为什么要这样做?让我们看看它的帮助:

-ExpandProperty
指定要选择的属性...如果该属性包含一个对象,则该对象的属性将显示在输出中。

在这种情况下,属性是一个对象,我们没有得到“那个对象的属性”,我们只得到了对象本身。

谁能告诉我:

  1. 当帮助中提到扩展数组和获取属性对象(而不是属性对象本身)的属性时,为什么-ExpandProperty 会获取属性对象本身?这是我很困惑的地方。我读错了吗?我觉得这需要再次进行技术编辑。
  2. 用“-Property”返回的对象,有什么用吗?

【问题讨论】:

    标签: powershell


    【解决方案1】:

    扩展#1 的答案:-expandproperty 最常见的用途是将作为数组的属性扩展为数组元素,尤其是在执行 export-csv 时。

    PS C:\> get-process lsass | select threads | convertto-csv -notype
    "Threads"
    "System.Diagnostics.ProcessThreadCollection"
    

    不是很有用。现在,在该线程集合上使用 -expandproperty:

    PS C:\> get-process lsass | select -expand threads | convertto-csv -notype
    
     "BasePriority","CurrentPriority","Id","IdealProcessor","PriorityBoostEnabled","PriorityLevel","PrivilegedProcessorTime"
     ,"StartAddress","StartTime","ThreadState","TotalProcessorTime","UserProcessorTime","WaitReason","ProcessorAffinity","Si
     te","Container"
     "9","10","572",,,,,"2000143616",,"Wait",,,"LpcReceive",,,
     "9","10","588",,,,,"2000143616",,"Wait",,,"UserRequest",,,
     "9","9","592",,,,,"2000143616",,"Wait",,,"UserRequest",,,
     "9","10","596",,,,,"0",,"Wait",,,"EventPairLow",,,
     "9","9","1404",,,,,"0",,"Wait",,,"UserRequest",,,
     "9","9","3896",,,,,"0",,"Wait",,,"EventPairLow",,,
     "9","9","848",,,,,"0",,"Wait",,,"EventPairLow",,,
     "9","11","6216",,,,,"2000143616",,"Wait",,,"UserRequest",,,
     "9","9","7924",,,,,"2000143616",,"Wait",,,"EventPairLow",,,
    

    【讨论】:

    • 这是有道理的。令我惊讶的是,如果该属性不是一个数组,那么 cmdlet 将单独返回该属性,我看不到任何“扩展”发生:P
    • 这样想。使用 $object | select -expand 属性会给你与 $object | 相同的结果。 foreach {$_.property}。如果该属性是一个标量(单个值),您只会得到一个对象。如果有多个对象,则返回一组对象。
    • 啊,有道理。许多 cmdlet 自动处理标量或数组值,而无需我将标量包装在一个元素的数组中。不知何故,没有点击。对于那些阅读问题 2 答案的人,请参阅下面 Mike Shepard 的答案(和 cmets)。
    【解决方案2】:

    Select-object(没有 -expandproperty)返回一个带有您选择的属性集的 PSCustomObject。那是因为您可能想要选择多个属性(并且不能期望获得例如 2 个属性的日期时间对象)。

    #2 的答案是,有时最好拥有一个具有较少属性的对象并丢失方法。此外,您可以使用带有表达式的 select-object 来返回“计算”属性。

    【讨论】:

    • 我还没有使用计算属性。当 PSCustomObject 有用时,我仍然很模糊(它的 MSDN 文档有点少)。如果我想接收多个属性,我首先想到的是一组属性。 “在”对象上的属性有什么特别之处吗?
    • 许多“开箱即用”的 cmdlet 都适用于属性(where-object、sort-object 等),并且不适用于属性数组。至于计算的属性,这里有一个例子:Get-ChildItem C:\Test | Select-Object Name, CreationTime, @{Name="Kbytes";Expression={$_.Length / 1Kb}}取自here
    猜你喜欢
    • 2015-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-29
    相关资源
    最近更新 更多