How to fix "Where-Object : Method invocation failed because [Deserialized.Microsoft.Exchange.Data.ByteQuantifiedSize] does not contain a method named 'ToGB'." error

mohana sai krishna s 0 Reputation points
2024-08-21T17:10:20.5+00:00

Hi All,

!!!Need support on the below issue.!!!

I'm receiving an error while executing the script for the below scenario TASKs.

TASK 1: Export the Exchange Online Shared Mailboxes which occupies more than 90% mailbox size.

TASK 2: Filter the mailboxes which occupies more than 100% mailbox size.

TASK 3: Runs a mail trace for the last 3 hours, filter the failed email deliveries, and exports the count of failed emails for each recipients listed in the TASK 2.

TASK 4: Sends an email with the generated reports as attachments via the specified SMTP server.

SCRIPT:

Task 1: Export Shared Mailboxes with TotalItemSize above 90% in GB

Connect to Exchange Online

$AppID = "xxxxx-xxx-xxxx"

$CertificateThumbprint = "000000000000000000"

$Organization = "abc.contoso.com"

$CloudSession = Connect-ExchangeOnline -AppId $AppId -CertificateThumbprint $CertificateThumbprint -Organization $Organization -ShowBanner:$false	

#$CloudSession = Connect-ExchangeOnline -CertificateThumbPrint "12345678" -AppID "0000000" -Organization "abc.onmicrosoft.com"

#$CloudSession = Connect-ExchangeOnline -Credential $Cred -Verbose

Write-Host "Online session is imported..."

Define the threshold

$threshold = 0.9

$date = Get-Date -Format "yyyyMMdd_HHmmss"

Get shared mailboxes with TotalItemSize above 90%

$sharedMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox | Get-MailboxStatistics | Where-Object { $.TotalItemSize.Value.ToGB() -gt ($.TotalItemSize.MaximumSize.ToGB() * $threshold) }

Export to CSV

$sharedMailboxes | Select-Object DisplayName, TotalItemSize | Export-Csv -Path "E:\GM_Report\SharedMailboxesAbove90_$date.csv" -NoTypeInformation

Task 2: Filter Shared Mailboxes with TotalItemSize at 100% in GB

Define the threshold

$threshold = 1.0

$date = Get-Date -Format "yyyyMMdd_HHmmss"

Get shared mailboxes with TotalItemSize at 100%

$fullMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox | Get-MailboxStatistics | Where-Object { $.TotalItemSize.Value.ToGB() -eq ($.TotalItemSize.MaximumSize.ToGB() * $threshold) }

Export to CSV

$fullMailboxes | Select-Object DisplayName, TotalItemSize | Export-Csv -Path "E:\GM_Report\SharedMailboxesAt100_$date.csv" -NoTypeInformation

##Task 3: Run Mail Trace for Last 3 Hours and Export Failed Deliveries##

Define the time range

$endTime = (Get-Date)

$startTime = $endTime.AddHours(-3)

$date = Get-Date -Format "yyyyMMdd_HHmmss"

Get recipients from Task 2

$fullMailboxes = Import-Csv -Path "E:\GM_Report\SharedMailboxesAt100_$date.csv"

Initialize an array to store failed email counts

$failedEmailCounts = @()

foreach ($mailbox in $fullMailboxes) {

$recipient = $mailbox.DisplayName

# Run mail trace for each recipient

$failedEmails = Get-MessageTrace -StartDate $startTime -EndDate $endTime -RecipientAddress $recipient | Where-Object { $_.Status -eq "Failed" }

# Store the count of failed emails

$failedEmailCounts += [PSCustomObject]@{

    Recipient = $recipient

    FailedEmailCount = $failedEmails.Count

}

}

Export the failed email counts to CSV

$failedEmailCounts | Export-Csv -Path "E:\GM_Report\FailedEmailCounts_$date.csv" -NoTypeInformation

Task 4: Send Email with Generated Reports##

Define SMTP server details

$smtpServer = "123.xyz.com"

$smtpPort = 25

$sender = "******@xyz.com"

$recipient = "******@xyz.com"

Create email message

$emailMessage = New-Object System.Net.Mail.MailMessage

$emailMessage.From = $sender

$emailMessage.To.Add($recipient)

$emailMessage.Subject = "Generated Reports"

$emailMessage.Body = "Please find the attached reports."

$emailMessage.Attachments.Add("E:\GM_Report\SharedMailboxesAbove90_$date.csv")

$emailMessage.Attachments.Add("E:\GM_Report\SharedMailboxesAt100_$date.csv")

$emailMessage.Attachments.Add("E:\GM_Report\FailedEmailCounts_$date.csv")

Send email

$smtpClient = New-Object System.Net.Mail.SmtpClient($smtpServer, $smtpPort)

$smtpClient.Send($emailMessage)

Errors:

Where-Object : Method invocation failed because [Deserialized.Microsoft.Exchange.Data.ByteQuantifiedSize] does not contain a method

named 'ToGB'.

At line:19 char:94

  • ... tatistics | Where-Object { $.TotalItemSize.Value.ToGB() -gt ($.Tota ...
  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidOperation: (ToGB:String) [Where-Object], RuntimeException
    • FullyQualifiedErrorId : MethodNotFound,Microsoft.PowerShell.Commands.WhereObjectCommand

Where-Object : Method invocation failed because [Deserialized.Microsoft.Exchange.Data.ByteQuantifiedSize] does not contain a method

named 'ToGB'.

At line:31 char:92

  • ... tatistics | Where-Object { $.TotalItemSize.Value.ToGB() -eq ($.Tota ...
  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidOperation: (ToGB:String) [Where-Object], RuntimeException
    • FullyQualifiedErrorId : MethodNotFound,Microsoft.PowerShell.Commands.WhereObjectCommand

Import-Csv : Could not find file 'E:\GM_Report\SharedMailboxesAt100_20240821_120312.csv'.

At line:45 char:18

  • ... Mailboxes = Import-Csv -Path "E:\GM_Report\SharedMailboxesAt100_$date ...
  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : OpenError: (:) [Import-Csv], FileNotFoundException
    • FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.ImportCsvCommand

Cannot convert argument "item", with value: "E:\GM_Report\SharedMailboxesAbove90_20240821_120312.csv", for "Add" to type

"System.Net.Mail.Attachment": "Cannot convert value "E:\GM_Report\SharedMailboxesAbove90_20240821_120312.csv" to type

"System.Net.Mail.Attachment". Error: "Could not find file 'E:\GM_Report\SharedMailboxesAbove90_20240821_120312.csv'.""

At line:79 char:1

  • $emailMessage.Attachments.Add("E:\GM_Report\SharedMailboxesAbove90_$d ...
  • 
        + CategoryInfo          : NotSpecified: (:) [], MethodException
    
        + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
    
     
    
    

Cannot convert argument "item", with value: "E:\GM_Report\SharedMailboxesAt100_20240821_120312.csv", for "Add" to type

"System.Net.Mail.Attachment": "Cannot convert value "E:\GM_Report\SharedMailboxesAt100_20240821_120312.csv" to type

"System.Net.Mail.Attachment". Error: "Could not find file 'E:\GM_Report\SharedMailboxesAt100_20240821_120312.csv'.""

At line:80 char:1

  • $emailMessage.Attachments.Add("E:\GM_Report\SharedMailboxesAt100_$dat ...
  • 
        + CategoryInfo          : NotSpecified: (:) [], MethodException
    
        + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
    
     
    
    
Exchange Online
Exchange Online
A Microsoft email and calendaring hosted service.
6,178 questions
Windows for business | Windows Server | User experience | PowerShell
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Anonymous
    2024-08-22T00:34:48.1133333+00:00

    Hi mohana sai krishna s,

    It seems there is no toGB() method. You can try this

    https://devblogs.microsoft.com/scripting/get-exchange-online-mailbox-size-in-gb/

    Best Regards,

    Ian Xue


    If the Answer is helpful, please click "Accept Answer" and upvote it.

    0 comments No comments

  2. Rich Matheisen 47,901 Reputation points
    2024-08-22T02:19:47.96+00:00

    If you're working with a deserialized version of the object you don't have the original version. What you have is aversion that been transformed into a text-only copy or the original. That copy is inert. It has no methods, only properties and values.

    Note that the object type is [**Deserialized.**Microsoft.Exchange.Data.ByteQuantifiedSize].

    This Serialization/Deserialization process happens to all objects that created on a remote machine and sent back the local machine. It isn't anything specific to Exchange.

    This is the reason you can't use Get-Process -ComputerName XXXX and then use the process objects method to stop the process from the local machine -- the method you need to do that has been removed by the serialization/deserialization of the data.

    0 comments No comments

  3. Rich Matheisen 47,901 Reputation points
    2024-08-22T21:42:35.9133333+00:00

    You can add a small function to your code. For example:

    function toGB{
        [CmdletBinding()]
        param (
            [Parameter(Mandatory)]
            [Int32]$Size
        )
        [Int32]$GB = 1073741824
        [double]($Size / $GB)
    }   # end function toGB
    

    And then change the use of the toGB method to the use of the toGB function. For example:

    $fullMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox | 
        Get-MailboxStatistics | 
            Where-Object { (toGB -Size $_.TotalItemSize.Value) -eq ((toGB -Size $_.TotalItemSize.MaximumSize) * $threshold) }
    

    What's your definition of a "full" mailbox? Your code says it's a mailbox whose contents are equal to the maximum allowable mailbox size. But an almost "full" mailbox may still reject messages if the current size of the mailbox PLUS the size of the new message exceeds the maximum allowed mailbox size. It would be pretty rare to find a mailbox that's exactly the maximum allowed size. Maybe you should be checking for mailboxes whose current size is within the size of a large message (you get to define the "tolerance". You can then check the message tracking to see if the "almost full" mailboes are rejecting messages.

    Also, your "full" mailboxes are also going to show up in the "more then 90%" bucket. When you're doing checks like your code does you should check in descending order of size and not check a mailbox twice. :-)

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.