I'm building a report about SMART metrics (SSD storage wear status):

Get-PhysicalDisk | %{ 
    $s = $_ | Get-StorageReliabilityCounter; 
    [PSCustomObject]@{
        Model = $_.Model; 
        BusType = $_.BusType; 
        MediaType = $_.MediaType;
        SizeGB = [Int]($_.Size/1e9);
        LogicalSectorSize = $_.LogicalSectorSize;
        PhysicalSectorSize = $_.PhysicalSectorSize;
        PowerOnHours = $s.PowerOnHours;
        Temperature = $s.Temperature;
        TemperatureMax = $s.TemperatureMax;
        Wear = $s.Wear 
    }
}

I'd like to shorten an expression by just taking few properties from a parent into a child result of a pipe... Like adding a Model name & Size from Get-PhysicalDisk into subsequent Get-StorageReliabilityCounter without verbose syntax.

How can I do this?

8 Replies 8

If you want to pass only certain properties from the parent and ignoring everything else, you can do is Get-PhysicalDisk | select PropertyName,PropertyName2,PropertynameEtc | % {...} which will pass only those properties to the pipeline.

If you meant to pass values down the variable without cumbersome code, you can us Get-PhysicalDrive -PV VariableName.
-PV is an alias for PipelineVariable: as the name suggests, it will cause the results of the cmdlet to be available later in the pipeline with that name(or whatever name you want to use)

ex: gci -pv AA|% { @{ name=$_.name }} | % { [pscustomobject]@{"Name"=$_.Name;'ext'=$AA.Extension } }

There's really no way around combining a lot of properties from one command with another. The -pipevariable option doesn't seem to work in this case, but this is almost the same thing. At least it's readable.

($disk = get-physicaldisk) | Get-StorageReliabilityCounter |
select @{n='Model';e={$disk.model}},
@{n='BusType';e={$disk.bustype}},
@{n='MediaType';e={$disk.mediatype}},
@{n='SizeGB';e={[int]($disk.size/1e9)}},  # or /1gb
@{n='LogicalSectorSize';e={$disk.logicalsectorsize}},
@{n='PhysicalSectorSize';e={$disk.PhysicalSectorSize}},
PowerOnHours, Temperature, TemperatureMax, Wear

Output:

Model              : EG6 KIOXIA 512GB
BusType            : NVMe
MediaType          : SSD
SizeGB             : 512
LogicalSectorSize  : 512
PhysicalSectorSize : 4096
PowerOnHours       :
Temperature        : 30
TemperatureMax     : 83
Wear               : 0

What is @{n='BusType';e={$disk.bustype}}? AI gave me similar examples, I just barely understand it. Seems n & e as shortcuts for Name & Expression in so called Calculated Property Syntax.

@{Name='PropertyName'; Expression={Script Block}} or @{n='PropertyName'; e={Script Block}}.

AI suggested an example:

Get-ChildItem -File | Select-Object Name, @{n='SizeMB'; e={$_.Length / 1MB}}

demonstrating exactly what I desired to archive, then why does @{n;e} act strangely in Select-Object?

What is @{n='BusType';e={$disk.bustype}}?

The n and e are indeed shorthands for Name and Expression - the cmdlets that accept calculated property expression tables (in this case Select-Object) will perform prefix-matching against expected keys, so you can use any starting part of either key:

... |Select-Object @{ Name = 'PropertyName'; Expression = {...} }
... |Select-Object @{ N = 'PropertyName'; Expression = {...} }
# Label and Name keys are analogous        -  Expr is my personal preference for Expression
... |Select-Object @{ Label = 'PropertyName'; Expr = {...} }

If you simply want a renamed copy of an existing property you can pass the name of the source property as the Expression value:

... |Select-Object @{ Name = 'NewPropertyName'; Expression = 'OriginalPropertyName' }

I strongly recommend searching and reviewing the documentation instead of consulting AI. The relevant document in this case would be the about_Calculated_Properties topic, which also lists the other utility cmdlets that accept calculated property expressions.

@Mclayton why the backticks after the commas?
The Commas already work a line-breaker, adding the backticks only make everything harder.

@sirtao First select requires backtick so first argument should be moved to the first line. I also prefer style where command is on the first line and all args are indented the same level. So backticks are for consistency...

Your Reply

By clicking “Post Your Reply”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.