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



我正在尝试编写一个小型的Powershell脚本来做一些事情

1)解析我的Outlook中的收件箱项目 2) 搜索正则表达式字符串 3) 将与正则表达式字符串匹配的行转储到 CSV 中

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

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

户名: 金邦

我试着在各个部分打一个"写主机$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 Names*: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;博士

用:

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

而不是

Write-Host $variable

以获得有意义的输出格式。

背景信息和调试提示如下。


请尝试以下方法的组合:

使用交互式调试:

  • 将 GUI 编辑器 Visual Studio Code 与 PowerShell 扩展结合使用,在代码中放置断点并以交互方式检查变量值。(在Windows PowerShell中,您也可以使用ISE,但它已经过时了。

  • 不太方便的是,使用*-PSBreakpointcmdlet 来管理在控制台(终端)窗口中运行脚本时命中的断点。一个简单的替代方法是将Wait-Debugger语句添加到脚本中,当命中时,这些语句会无条件中断。

>生成有用的调试输出:

通常使用Write-Debug而不是Write-Host,这有两个优点:

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

    • 默认情况下,它们是静默的,并且仅在选择加入的基础上生成输出,通过事先(临时)设置$DebugPreference = 'Continue'或通过-Debug开关(如果您的脚本/函数是高级脚本/函数,但请注意,在Windows PowerShell中,每当点击Write-Debug调用时,都会显示提示)。
    • 但是,您需要为在代码中保留Write-Debug调用而付出性能损失。
  • 调试输出清楚地标记为这样,彩色并以DEBUG:为前缀。

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

若要获取与在控制台中相同的丰富输出格式,请使用以下技术,该技术使用Out-String作为帮助程序命令:

$variable | Out-String | Write-Debug

如果要显式控制视图(列表、表、宽视图与自定义),请插入Format-*调用;例如:

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

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


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

我发现捕获Out-Host$Host.UI.Write()方法的唯一方法是捕获控制台缓冲区,例如:

$Host.UI.Write('aaa')  # or Out-Host 'aaa'
$rect = [System.Management.Automation.Host.Rectangle]::new(0,0,3,1)
$buff = $Host.UI.RawUI.GetBufferContents($rect)
(1..3 | foreach {$buff[0,$_].Character}) -join ''
# The constructor is: [Rectangle]::new(Left,Top,Right,Bottom)

最新更新