Exception Messages

This topic contains 10 replies, has 2 voices, and was last updated by  Stuart 1 month, 3 weeks ago.

  • Author
    Posts
  • #97139

    Stuart
    Participant

    Hi All,

    When using $_.Exception.Message to capture an error message within a TRY / CATCH I notice that the error from say an Exchange Commandlet is very different to what is captured by the $_.Exception.Message.

    How do I allow ALL errors to be included and logged in my TRY /CATCH loop.

    THanks

    Stuart

  • #97145

    Stuart
    Participant

    There are hundreds of different classes of Exchange messages. How do I catch them all?

  • #97148

    Stuart
    Participant
  • #97155

    Stuart
    Participant

    Example error message:

    Cannot bind argument to parameter 'Identity' because it is null.
        + CategoryInfo          : InvalidData: (:) [Get-MailboxStatistics], ParameterBindingValidationException
        + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Get-MailboxStatistics
        + PSComputerName        : sh-vm-exch-01
    

    Example TRY / CATCH

    catch
                    {
                    $msg = $_.CategoryInfo.TargetName
                    Write-Log -Code Error -CatchIndex 002 -ErrorMessage $msg
                    }
    
    
    Function Write-Log ([string]$Code,[string]$ObjectGuid,[string]$DisplayName,[string]$ErrorMessage,[string]$FriendlyText,[String]$CatchIndex) {
    
        If ($Code -eq "SUCCESS") {
            Write-Host "[SUCCESS]`t $($FriendlyText) `t ObjectGuid $($ObjectGuid) `t DisplayName $($DisplayName)" -ForegroundColor Green
            "[SUCCESS]`t $($FriendlyText) `t $($ObjectGuid) `t DisplayName $($DisplayName)`n"| Out-File $Log -Append  }
    
        If ($Code -eq "ERROR") {
            Write-Host "[ERROR]`t $CatchIndex ObjectGuid $($ObjectGuid) `t DisplayName $($DisplayName) ErrorMessage: $errorMessage" -BackgroundColor Red
            "[ERROR]`t`t CATCHINDEX: $CatchIndex`t`t $errorMessage`n"| Out-File $Log -Append  }
            }
    
    
  • #97164

    Stuart
    Participant

    This seems to work:

     catch
                    {
                    $Name = $ADUser.name
                    $GUID = $ADuser.ObjectGUID
                    $DN = $ADuser.DistinguishedName
                    $msg1 = $_.CategoryInfo.TargetName
                    $msg2= $_.Exception.Message
                    Write-Log -Code Error -CatchIndex 004 -ErrorMessage1 $msg1 -ErrorMessage2 -$msg2 -GUID $GUID -Name $Name -DN $DN
                    }
    

    But crude, but gets the job done

  • #97166

    Joel Sallow
    Participant

    As you found, you can catch everything using a non-specific catch clause. A slightly tidier way to have your function called and values passed in here would definitely take advantage of splatting:

    $LoggingData = @{
        Name = $ADUser.name
        GUID = $ADuser.ObjectGUID
        DN = $ADuser.DistinguishedName
        msg1 = $_.CategoryInfo.TargetName
        msg2= $_.Exception.Message
        Code = 'Error'
        CatchIndex = 004
    }
    Write-Log @LoggingData
    
  • #97184

    Stuart
    Participant

    Thanks for the advice. I'll incorporate that.

    One question, just as I thought I had provided a decent catch, I saw yet another error message which was not within the scope of $_.CategoryInfo.TargetName or $_.Exception.Message.

    The only way I know how to include it is to debug the code and then just see what $_. variables exist at the time of the error. Seems pretty long winded, is there a better approach?

    Many Thanks

    Stuart

  • #97194

    Stuart
    Participant

    Hi, I tried this CATCH:

     }
                        catch
                        { #CATCH002 FN-PM
    
                        $LoggingData =
                        @{
    
                            Name = $ADUser.name
                            GUID = $ADuser.ObjectGUID
                            DN = $ADuser.DistinguishedName
                            TargetName = $_.CategoryInfo.TargetName
                            Exception= $_.Exception.Message
                            Error0=$Error[0]
                            Error1=$Error[1]
                            Error2=$Error[2]
                            Code = 'Error'
                            TryIndex = '002 FN-PM'
    
                        }#End Splat
    
                        [Array]$Invocation= $_.InvocationInfo
                        Write-Log -ErrorData $LoggingData -InvocationError $Invocation
                        } #END #CATCH 002 FN-PM
    

    Here is the log function:

    Function Write-Log ([Array]$SuccessData,[array]$ErrorData,[Array]$InvocationError) {
    
        If ($SuccessData.Code -eq "SUCCESS") {
            Write-Host "[SUCCESS]`t $($SuccessData.FriendlyText) `t ObjectGuid $($SuccessData.GUID) `t DisplayName $($SuccessData.DisplayName)" -ForegroundColor Green
            "[SUCCESS]`t $($SuccessData.FriendlyText) `t $($SuccessData.GUID) `t DisplayName $($SuccessData.DisplayName)`n"| Out-File $Log -Append  }
    
        If ($ErrorData.Code -eq "ERROR") {
            Write-Host "[ERROR]`t TRY Index: $($ErrorData.TryIndex) Name: $($ErrorData.Name) TargetName: $($ErrorData.TargetName) Exception: $($ErrorData.Exception)" -BackgroundColor Red
            "[ERROR]`t TRY Index: $($ErrorData.TryIndex) ObjectGuid: $($ErrorData.GUID) Name: $($ErrorData.Name)`t TargetName: $($ErrorData.TargetName) Exception: $($ErrorData.Exception)" | Out-File $Log -Append
            "[ERROR]`t TRY Index: $($ErrorData.TryIndex) ObjectGuid: $($ErrorData.GUID) Name: $($ErrorData.Name) DN: $($ErrorData.DN)`t TargetName: $($ErrorData.TargetName) Exception:  $($ErrorData.Exception) Error0: $($ErrorData.Error0) Error1: $($ErrorData.Error1) Error2: $($ErrorData.Error2)" | Out-File $ErrorLog -Append
             $invocation | Out-File $ErrorLog -Append }
            }
    
    

    Seems to work quite well. So this now seems to capture ALL errors, however it still dumps the errors out onto the screen which is really messy. How can I suppress that?

    Also at the start I have put $ErrorActionPreference = 'SilentlyContinue' which in theory should stop the CATCH portion from working as the commendlets wont 'terminate' when they error, however it seems to work still, not sure why.

    If I set $ErrorActionPreference = 'Stop' then the script fails as soon as one terminating error is detected. I think I am misunderstanding how TRY/CATCH works despite reading many articles about it.

    Below is the full code in case it helps

    Thanks

    Stuart

    $ScriptInfo = @"
    ================================================================================
    Export-MailboxMigrationDetails.ps1 | v1.0.0
    by Stuart Hendry
    ================================================================================
    SAMPLE SCRIPT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
    "@
    
    #==========================Creating variables and paths==========================#
    $ErrorActionPreference = 'SilentlyContinue'
    $path=Test-Path c:\O365Reports
    If ($path -like "False") {md c:\O365Reports} else {}
    $second=(get-date).Second
    $minute=(get-date).Minute
    $hour=(get-date).Hour
    $day=(get-date).Day
    $month=(get-date).Month
    $year=(get-date).Year
    $time="$hour.$minute.$second"
    $ReportPreText="AllMailboxSummary"
    $DMY="$day.$Month.$year"
    $report="$ReportPreText-$DMY-$time"
    $Reportx=@()
    $log="c:\O365Reports\$DMY-$Time-log.txt"
    $ErrorLog="c:\O365Reports\$DMY-$Time-Errorlog.txt"
    $i=0
    
    $IncludeMailboxAccess = $true
    $IncludeSendAs = $true
    $IncludeSendOnBehalf = $true
    $IncludeFolderDelegates = $true
    $IncludeCommonFoldersOnly = $true
    $DelegatesToSkip = "NT AUTHORITY\SELF","DOMAIN\BESADMIN","DOMAIN\Administrators"
    $IncludeSecurityGroups = $True
    $ExpandDistributionGroups = $false
    $hash = @{} #This hash table is used by the Check-Delegates function
    
    
    
    #==========================Functions==========================#
    
    Function Connect-OnPremiseExchange{ 
    
        #Connects to Exchange On Premise, this will revive any existing sessions
        #Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File "C:\O365Reports\EXpassword.txt"
        $ComputerName = '*****' 
        $password=get-content "C:\O365Reports\EXpassword.txt" | ConvertTo-SecureString
        $userid='******'
        $UserCredential=New-Object System.Management.Automation.PSCredential $userid,$password
    
        $Sessions = @( Get-PSSession | Where-Object {
        ( $_.computername -EQ $ComputerName ) -AND ( $_.State -EQ 'Opened' ) } )
    
        If ( $Sessions )
        {
        If ( $Sessions.Count -GT 1 )
        {
            $Session   = $Sessions | Select-Object -First 1
            $LeftOvers = $Sessions | Where-Object { -Not ( $_.Id -EQ $Session.Id ) }
            $LeftOvers | Remove-PSSession -ErrorAction SilentlyContinue | Out-Null
        }
    
        Else { $Session = $Sessions }
        }
        Else
        {
        $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$ComputerName/PowerShell/ -Authentication Kerberos -Credential $UserCredential # Create new session.
        }
    
        Import-PSSession $Session[0] -AllowClobber # Use this.
     } # Close Function
    
    Function Write-Log ([Array]$SuccessData,[array]$ErrorData,[Array]$InvocationError) {
    
        If ($SuccessData.Code -eq "SUCCESS") {
            Write-Host "[SUCCESS]`t $($SuccessData.FriendlyText) `t ObjectGuid $($SuccessData.GUID) `t DisplayName $($SuccessData.DisplayName)" -ForegroundColor Green
            "[SUCCESS]`t $($SuccessData.FriendlyText) `t $($SuccessData.GUID) `t DisplayName $($SuccessData.DisplayName)`n"| Out-File $Log -Append  }
    
        If ($ErrorData.Code -eq "ERROR") {
            Write-Host "[ERROR]`t TRY Index: $($ErrorData.TryIndex) Name: $($ErrorData.Name) TargetName: $($ErrorData.TargetName) Exception: $($ErrorData.Exception)" -BackgroundColor Red
            "[ERROR]`t TRY Index: $($ErrorData.TryIndex) ObjectGuid: $($ErrorData.GUID) Name: $($ErrorData.Name)`t TargetName: $($ErrorData.TargetName) Exception: $($ErrorData.Exception)" | Out-File $Log -Append
            "[ERROR]`t TRY Index: $($ErrorData.TryIndex) ObjectGuid: $($ErrorData.GUID) Name: $($ErrorData.Name) DN: $($ErrorData.DN)`t TargetName: $($ErrorData.TargetName) Exception:  $($ErrorData.Exception) Error0: $($ErrorData.Error0) Error1: $($ErrorData.Error1) Error2: $($ErrorData.Error2)" | Out-File $ErrorLog -Append
             $invocation | Out-File $ErrorLog -Append }
            }
    
    Function Check-Delegates ([string]$DelegateID,[string]$objectguid,[string]$DisplayName,[string]$DelegateAccess) {
        $CheckDelegate = Get-Recipient $DelegateID -ErrorAction SilentlyContinue
    
        If ($CheckDelegate -eq $null) {
            $CheckDelegate = Get-Group $DelegateID -ErrorAction SilentlyContinue }
    
        If ($CheckDelegate -ne $null) {
            If (($CheckDelegate.RecipientType -like "Mail*" -and $IncludeDistributionGroups -eq $false) -or $CheckDelegate.RecipientType -like "*Mailbox") {
                $DelegateName = $CheckDelegate.Name
                $DelegateEmail = $CheckDelegate.PrimarySmtpAddress
    
                $obj=new-object System.Object
                $obj|add-member -membertype NoteProperty -name "ObjectGuid" -value "$objectguid"
                $obj|add-member -membertype NoteProperty -name "ExchangeGuid" -value ""
                $obj|add-member -membertype NoteProperty -name "SamAccountName" -value ""
                $obj|add-member -membertype NoteProperty -name "UserPrincipalName" -value ""
                $obj|add-member -membertype NoteProperty -name "DisplayName" -value "$DisplayName"
                $obj|add-member -membertype NoteProperty -name "Company" -value ""
                $obj|add-member -membertype NoteProperty -name "Department" -value ""
                $obj|add-member -membertype NoteProperty -name "JobTitle" -value ""
                $obj|add-member -membertype NoteProperty -name "PrimarySmtpAddress" -value ""
                $obj|add-member -membertype NoteProperty -name "Database" -value ""
                $obj|add-member -membertype NoteProperty -name "ItemCount" -value ""
                $obj|add-member -membertype NoteProperty -name "TotalItemSize" -value ""
                $obj|add-member -membertype NoteProperty -name "ArchiveItemCount" -value ""
                $obj|add-member -membertype NoteProperty -name "ArchiveTotalItemSize" -value ""
                $obj|add-member -membertype NoteProperty -name "CombinedTotalSize" -value ""
                $obj|add-member -membertype NoteProperty -name "EA1" -value ""
                $obj|add-member -membertype NoteProperty -name "EA2" -value ""
                $obj|add-member -membertype NoteProperty -name "EA3" -value ""
                $obj|add-member -membertype NoteProperty -name "EA4" -value ""
                $obj|add-member -membertype NoteProperty -name "EA5" -value ""
                $obj|add-member -membertype NoteProperty -name "LastLogonDate" -value ""
                $obj|add-member -membertype NoteProperty -name "RecipientType" -value ""
                $obj|add-member -membertype NoteProperty -name "RecipientTypeDetails" -value ""
                $obj|add-member -membertype NoteProperty -name "DelegateName" -value $DelegateName
                $obj|add-member -membertype NoteProperty -name "DelegateEmail" -value $DelegateEmail
                $obj|add-member -membertype NoteProperty -name "DelegateAccess" -value $DelegateAccess
     
                Build-Report -obj $obj
                
                }
    
            If ($CheckDelegate.RecipientType -like "*Group") {
                Write-Log "ALERT: Group [$($CheckDelegate.Name)] found as delgate of $($DisplayName)."
                        $DelegateName = $DelegateID + ":" + $CheckMember.Name
                        $DelegateEmail = $CheckMember.PrimarySmtpAddress
    
                $obj=new-object System.Object
    
                $obj|add-member -membertype NoteProperty -name "ObjectGuid" -value "$objectguid"
    
                $obj|add-member -membertype NoteProperty -name "ExchangeGuid" -value ""
    
                $obj|add-member -membertype NoteProperty -name "SamAccountName" -value ""
    
                $obj|add-member -membertype NoteProperty -name "UserPrincipalName" -value ""
    
                $obj|add-member -membertype NoteProperty -name "DisplayName" -value "$DisplayName"
    
                $obj|add-member -membertype NoteProperty -name "Company" -value ""
    
                $obj|add-member -membertype NoteProperty -name "Department" -value ""
    
                $obj|add-member -membertype NoteProperty -name "JobTitle" -value ""
                               
                $obj|add-member -membertype NoteProperty -name "PrimarySmtpAddress" -value ""
    
                $obj|add-member -membertype NoteProperty -name "Database" -value ""
    
                $obj|add-member -membertype NoteProperty -name "ItemCount" -value ""
    
                $obj|add-member -membertype NoteProperty -name "TotalItemSize" -value ""
    
                $obj|add-member -membertype NoteProperty -name "ArchiveItemCount" -value ""
    
                $obj|add-member -membertype NoteProperty -name "ArchiveTotalItemSize" -value ""
    
                $obj|add-member -membertype NoteProperty -name "CombinedTotalSize" -value ""
    
                $obj|add-member -membertype NoteProperty -name "EA1" -value ""
    
                $obj|add-member -membertype NoteProperty -name "EA2" -value ""
    
                $obj|add-member -membertype NoteProperty -name "EA3" -value ""
    
                $obj|add-member -membertype NoteProperty -name "EA4" -value ""
    
                $obj|add-member -membertype NoteProperty -name "EA5" -value ""
    
                $obj|add-member -membertype NoteProperty -name "LastLogonDate" -value ""
    
                $obj|add-member -membertype NoteProperty -name "RecipientType" -value ""
    
                $obj|add-member -membertype NoteProperty -name "RecipientTypeDetails" -value ""
                
                $obj|add-member -membertype NoteProperty -name "DelegateName" -value $DelegateName
    
                $obj|add-member -membertype NoteProperty -name "DelegateEmail" -value $DelegateEmail
    
                $obj|add-member -membertype NoteProperty -name "DelegateAccess" -value $DelegateAccess
     
                Build-Report -obj $obj
                        } } 
    
      
     }
    
    Function Process-Mailboxes { #FN-PM
    
    [cmdletbinding()]
    param([string]$Name)
    
    
    
            Get-Mailbox -ResultSize 1000 |?{!($_.DisplayName -like "*Discovery S*")} | select identity,DisplayName,DistinguishedName,guid,ExchangeGuid,ArchiveGuid,SamAccountName,UserprincipalName,DisplayName,PrimarySmtpAddress,Database,ServerName,RecipientType,RecipientTypeDetails| foreach-object{
            #Begin ForLoop
    
              #Try{ #TRY001 FN-PM
    
    
                
                #*** Increment Counters and Write to Screen
                $i++
                Write-Host "$($i) Mailbox(s) processed . . ."
    
                #*** Gather AD and Mailbox Attributes and send to reporting function ***
    
                $ADUser=(Get-ADUser $_.guid -Properties department,company,title,lastlogondate,extensionAttribute1,extensionAttribute2,extensionAttribute3,extensionAttribute4,extensionAttribute5)
                $Department=$Aduser.department
                $Company=$ADUser.company
                $JobTitle=$aduser.title
                $LastLogonDate=$Aduser.LastLogonDate
                $EA1=$Aduser.extensionAttribute1
                $EA2=$Aduser.extensionAttribute2
                $EA3=$Aduser.extensionAttribute3
                $EA4=$Aduser.extensionAttribute4
                $EA5=$Aduser.extensionAttribute5
                
                #*** Start Hash System Object for Report ***
    
                $obj=new-object System.Object
                $obj|add-member -membertype NoteProperty -name "ObjectGuid" -value $_.Guid
                $obj|add-member -membertype NoteProperty -name "ExchangeGuid" -value $_.ExchangeGuid
                $obj|add-member -membertype NoteProperty -name "SamAccountName" -value $_.SamAccountName
                $obj|add-member -membertype NoteProperty -name "UserPrincipalName" -value $_.UserPrincipalName
                $obj|add-member -membertype NoteProperty -name "DisplayName" -value $_.DisplayName
                $obj|add-member -membertype NoteProperty -name "Company" -value $Company
                $obj|add-member -membertype NoteProperty -name "Department" -value $Department
                $obj|add-member -membertype NoteProperty -name "JobTitle" -value $JobTitle
                $obj|add-member -membertype NoteProperty -name "PrimarySmtpAddress" -value $_.PrimarySMTPAddress
                $obj|add-member -membertype NoteProperty -name "Database" -value $_.Database
                $obj|add-member -membertype NoteProperty -name "EA1" -value $EA1
                $obj|add-member -membertype NoteProperty -name "EA2" -value $EA2
                $obj|add-member -membertype NoteProperty -name "EA3" -value $EA3
                $obj|add-member -membertype NoteProperty -name "EA4" -value $EA4
                $obj|add-member -membertype NoteProperty -name "EA5" -value $EA5
                $obj|add-member -membertype NoteProperty -name "LastLogonDate" -value $LastLogonDate
                $obj|add-member -membertype NoteProperty -name "RecipientType" -value $_.RecipientType
                $obj|add-member -membertype NoteProperty -name "RecipientTypeDetails" -value $_.RecipientTypeDetails
    
                #*** Gather Mailbox Statistics Attributes ***
    
                    Try{ #TRY002 FN-PM
    
                        $ItemCount=(Get-MailboxStatistics -Identity $_.DisplayName).ItemCount
                        $TotalItemSize=(Get-MailboxStatistics -Identity $_.DisplayName).totalitemsize.value.ToMB()
                        $obj|add-member -membertype NoteProperty -name "ItemCount" -value $ItemCount
                        $obj|add-member -membertype NoteProperty -name "TotalItemSize" -value $TotalItemSize
    
                        }
                        catch
                        { #CATCH002 FN-PM
    
                        $LoggingData =
                        @{
    
                            Name = $ADUser.name
                            GUID = $ADuser.ObjectGUID
                            DN = $ADuser.DistinguishedName
                            TargetName = $_.CategoryInfo.TargetName
                            Exception= $_.Exception.Message
                            Error0=$Error[0]
                            Error1=$Error[1]
                            Error2=$Error[2]
                            Code = 'Error'
                            TryIndex = '002 FN-PM'
    
                        }#End Splat
    
                        [Array]$Invocation= $_.InvocationInfo
                        Write-Log -ErrorData $LoggingData -InvocationError $Invocation
                        } #END #CATCH 002 FN-PM
                    
    
                #Check if the mailbox has an archive & Gather stats if exists
    
                if(($_.ArchiveGuid -ne "00000000-0000-0000-0000-000000000000")){
    
                    Try{ #TRY003 FN-PM
    
                        $ArchiveItemCount=(Get-MailboxStatistics -Identity $_.DisplayName -Archive).ItemCount
                        $ArchiveTotalItemSize=(Get-MailboxStatistics –identity $_.DistinguishedName -Archive).totalitemsize.value.ToMB()
                        $obj|add-member -membertype NoteProperty -name "ArchiveItemCount" -value $ArchiveItemCount
                        $obj|add-member -membertype NoteProperty -name "ArchiveTotalItemSize" -value $ArchiveTotalItemSize
    
                        }
                        catch
                        { #CATCH003 FN-PM
    
                        $LoggingData = #Begin Splat
                        @{
    
                            Name = $ADUser.name
                            GUID = $ADuser.ObjectGUID
                            DN = $ADuser.DistinguishedName
                            TargetName = $_.CategoryInfo.TargetName
                            Exception= $_.Exception.Message
                            Error0=$Error[0]
                            Error1=$Error[1]
                            Error2=$Error[2]
                            Code = 'Error'
                            TryIndex = '003'
    
                        } #End Splat
    
                        [Array]$Invocation= $_.InvocationInfo
                        Write-Log -ErrorData $LoggingData -InvocationError $Invocation
    
                        } #END Catch003 FN-PM
    
                } #END IF (ArchiveGUID)
    
                $CombinedTotal=$TotalItemSize+$ArchiveTotalItemSize
                $obj|add-member -membertype NoteProperty -name "CombinedTotalSize" -value $CombinedTotal
    
                # *** These three are added so that the $obj template first committed to the log file report
                # *** by Build-Report has all headings added.  Later the Check-Delegates function will add these
                # *** three headings.  If they werent first added here then Check-Delegates could not subsequently 
                # *** add them in. 
                
                $obj|add-member -membertype NoteProperty -name "DelegateName" -value ""
                $obj|add-member -membertype NoteProperty -name "DelegateEmail" -value ""
                $obj|add-member -membertype NoteProperty -name "DelegateAccess" -value ""
    
                #*** Sends $OBJ array to the Build-Report function**
    
                Build-Report -Obj $obj
    
                # *** Export mailbox access permissions and log ***
    
                If ($IncludeMailboxAccess -eq $true) {
    
                    $SuccessData=
                    @{
                        Code="SUCCESS"
                        GUID=$_.Guid
                        DisplayName=$_.displayname
                        FriendlyText="Interrogating Mailbox:"
    
                     } #END Splat
    
                    # *** Send to Log Function ***
    
                    Write-Log $SuccessData
    
                    $Delegates = @()
                    $Delegates = (Get-MailboxPermission $_.DistinguishedName | Where { $DelegatesToSkip -notcontains $_.User -and $_.IsInherited -eq $false })
                        If ($Delegates -ne $null) {
                            ForEach ($Delegate in $Delegates) {
                                $DelegateAccess = $Delegate.AccessRights
                                Check-Delegates -DelegateID $Delegate.User -objectguid $_.guid -DisplayName $_.Displayname -DelegateAccess $DelegateAccess
    
                                } #END ForEach
    
                        } #END IF (Delegates)
                  
                } #END IF (MailboxAccess Check)
    
          
            } #END ForLoop
    
        
    
    } #END Function   
    
    Function Build-Report{
    
        [CmdletBinding()]
    
    Param(
        [Parameter(Mandatory=$False)]   
        [Array]$Obj,
        [Parameter(Mandatory=$False)]
        [String]$WriteToLog,
        [Parameter(Mandatory=$False)]
        [String]$ReceiveDelegates,
        [Parameter(Mandatory=$False)]
        [String]$PlaceHolder4,
        [Parameter(Mandatory=$False)]
        [String]$PlaceHolder5,
        [Parameter(Mandatory=$False)]
        [String]$PlaceHolder6,
        [Parameter(Mandatory=$False)]
        [String]$PlaceHolder7,
        [Parameter(Mandatory=$False)]
        [String]$PlaceHolder8,
        [Parameter(Mandatory=$False)]
        [String]$PlaceHolder9)
    
        TRY{
                #*** Building Report ***
    
    
                $obj|export-csv c:\O365Reports\$report.csv -Append
    
                    }
                    catch
                    {
                    $LoggingData =
                    @{
                        Name = $ADUser.name
                        GUID = $ADuser.ObjectGUID
                        DN = $ADuser.DistinguishedName
                        TargetName = $_.CategoryInfo.TargetName
                        Exception= $_.Exception.Message
                        Error0=$Error[0]
                        Error1=$Error[1]
                        Error2=$Error[2]
                        Code = 'Error'
                        TryIndex = '004'
                    }
    
                    [Array]$Invocation= $_.InvocationInfo
                    Write-Log -ErrorData $LoggingData -InvocationError $Invocation
    
                    }
    
    }
    
    #==========================Script Body==========================#
    
    Connect-OnPremiseExchange
    
    Process-Mailboxes
    
    
    
  • #97209

    Joel Sallow
    Participant

    So, when catching an error, you'll get an ErrorRecord object: https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.errorrecord?view=powershellsdk-1.1.0

    That page lists all the properties. Most commonly utilised is the Exception property, which contains an Exception-type object, with a specific type name based on how it was generated. https://msdn.microsoft.com/en-us/library/system.exception(v=vs.110).aspx

    That page has a full list of all .NET exception types, but many custom types exist and are frequently in use in various code libraries, and I believe PowerShell itself also has some custom Exceptions built in. All exceptions generally have the same properties, though, and you can get whichever ones you deem relevant from that list and include those.

    That said... Generally speaking, the most useful bits of information that I've found are:

    $_.TargetObject
    $_.ErrorDetails
    $_.Exception
    $_.Exception.Message
    $_.Exception.InnerException
    

    Do note that InnerException is itself another exception type, and may not always be present. As such, it has its own Message property as well. You can test for its existence using:

    if ($_.Exception.InnerException) {}
    

    And InnerExceptions themselves may also have their own inner exceptions, stacking all the way down to the very root cause of the error. However, in the vast, vast majority of cases, one or two levels deep is all that is useful. The surface level exceptions generally tell you what's actually going wrong, and the rest are mainly just technical errors caused by what you did wrong.

    In large part, most of this isn't super necessary. Logging all of it is often a waste of time and disk space, so in most cases I'd recommend just taking the top-level exception and message, the error details, and the target object.

  • #97257

    Stuart
    Participant

    Thank you

  • #97419

    Stuart
    Participant

    I put in a option to turn off more detailed logging as you were right, it started to chew up a lot of disk!

You must be logged in to reply to this topic.