1

I'm having a weird issue with error handling from within a module. When I copy my advanced function in the ISE editor and run it from there I don't see any errors reported. As this is the desired behavior. However, when I paste that same function in a module file (Toolbox.ActiveDirectory.psm1) and call it from there, it does fill up the variable $Error.

I don't really understand why it's reporting the errors from the function Get-ADTSProfileHC from within the module and not from within the script pane. As you can see I erase the last error in the Catch clause (thanks to the help of DanL in a previous question).

It seems like there's a difference between error handling from the console or from a module.

The function:

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
        }
    }
} 

}

The error:

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

1 Answer 1

4

I found the answer thanks to another post on StackOverflow from a Microsoft engineer. It appears that the $Error variable for modules needs to be changed in the Global scope.

In short, I had to change $Error.Remove($Error[0]) to:

$Global:Error.Remove($Global:Error[0])
$Global:Error.RemoveAt(0) # same but shorter
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.