PowerShell try catch会丢失重复的访问错误
似乎无法可靠地捕获所有错误。Try catch onPowerShell try catch会丢失重复的访问错误,powershell,error-handling,Powershell,Error Handling,似乎无法可靠地捕获所有错误。Try catch onget ChildItem不报告Try catch之外报告的所有访问错误 编辑:try-catch不可靠不是真的,它只报告一个错误是有充分理由的。请参阅我对公认答案的评论,以了解我在这个问题背后的误解 在运行PowerShell 5.1的Windows 10 Pro 64中,此脚本: $sScriptName = "ErrorTest.ps1" write-host ("I will get the file structure of ""
get ChildItem
不报告Try catch之外报告的所有访问错误
编辑:try-catch不可靠不是真的,它只报告一个错误是有充分理由的。请参阅我对公认答案的评论,以了解我在这个问题背后的误解
在运行PowerShell 5.1的Windows 10 Pro 64中,此脚本:
$sScriptName = "ErrorTest.ps1"
write-host ("I will get the file structure of ""C:\Windows\System32"", but this yields two access-denied errors:")
$aoFileSystem = @(get-ChildItem "C:\Windows\System32" -recurse -force)
write-host ("I will now do it again and trap for those errors. But I only get one of them:")
try {$aoFileSystem = @(get-ChildItem $sPath -recurse -force -ErrorAction Stop)}
catch [System.UnauthorizedAccessException]
{$sErrorMessage = $_.ToString()
write-host ("System.UnauthorizedAccessException: " + $sErrorMessage.substring(20, $sErrorMessage.length - 32))}
以管理员身份在ISE中运行,获得以下输出:
PS C:\WINDOWS\system32> D:\<path>\ErrorTest.ps1
I will get the file structure of "C:\Windows\System32", but this yields two access-denied errors:
get-ChildItem : Access to the path 'C:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache\Content.IE5' is denied.
At D:\<path>\ErrorTest.ps1:5 char:19
+ ... aoFileSystem = @(get-ChildItem "C:\Windows\System32" -recurse -force)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\Windows\Syst...che\Content.IE5:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
get-ChildItem : Access to the path 'C:\Windows\System32\LogFiles\WMI\RtBackup' is denied.
At D:\<path>\ErrorTest.ps1:5 char:19
+ ... aoFileSystem = @(get-ChildItem "C:\Windows\System32" -recurse -force)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\Windows\Syst...es\WMI\RtBackup:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
I will now do it again and trap for those errors. But I only get one of them:
System.UnauthorizedAccessException: C:\WINDOWS\system32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache\Content.IE5
PS C:\WINDOWS\system32>
PS C:\WINDOWS\system32>D:\\ErrorTest.ps1
我将获得文件结构“C:\Windows\System32”,但这会产生两个拒绝访问错误:
get-ChildItem:对路径“C:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache\Content.IE5”的访问被拒绝。
在D:\\ErrorTest.ps1:5字符:19
+ ... aoFileSystem=@(获取子项“C:\Windows\System32”-递归-force)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+CategoryInfo:PermissionDenied:(C:\Windows\Syst…che\Content.IE5:String)[Get ChildItem],UnauthorizedAccessException
+FullyQualifiedErrorId:DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
get-ChildItem:对路径“C:\Windows\System32\LogFiles\WMI\RtBackup”的访问被拒绝。
在D:\\ErrorTest.ps1:5字符:19
+ ... aoFileSystem=@(获取子项“C:\Windows\System32”-递归-force)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+CategoryInfo:PermissionDenied:(C:\Windows\Syst…es\WMI\RtBackup:String)[Get ChildItem],UnauthorizedAccessException
+FullyQualifiedErrorId:DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
我现在将再次这样做,并为这些错误设置陷阱。但我只得到其中一个:
System.UnauthorizedAccessException:C:\WINDOWS\system32\config\systemprofile\AppData\Local\Microsoft\WINDOWS\INetCache\Content.IE5
PS C:\WINDOWS\system32>
我想记录访问错误,但当我试图捕捉它们时,我只得到第一个错误。当我为他们设陷阱时,我需要做什么才能让第二个出现
编辑:我收到一条消息,告诉我需要编辑我的问题,以解释它与其他问题的不同之处。因此,我将在这里重复我对怀疑论者下面评论的回应。该问题适用于
ForEach
循环中的getchilditem
。我的问题不涉及这样的循环。尽管如此,我还是尝试了接受答案的方法,使用了-ErrorAction-SilentlyContinue
,但这样可以隐藏错误而不会捕获错误。然而,在我找到的并将作为答案发布的解决方案中,我确实使用了-ErrorAction SilentlyContinue
与-ErrorVariable
组合使用,非常简单!您在第二条目录访问语句中指定了参数-ErrorAction Stop。将其切换到-ErrorAction Continue,您将收到两条错误消息。非常简单!您在第二条目录访问语句中指定了参数-ErrorAction Stop。将其切换到-ErrorAction Continue时,您会收到两条错误消息。我对ErrorAction
参数进行了一些研究,发现了ErrorVariable
参数。(两者都是,所以它们不会出现在的文档中。)从那以后,我就能够找出如何正确捕获错误
下面的新脚本显示了四种方法。方法2和方法3效果良好。方法4不起作用,因为它是。方法1,最初的try-catch方法,不起作用,我仍然不知道为什么。这是令人不安的,因为错误捕获按预期工作很重要。如果我不知道会出现两个错误,我就不会知道try-catch没有给我正确的输出
我不接受这个(我自己的)答案,因为,尽管下面的脚本显示了两种正确捕获这些错误的方法,如果有人能解释为什么try-catch不起作用,那就更好了。
新脚本:
$sScriptName = "ErrorTest.ps1"
$sPath = "C:\Windows\System32"
write-host ("I will get the file structure of """ + $sPath + """, but this yields two access-denied errors:")
$aoFileSystem = @(get-ChildItem $sPath -recurse -force)
write-host ("I will now do it again and trap for those errors.")
write-host ("`r`nMethod 1: Original method using try-catch (incorrect results; only finds one of the two errors; why?):")
try {$aoFileSystem = @(get-ChildItem $sPath -recurse -force -ErrorAction Stop)}
catch [System.UnauthorizedAccessException]
{$sErrorMessage = $_.ToString()
write-host ("System.UnauthorizedAccessException: " + $sErrorMessage.substring(20, $sErrorMessage.length - 32))}
write-host ("`r`nGet array for Methods 2 to 4.")
$aoFileSystem = @(get-ChildItem $sPath -recurse -force -ErrorAction SilentlyContinue -ErrorVariable aoChildItemError)
write-host ("`r`nMethod 2: Output by piping to ForEach-object (correct results):")
$aoChildItemError |
ForEach-object `
{$oErrorRecord = $_
write-host ($oErrorRecord.CategoryInfo.reason + ": """ + $oErrorRecord.TargetObject + """")}
write-host ("`r`nMethod 3: Output by for loop (correct results):")
for ($nCount = 0; $nCount -lt $aoChildItemError.count; $nCount++)
{$oErrorRecord = $aoChildItemError[$nCount]
write-host ($oErrorRecord.CategoryInfo.reason + ": """ + $oErrorRecord.TargetObject + """")}
write-host ("`r`nMethod 4: Output by ForEach-object loop without pipeline (incorrect results because it incorrectly attempts to use the parameter ""InputObject"" in ""ForEach-object""):")
ForEach-object -InputObject $aoChildItemError `
{$oErrorRecord = $_
write-host ($oErrorRecord.CategoryInfo.reason + ": """ + $oErrorRecord.TargetObject + """")}
新产出:
PS C:\WINDOWS\system32> D:\_\z-temp\ErrorTest.ps1
I will get the file structure of "C:\Windows\System32", but this yields two access-denied errors:
get-ChildItem : Access to the path 'C:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache\Content.IE5' is denied.
At D:\_\z-temp\ErrorTest.ps1:6 char:19
+ $aoFileSystem = @(get-ChildItem $sPath -recurse -force)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\Windows\Syst...che\Content.IE5:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
get-ChildItem : Access to the path 'C:\Windows\System32\LogFiles\WMI\RtBackup' is denied.
At D:\_\z-temp\ErrorTest.ps1:6 char:19
+ $aoFileSystem = @(get-ChildItem $sPath -recurse -force)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\Windows\Syst...es\WMI\RtBackup:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
I will now do it again and trap for those errors.
Method 1: Original method using try-catch (incorrect results; only finds one of the two errors; why?):
System.UnauthorizedAccessException: C:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache\Content.IE5
Get array for Methods 2 to 4.
Method 2: Output by piping to ForEach-object (correct results):
UnauthorizedAccessException: "C:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache\Content.IE5"
UnauthorizedAccessException: "C:\Windows\System32\LogFiles\WMI\RtBackup"
Method 3: Output by for loop (correct results):
UnauthorizedAccessException: "C:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache\Content.IE5"
UnauthorizedAccessException: "C:\Windows\System32\LogFiles\WMI\RtBackup"
Method 4: Output by ForEach-object loop without pipeline (incorrect results because it incorrectly attempts to use the parameter "InputObject" in "ForEach-object"):
UnauthorizedAccessException UnauthorizedAccessException : " C:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache\Content.IE5 C:\Window
s\System32\LogFiles\WMI\RtBackup "
PS C:\WINDOWS\system32>
我对
ErrorAction
参数做了一些研究,发现了ErrorVariable
参数。(两者都是,所以它们不会出现在的文档中。)从那以后,我就能够找出如何正确捕获错误
下面的新脚本显示了四种方法。方法2和方法3效果良好。方法4不起作用,因为它是。方法1,最初的try-catch方法,不起作用,我仍然不知道为什么。这是令人不安的,因为错误捕获按预期工作很重要。如果我不知道会出现两个错误,我就不会知道try-catch没有给我正确的输出
我不接受这个(我自己的)答案,因为,尽管下面的脚本显示了两种正确捕获这些错误的方法,如果有人能解释为什么try-catch不起作用,那就更好了。
新脚本:
$sScriptName = "ErrorTest.ps1"
$sPath = "C:\Windows\System32"
write-host ("I will get the file structure of """ + $sPath + """, but this yields two access-denied errors:")
$aoFileSystem = @(get-ChildItem $sPath -recurse -force)
write-host ("I will now do it again and trap for those errors.")
write-host ("`r`nMethod 1: Original method using try-catch (incorrect results; only finds one of the two errors; why?):")
try {$aoFileSystem = @(get-ChildItem $sPath -recurse -force -ErrorAction Stop)}
catch [System.UnauthorizedAccessException]
{$sErrorMessage = $_.ToString()
write-host ("System.UnauthorizedAccessException: " + $sErrorMessage.substring(20, $sErrorMessage.length - 32))}
write-host ("`r`nGet array for Methods 2 to 4.")
$aoFileSystem = @(get-ChildItem $sPath -recurse -force -ErrorAction SilentlyContinue -ErrorVariable aoChildItemError)
write-host ("`r`nMethod 2: Output by piping to ForEach-object (correct results):")
$aoChildItemError |
ForEach-object `
{$oErrorRecord = $_
write-host ($oErrorRecord.CategoryInfo.reason + ": """ + $oErrorRecord.TargetObject + """")}
write-host ("`r`nMethod 3: Output by for loop (correct results):")
for ($nCount = 0; $nCount -lt $aoChildItemError.count; $nCount++)
{$oErrorRecord = $aoChildItemError[$nCount]
write-host ($oErrorRecord.CategoryInfo.reason + ": """ + $oErrorRecord.TargetObject + """")}
write-host ("`r`nMethod 4: Output by ForEach-object loop without pipeline (incorrect results because it incorrectly attempts to use the parameter ""InputObject"" in ""ForEach-object""):")
ForEach-object -InputObject $aoChildItemError `
{$oErrorRecord = $_
write-host ($oErrorRecord.CategoryInfo.reason + ": """ + $oErrorRecord.TargetObject + """")}
新产出:
PS C:\WINDOWS\system32> D:\_\z-temp\ErrorTest.ps1
I will get the file structure of "C:\Windows\System32", but this yields two access-denied errors:
get-ChildItem : Access to the path 'C:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache\Content.IE5' is denied.
At D:\_\z-temp\ErrorTest.ps1:6 char:19
+ $aoFileSystem = @(get-ChildItem $sPath -recurse -force)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\Windows\Syst...che\Content.IE5:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
get-ChildItem : Access to the path 'C:\Windows\System32\LogFiles\WMI\RtBackup' is denied.
At D:\_\z-temp\ErrorTest.ps1:6 char:19
+ $aoFileSystem = @(get-ChildItem $sPath -recurse -force)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\Windows\Syst...es\WMI\RtBackup:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
I will now do it again and trap for those errors.
Method 1: Original method using try-catch (incorrect results; only finds one of the two errors; why?):
System.UnauthorizedAccessException: C:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache\Content.IE5
Get array for Methods 2 to 4.
Method 2: Output by piping to ForEach-object (correct results):
UnauthorizedAccessException: "C:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache\Content.IE5"
UnauthorizedAccessException: "C:\Windows\System32\LogFiles\WMI\RtBackup"
Method 3: Output by for loop (correct results):
UnauthorizedAccessException: "C:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache\Content.IE5"
UnauthorizedAccessException: "C:\Windows\System32\LogFiles\WMI\RtBackup"
Method 4: Output by ForEach-object loop without pipeline (incorrect results because it incorrectly attempts to use the parameter "InputObject" in "ForEach-object"):
UnauthorizedAccessException UnauthorizedAccessException : " C:\Windows\System32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache\Content.IE5 C:\Window
s\System32\LogFiles\WMI\RtBackup "
PS C:\WINDOWS\system32>
发出的错误是非终止错误,并且,根据定义,此类错误不会终止命令,因此单个命令可能会发出多个此类错误Get ChildItem“C:\Windows\System32”-recurse-force
- cmdlet发出的所有非终止错误都可以在指定变量中捕获,该变量的名称可以传递给
公共参数-ErrorVariable
- 此外,默认情况下,所有错误(非终止和终止错误)都记录在会话全局自动
集合变量中$Error
- cmdlet发出的所有非终止错误都可以在指定变量中捕获,该变量的名称可以传递给
/try
仅对终止错误起作用,因此默认情况下,它对仅发出非终止错误的命令(如catch
Get-C)无效