PowerShell tr y-catch丢失重复访问错误

问题描述 投票:0回答:2

在运行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> 

我想记录访问错误,但是当我尝试捕获它们时,我只会得到第一个错误。当我困住他们时,我该怎么做才能使第二个出现?

编辑:我收到一条消息,告诉我我需要编辑问题以解释它与Can PowerShell trap errors in GetChildItem and continue looping?有何不同。因此,在此我将重复我对以下Scepticalist的评论所讲的内容。这个问题是针对get-ChildItem循环中的ForEach。我的问题不涉及这样的循环。尽管如此,我还是在这里尝试了接受的答案,即使用-ErrorAction SilentlyContinue,并且仅隐藏错误,而不会捕获错误。但是,在我发现并准备发布作为答案的解决方案中,我确实将-ErrorAction SilentlyContinue-ErrorVariable结合使用。

powershell error-handling access
2个回答
0
投票

[好的,我对ErrorAction参数做了一些研究,然后发现了ErrorVariable参数。 (这两个都是common parameters,因此它们没有出现在get-ChildItem的文档中。)然后,我就可以弄清楚如何做到这一点。

我不会立即接受这个答案,但是会等待,看看有人是否有更好的解决方案。

新脚本:

$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.")
$aoFileSystem = @(get-ChildItem $sPath -recurse -force -ErrorAction SilentlyContinue -ErrorVariable aoChildItemError)

# This doesn't work right. It merges text from both errors together. Why?
#ForEach-object -InputObject $aoChildItemError `
#   {$oErrorRecord = $_
#    write-host ($oErrorRecord.CategoryInfo.reason + ": """ + $oErrorRecord.TargetObject + """")}

for ($nCount = 0; $nCount -lt $aoChildItemError.count; $nCount++)
   {$oErrorRecord = $aoChildItemError[$nCount]
    write-host ($oErrorRecord.CategoryInfo.reason + ": """ + $oErrorRecord.TargetObject + """")}

新输出:

PS C:\WINDOWS\system32> D:\<path>\ErrorTest_mod.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_mod.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_mod.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.
UnauthorizedAccessException: "C:\WINDOWS\system32\config\systemprofile\AppData\Local\Microsoft\Windows\INetCache\Content.IE5"
UnauthorizedAccessException: "C:\WINDOWS\system32\LogFiles\WMI\RtBackup"

PS C:\WINDOWS\system32>  

在评论我的问题时,@ AdminOfThings建议使用$error。我对此并不熟悉,但是在common parameters的文档中已经提到过,它说$error存储整个会话中的错误,但是ErrorVariable参数允许我从对cmdlet的特定调用中收集错误。因此,这样做可能更好。但是,与@AdminOfThings的评论一致,此解决方案不使用try-catch。

[如果有人可以解释为什么新脚本中注释掉的ForEach-object无效,并显示了解决方法,我可以接受该答案。


-1
投票

非常简单!您在第二个目录访问语句中指定了参数-ErrorAction Stop。将其切换到-ErrorAction继续,您会收到两个错误消息。

© www.soinside.com 2019 - 2024. All rights reserved.