来自模块的 PowerShell 错误处理

标签 powershell error-handling

我在模块内处理错误时遇到了一个奇怪的问题。当我在 ISE 编辑器中复制我的高级功能并从那里运行它时,我看不到任何错误报告。因为这是期望的行为。但是,当我将相同的函数粘贴到模块文件( Toolbox.ActiveDirectory.psm1 )中并从那里调用它时,它确实填充了变量 $Error .

我真的不明白为什么它会报告函数 Get-ADTSProfileHC 的错误从模块内而不是从脚本 Pane 内。如您所见,我删除了 Catch 中的最后一个错误。子句(感谢 DanL 在上一个问题中的帮助)。

控制台或模块的错误处理似乎有所不同。

功能:

Function Get-ADusersHC {
[CmdletBinding(SupportsShouldProcess=$True)]
Param(
     [Parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true,Position=0)]
     [String[]] $OU
)

Begin {
    Function Get-ADOUNameHC {
        $CanonicalName = $_.CanonicalName
        [System.Collections.ArrayList]$Pieces = $CanonicalName.split(“/”) 
        $Pieces.Remove($Pieces[-1])
        $OU = $Pieces -join '\'
        $OU -replace ($Pieces[0],$Pieces[0].ToUpper())
    }

    Function Get-ADManagerDisplayNameHC {
        $m = Get-ADObject -Identity $_.manager -Properties displayName,cn
        if($m.ObjectClass -eq "user") { $m.displayName } Else{ $m.cn }
    }

    Function Get-ADTSProfileHC {

        [CmdletBinding()]
        Param(
            [Parameter(Mandatory=$true,Position=0)]
            [String] $DistinguishedName,
            [parameter(Mandatory=$true,Position=1)]
            [ValidateNotNullOrEmpty()]
            [ValidateSet('UserProfile','AllowLogon','HomeDirectory','HomeDrive')]
            [String]$Property
        )

        Begin {
            $User = [ADSI]"LDAP://$DistinguishedName"
        }

        Process {
            Try {
                Switch ($Property) {
                    'AllowLogon'    {if ($($User.psbase.InvokeGet('allowLogon')) -eq '1'){$True}else{$False}}
                    'HomeDirectory' {$User.psbase.InvokeGet('TerminalServicesHomeDirectory')}
                    'HomeDrive'     {$User.psbase.InvokeGet('TerminalServicesHomeDrive')}
                    'UserProfile'   {$User.psbase.InvokeGet('TerminalServicesProfilePath')}
                }
            }
            Catch {
                # When we receive an error, it means the field has never been used before and is blank
                # this is due to an error in the AD (same problem with the Quest CmdLet), AllowLogon is 
                # always 'TRUE' but we don't set it because we can't read it sometimes so we write 'blanks'
                Write-Output $null
                $Error.Remove($Error[0])
            }
        }
    }
}

Process {    
    Foreach ($_ in $OU) {
        Write-Verbose "Function Get-HCADusersNoManager > OU: $_"
        Write-Verbose "Function Get-HCADusersNoManager > Manager field empty"
        Get-ADUser -SearchBase $_ -Filter 'SAMAccountName -eq "shenn"' -Properties * |
        #Get-ADUser -SearchBase $_ -Filter * -Properties * |
        Foreach {
            $Properties = ([Ordered] @{
                    "Creation date" = $_.whenCreated;
                    "Display name" = $_.displayName;
                    "CN name" = $_.name;
                    "Last name" = $_.sn;
                    "First name" = $_.givenName;
                    "Logon name" = $_.sAMAccountName;
                    "Manager" = if($_.manager){Get-ADManagerDisplayNameHC};
                    "Employee ID" = $_.EmployeeID;
                    "HeidelbergcCement Billing ID" = $_.extensionAttribute8
                    "Type of account" = $_.employeeType;
                    "OU" = Get-ADOUNameHC;
                    "Notes" = $_.info -replace "`n"," ";
                    "E-mail" = $_.EmailAddress;
                    "Logon script" = $_.scriptPath;
                    "TS User Profile" = Get-ADTSProfileHC $_.DistinguishedName 'UserProfile';
                    "TS Home directory" = Get-ADTSProfileHC $_.DistinguishedName 'HomeDirectory';
                    "TS Home drive" = Get-ADTSProfileHC $_.DistinguishedName 'HomeDrive';
                    "TS Allow logon" = Get-ADTSProfileHC $_.DistinguishedName 'AllowLogon'
                    })
            $Object = New-Object -TypeName PSObject -Property $Properties
            Write-Output $Object
        }
    }
} 

}

错误:
Exception calling "InvokeGet" with "1" argument(s): "The directory property cannot be foun
d in the cache.
"
At C:\Program Files\WindowsPowerShell\Modules\Toolbox.ActiveDirectory\Toolbox.ActiveDirect
ory.psm1:299 char:42
+                         'UserProfile'   {$User.psbase.InvokeGet('TerminalService ...
+                                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodTargetInvocation

最佳答案

感谢另一个 post,我找到了答案来自 Microsoft 工程师的 StackOverflow。看来 $Error模块的变量需要在 Global 中更改范围。

简而言之,我不得不改变 $Error.Remove($Error[0])到:

$Global:Error.Remove($Global:Error[0])

关于来自模块的 PowerShell 错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26336217/

相关文章:

powershell - 在 Windows 10 Powershell 中通过 F7 使命令历史弹出窗口工作

用于将 Hyper-V guest 状态保存到磁盘的 Powershell 命令

ruby-on-rails - 如何在 rails 开发环境中测试错误页面?

c# - 在对模型类应用Crud操作时,我在ASP.Net Mvc项目中出错

javascript - 如何获取img.onerror触发的原因?

powershell - 使用 PowerShell 创建计划的 Azure WebJob

powershell - 父PowerShell控制台似乎可以控制子PowerShell控制台I/O

reactjs - 在 React-Redux 应用程序中显示和管理错误消息的最佳实践

testing - 测试迫使Webapp抛出错误以揭示黑客攻击信息

PowerShell 新的自签名证书 ip 地址