尝试测试代码,不断获取 "System.____comobject" 而不是变量值

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

我正在尝试编写一个可以执行一些操作的小型 powershell 脚本

1) 在我的 outlook 中解析收件箱项目 2) 搜索 RegEx 字符串 3) 将与 RegEx 字符串匹配的行转储到 CSV

我无法让#3 工作。它确实运行了大约 10 分钟,但生成的 csv 是空的。

这是我希望它查找的内容的片段:

Account Name: Jbond

我试着在各个部分拍打 "Write-Host $variable" 看看发生了什么,但我得到的只是 "System.____comobject"。我在网上找不到将其转换为纯文本的解决方案。

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

tl;dr:

使用:

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

而不是

Write-Host $variable

获得有意义的输出格式。

下面是背景信息和调试提示。


尝试结合使用以下方法:

使用交互式调试:

  • 使用 GUI 编辑器 Visual Studio Code with the PowerShell extension 在代码中放置断点并以交互方式检查变量值。 (在 Windows PowerShell 中,您也可以使用 ISE,但它已过时。)

  • 不太方便,在脚本中使用 *-PSBreakpoint cmdlets to manage breakpoints that are hit when you run your script in a console (terminal) window. A simple alternative is to add Wait-Debugger 语句,当命中时,它会无条件中断。


产生有用的调试输出:

一般使用Write-Debug而不是Write-Host,有两个好处:

  • 您可以随时在代码中保留 Write-Debug 调用以进行按需调试:

    • 默认情况下它们是静默的,并且仅在选择加入的基础上产生输出,通过(暂时)预先设置$DebugPreference = 'Continue'或传递-Debug 开关(如果您的脚本/函数是高级脚本/函数,但请注意,在 Windows PowerShell 中,只要出现 prompt Write-Debug 呼叫成功)。
    • 但是,您确实会因为在代码中留下 Write-Debug 调用而付出性能损失。
  • 调试输出被清楚地标记为这样,带有颜色和前缀DEBUG:

您在使用 Write-Host 时遇到的问题是 ll Write-* cmdlet 对其参数执行简单的 .ToString() 字符串化,这通常会导致无用的表示,例如您的 System.____comobject

获得与控制台相同的丰富输出格式,请使用以下技术,该技术将Out-String用作辅助命令:

$variable | Out-String | Write-Debug

如果你想明确地控制视图(list vs. table vs. wide vs. custom),插入一个 Format-* 调用;例如:

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

通常只有标准 Out-* cmdlet 使用 PowerShell 的输出格式化系统。


Write-Debug 的快速替代方法是使用 Out-Host 而不是 Write-Host - 例如,快速插入稍后将删除的调试命令; Out-Host 本身 执行通常的输出格式 ,这简化了事情:

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

# Explicit formatting
$variable | Format-List | Out-Host

警告:除了格式化之外,Write-HostOut-Host 之间的另一个重要区别是在 PSv5+ 中只有 Write-Host 写入主机通过信息流(流号6),而Out-Host真正直接写入主机,这意味着无法捕获其输出 重定向如 6>*> - 见 about_Redirection.