powershelldebuggingwrite-host

Trying to test code, keep getting "System.____comobject" instead of variable value


I'm trying to write a small powershell script that does a few things

1) Parses Inbox items in my outlook 2) Searches for a RegEx string 3) Dumps the line that matches the RegEx string into a CSV

I can't get #3 to work. It definitely runs for about 10 minutes, but the resulting csv is empty.

Here's a snippet of what I want it to look for:

Account Name: Jbond

I tried just slapping a "Write-Host $variable" in various parts to see what was happening, but all I get is "System.____comobject". I can't find a solution online to just convert this into plain text.

Add-Type -Assembly "Microsoft.Office.Interop.Outlook"
$Outlook = New-Object -ComObject Outlook.Application
$namespace = $Outlook.GetNameSpace("MAPI")
$inbox = $namespace.GetDefaultFolder([Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderInbox)                                                                                  
$RE = [RegEx]'(?sm)Account Name\s*:\s*(?<AccName>.*?)$.*'

$Data = ForEach ($item in $inbox.items){
    $resultText = $item.item.Value
    Write-Host $resultText
    if ($item.from -like "email@email.org"){
        if ($item.body -match $RE){
            [PSCustomObject]@{
                AccName = $Matches.AccName
            }
        }
    }
}
$Data 
$Data | Export-CSv '.\data.csv' -NoTypeInformation

Solution

  • tl;dr:

    Use:

    $variable | Out-Host # or: Out-Host InputObject $variable
    

    rather than

    Write-Host $variable
    

    to get meaningful output formatting.

    Background information and debugging tips below.


    Try a combination of the following approaches:

    Use interactive debugging:


    Produce helpful debugging output:

    Generally, use Write-Debug rather than Write-Host, which has two advantages:

    The problem you experienced with Write-Host is that all Write-* cmdlets perform simple .ToString() stringification of their arguments, which often results in unhelpful representations, such as System.____comobject in your case.

    To get the same rich output formatting you would get in the console, use the following technique, which uses Out-String as a helper command:

    $variable | Out-String | Write-Debug
    

    If you want to control the view (list vs. table vs. wide vs. custom) explicitly, insert a Format-* call; e.g.:

    $variable | Format-List | Out-String | Write-Debug
    

    It is generally only the standard Out-* cmdlets that use PowerShell's output formatting system.


    A quick-and-dirty alternative to Write-Debug is to use Out-Host rather than Write-Host - e.g., for quick insertion of debugging commands that you'll remove later; Out-Host itself performs the usual output formatting, which simplifies matters:

    # Default for-display formatting
    $variable | Out-Host  # or: Out-Host -InputObject $variable
    
    # Explicit formatting
    $variable | Format-List | Out-Host
    

    Caveat: Aside from formatting, another important difference between Write-Host and Out-Host is that in PSv5+ only Write-Host writes to the host via the information stream (stream number 6), whereas Out-Host truly writes directly to the host, which means that its output cannot be captured with redirections such as 6> or *> - see about_Redirection.