forcing property format


I’m running a command and I want to force the output into a format I can work with, currently I have

select -expandproperty resultitemssize

Which returns

14.37 KB [14,718 bytes]
0 B [0 bytes]
0 B [0 bytes]


select resultitemssize


14.37 KB [14,718 bytes]                                                                                                                                                  
0 B [0 bytes]                                                                                                                                                            
0 B [0 bytes]   

Now the formatting when you want to count the total won’t work, as it just counts the entries, is there something in the pipe I can use for formatting, maybe force the output to bytes and then measure it taking out the B [0 bytes]?

Couple of questions. First, how are you producing the property with multiple values. Is the command returning that be default or are you creating a custom object? Second, if you do:

$var = mysteryCommand | select resultitemssize

What data type is in the property? System.Array?

What do you get when you pipe select -expandproperty resultitemssize to Get-Member?

I’m getting the property as follows

$p = get-mailbox | search-Mailbox -SearchQuery {Received:29/05/2015..29/05/2015} -EstimateResultOnly | select -expandproperty resultitemssize 


IsPublic IsSerial Name BaseType

True True Object[] System.Array

Dave Wyatt wrote:
What do you get when you pipe select -expandproperty resultitemssize to Get-Member?

Comes back as string

That’s annoying. You’ll need to do some string parsing, then. Perhaps something like this:

$p = get-mailbox |
search-Mailbox -SearchQuery {Received:29/05/2015..29/05/2015} -EstimateResultOnly |
ForEach-Object {
    if ($_ -match '\[\s*([^\]]+)\s+bytes\s*\]')
        [int]($matches[1] -replace '\D')

Regular expressions are annoying sometimes, but in this case, it’s probably the best way to go.

That could may be even be shortened to this:

$p = get-mailbox |
search-Mailbox -SearchQuery {Received:29/05/2015..29/05/2015} -EstimateResultOnly |
ForEach-Object { [int]( $_ -replace '^.*\[' -replace '\D' ) }

Alas your last command

$p = get-mailbox gf* |
search-Mailbox -SearchQuery {Received:29/05/2015..29/05/2015} -EstimateResultOnly |
ForEach-Object { [int]( $_ -replace '^.*\[' -replace '\D' ) }

presents me with

The first command comes back empty

Hah got it, you were right

$p = get-mailbox | search-Mailbox -SearchQuery {Received:29/05/2015..29/05/2015} -EstimateResultOnly | select -ExpandProperty resultitemssize |
ForEach-Object { [int]( $_ -replace '^.*\[' -replace '\D' ) }

Oops, forgot to include the Select-Object part. I was testing the regex with a static string array, and copied / pasted into the thread. :slight_smile:

You’re just getting the value and they are all not represented in bytes, I see KB, would you have to do something like this>

$p = "14.37 KB [14,718 bytes]","0 B [0 bytes]", "0 B [0 bytes]"

$totalbytes = 0
$p | foreach{
    $a = $_ -split " "
    switch ($a[1]) {
        "KB"{$bytes = [float]$a[0] * 1kb}
        "B" {$bytes = [float]$a[0]}
    $totalBytes = $totalBytes + $bytes


Ah, nevermind, I see the bytes representation in the square brackets that you’re parsing with regex.

Well it is going well, I now have my value is bytes, I’m trying to measure the total so I did

 | measure-object -sum

But that does not measure the total amount just the rows, hmm need more research

$p =  "14.37 KB [14,718 bytes]","0 B [0 bytes]", "0 B [0 bytes]" | ForEach-Object { [int]( $_ -replace '^.*\[' -replace '\D' ) }
$p | Measure-Object -Sum


Count    : 3
Average  : 
Sum      : 14718
Maximum  : 
Minimum  : 
Property :

I did this originally
Search all mailboxes for todays mail

Returned 99 mailboxes and 9895918761781 bytes

No way has this place received 9895 GB of mail in one day

I see where this may be going wrong [int] was not working as returned

ForEach-Object : Cannot convert value "32523409940" to type "System.Int32". Error: "Value was either too large or too small for an Int32."

So replaced with [long]

Be it 32523409940 is a bit more reasonable, so need sort that out

You could try to troubleshoot by getting entries per mailbox versus a lump sum to see if the query is working as expected. I didn’t test this, but you could attempt logic like this to provide you breakdown per mailbox and then get the final:

$results = get-mailbox | foreach{
    search-Mailbox -SearchQuery {Received:29/05/2015..29/05/2015} -EstimateResultOnly |
    Select Name,
           @{Label="resultitemssizeBytes";Expression={@($_.resultitemssize | ForEach-Object { [int]( $_ -replace '^.*\[' -replace '\D' ) })}},
           @{Label="resultitemssizeBytesTotal";Expression={(@($_.resultitemssize | ForEach-Object { [int]( $_ -replace '^.*\[' -replace '\D' ) }) | Measure-Object -Sum).Sum}}

$results | Measure-Object -Property resultitemssizeBytesTotal -Sum

I found the error,

The original output is 4.707 KB (4,820 bytes)
The format coding

ForEach-Object { [int]( $_ -replace '^.*\[' -replace '\D') }

Puts it into

Which is a mash of all the numbers,

I need to address the format coding so it only gives me KB or bytes, hmmm

Os it appears in this command it will output MB KB and B

So I will need anything just inside (110,382 bytes) without the bytes, or ()

Then Sum up the total of bytes, Going to be a large number too