目前正在努力理解为什么我的脚本没有像我预期的那样工作,所以我想我会把问题告诉你:)
基本上,我正在编写一个程序,它将在系统上搜索XML文件并迭代它们以确定它们是否格式正确。为此,我将Get-ChildItem
查询的输出传递给ForEach-Object
语句,并将详细信息记录在稍后要解析的ArrayList对象中。脚本看起来像这样;
// Variable declaration removed for brevity
Get-ChildItem -Path $dirFilePaths -Include "*.xml" -Recurse | ForEach-Object {
$tmpFile= $_;
$tmpXml= New-Object System.Xml.XmlDocument;
try {
$tmpXml.Load($tmpFile.FullName);
$tmpValues= New-Object PSObject;
$tmpValues | Add-Member -MemberType NoteProperty -Name "File_Name" -Value $tmpFile.Name;
$tmpValues | Add-Member -MemberType NoteProperty -Name "File_Path" -Value $tmpFile.FullName;
$tmpValues | Add-Member -MemberType NoteProperty -Name "File_Status" -Value "OK";
$arlFilesSuccess.Add($tmpValues)
}
catch {
$tmpValues= New-Object PSObject;
$tmpValues | Add-Member -MemberType NoteProperty -Name "File_Name" -Value $tmpFile.Name;
$tmpValues | Add-Member -MemberType NoteProperty -Name "File_Path" -Value $tmpFile.FullName;
$tmpValues | Add-Member -MemberType NoteProperty -Name "File_Status" -Value "NOT OK";
$tmpValues | Add-Member -MemberType NoteProperty -Name "Error_Details" -Value $Error[-1].Exception;
$arlFilesFailure.Add($tmpValues);
}
}
我面临的问题是$Error
变量实际上并不包含任何有关如果$tmpXml.Load()
方法因文件问题而失败而无法加载XML的信息。例如,如果我将名为“style.xml”的系统上的文件调用到脚本之外的$ tmpXml中,我会从PowerShell窗口中收到以下错误消息;
Exception calling "Load" with "1" argument(s): "The 'install-disabled' start tag on line 26 position 3 does not match the end tag of 'install'.
Line 26, position 105."
At line:1 char:1
+ $tmpXml.Load($arlFilesFailure[20].File_Path)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
但是当我在PowerShell控制台中输入$Error.count
时,由于某种未知原因,我得到的值为0
。我已尝试将$ErrorActionPreference
变量修改为Stop
以强制终止错误;我也尝试将上面的脚本写入ScriptBlock并使用Invoke-Command
调用它,并将ErrorVariable
CommonParameter设置为自定义变量 - 仍然没有捕获命令的错误信息,我无法弄清楚这里发生了什么!
这是否与遇到的异常是MethodInvocationException
并且未被归类为终止错误这一事实有关?它在Try / Catch语句中被“捕获”,因此它必须是终止错误,不是吗?任何人都可以告诉我为什么这些细节没有记录在全局$Error
变量中(以及我如何检索该信息)?
答案 0 :(得分:1)
在catch
块中,变量$_
表示当前异常(如
ErrorRecord
)。您不必使用$Error
。但是当你必须使用时
$Error
请记住,最近的错误是$Error[0]
,即第一个错误
清单。
此外,ForEach-Object
可能会导致一些不明确的错误,请参阅以下示例:
PowerShellTraps//Cmdlets/ForEach-Object
答案 1 :(得分:0)
我建议在这里使用PowerShell Community Extensions module。它已经有一个Test-Xml函数,可以完成你想要做的事情。