Is there a better way to expand a calculated field?

This topic contains 13 replies, has 5 voices, and was last updated by Profile photo of Richard Siddaway Richard Siddaway 2 years, 6 months ago.

  • Author
    Posts
  • #16012
    Profile photo of Adam Bertram
    Adam Bertram
    Participant

    I can do this but using Select-Object twice like this is ugly and probably inefficient. Is it possible to do an -ExpandProperty or equivalent on a calculated property?

    Get-Wmiobject -Class Win32_LogicalDisk | Select @{n='Drive';e={$_.DeviceID.TrimEnd(':')}} | Select -ExpandProperty Drive

  • #16013
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    You could just use ForEach-Object instead:

    Get-Wmiobject -Class Win32_LogicalDisk | ForEach-Object { $_.DeviceID.TrimEnd(':') }
    
  • #16015
    Profile photo of Richard Siddaway
    Richard Siddaway
    Moderator

    Not sure why you need the second select as

    £> Get-Wmiobject -Class Win32_LogicalDisk |
    Select @{n='Drive';e={$_.DeviceID.TrimEnd(':')}}

    Drive
    —–
    C
    D
    E
    F

    If you just want the drive letters then go with Dave's suggestion or make it shorter liek this
    (Get-Wmiobject -Class Win32_LogicalDisk).DeviceID.TrimEnd(':')

  • #16016
    Profile photo of Adam Bertram
    Adam Bertram
    Participant

    @Richard – I am wanting an output as an array of strings and not an array of objects.

    This is just academic tinkering mostly and figuring out how I can write this in the shortest way possible yet account for the instances when, for example, an array may contain 1,000,000+ items.

    @Richard So far, I've tried your suggestion which was 20 seconds. I tried Dave's suggestion and that was about the same. I also tried mine and it was about the same too. In this instance, it appears since they are the same performance-wise it'd be best to pick the shortest code which would be

    (Get-Wmiobject -Class CIM_DataFile | Select -first 20000).DeviceID.TrimEnd(':')

    Am I right?

    • #16025
      Profile photo of Rob Campbell
      Rob Campbell
      Participant

      Is this any faster:


      [string](gwmi win32_logicaldisk ) -split '\\\\.+?DeviceID="' -replace ':"'

  • #16017
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Depends on whether you intend to support PowerShell 2.0 or not. The (Get-Wmiobject -Class CIM_DataFile | Select -first 20000).DeviceID.TrimEnd(':') syntax requires version 3.0 or later.

  • #16018
    Profile photo of Adam Bertram
    Adam Bertram
    Participant

    It will always be at least v3.

  • #16019
    Profile photo of Adam Bertram
    Adam Bertram
    Participant

    Thanks guys. I appreciate the help.

  • #16026
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Even if it is faster, it would be bad habit to go back to text parsing like that. PowerShell's biggest strength is the ability to work with objects, not text.

    For example, run it this way, and you'll see that the text parsing approach looks correct at first, but actually outputs an extra empty string, and includes some unwanted whitespace:

    [string](gwmi win32_logicaldisk ) -split '\\\\.+?DeviceID="' -replace ':"' |
    ForEach-Object { "'$_'" }
    
  • #16027
    Profile photo of Rob Campbell
    Rob Campbell
    Participant

    I agree that doing text parsing is not something you want to do as a matter of course, but when a solution needs to scale to millions of operations I think purity can be put aside in favor of efficiency.

  • #16028
    Profile photo of Richard Siddaway
    Richard Siddaway
    Moderator

    The better question is what are you trying to achieve with your script and what is the best way to reach that goal. I would always recommend outputting objects as the first option BUT there are times when it isn't the right answer

  • #16029
    Profile photo of Adam Bertram
    Adam Bertram
    Participant

    In this instance I was not necessarily trying to achieve any real-world result. I appreciate the replies. I learned a few approaches that I had never considered before.

  • #16042
    Profile photo of Richard Siddaway
    Richard Siddaway
    Moderator

    -ExpandProperty doesn't necessarily convert to a string. It takes a property that can have one, or more, values and supplies you with the value(s). Those values could be of any type. In other words it strips the values out of the property

  • #16041
    Profile photo of Istvan Szarka
    Istvan Szarka
    Participant

    I've been experimenting with something similar. The purpose of -ExpandProperty is to convert an object to string, so that another cmdlet's parameter can accept it, right? However, in a custom property you cannot use it, but you can use -as [string] – I mean if you only want to convert it, not trim or alike.

You must be logged in to reply to this topic.