Try/Catch block works in ISE but not PowerShell Console

This topic contains 15 replies, has 4 voices, and was last updated by Profile photo of Dan Potter Dan Potter 2 months, 3 weeks ago.

Viewing 15 posts - 1 through 15 (of 16 total)
  • Author
    Posts
  • #46136
    Profile photo of Robbie Courtney
    Robbie Courtney
    Participant

    I've been having the following problem. When I try to run the code below and an error occurs in the Try Block the Catch block is not ran when I run it from the PowerShell Console, It does however work when i run it from the ISE.

    The example below should throw an error if the user accounts already exist in AD. When I run in the PS Console it does display errors but keeps running without showing the Write-Warning inside the catch block. It runs perfectly as expected in the ISE

    OS is Win7 64 bit, PSv4

    $userList = Import-Csv 'C:\SomePath\ImportUserAccounts.csv'
    $AccountPassword = (ConvertTo-SecureString "SomePassword" -AsPlainText -Force)
    $OUpath = "OU=Users,OU=Test,DC=Example,DC=Local"
    
    foreach($u in $userList)
    {
        
        try
        {
            $ErrorActionPreference = "Stop"                                  
           New-ADUser  -Name $u.name `
                       -DisplayName $u.DisplayName `
                       -SamAccountName $u.SamAccountName `
                       -UserPrincipalName $u.UPN `
                       -Description $u.Description `
                       -AccountPassword $AccountPassword `
                       -Enabled $TRUE `
                       -Path $OUpath       
        }
        catch
        {
            Write-Warning "An error has occured, check the error log for errors"
           
        } 
        finally {
            $ErrorActionPreference = "Continue"
        }             
    
    }
    
    #46145
    Profile photo of Don Jones
    Don Jones
    Keymaster

    Setting $ErrorActionPreference is kind of a poor practice – have you tried setting -ErrorAction directly on the cmdlet? That's the intended approach in the shell.

    But regardless, it's a bit odd that it works one way in the ISE and another way in the console. Could you paste an example of one error that is displayed in the console, when it's not running as desired?

    #46147
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    I'm not sure why it's not working in ISE, but here are a couple of tips. First, rather than setting the global settings for ErrorAction and then setting it back to Continue, you should just set the error action on the command itself. Next, for prettier formatting without the continuation character, you should use splatting to format your parameters. Take a look at this:

    $userList = Import-Csv 'C:\SomePath\ImportUserAccounts.csv'
    $AccountPassword = (ConvertTo-SecureString "SomePassword" -AsPlainText -Force)
    $OUpath = "OU=Users,OU=Test,DC=Example,DC=Local"
    
    foreach($u in $userList){
        try {                      
            $newUsrParams = @{
                Name              = $u.Name;
                DisplayName       = $u.DisplayName;
                SamAccountName    = $u.SamAccountName
                UserPrincipalName = $u.UPN
                Description       = $u.Description
                AccountPassword   = $AccountPassword
                Enabled           = $true
                Path              = $OUPath
                ErrorAction       = $true
            }
    
            New-ADUser @newUsrParams
        }
        catch {
            Write-Warning "An error has occured, check the error log for errors"
        }      
    }
    
    #46153
    Profile photo of Robbie Courtney
    Robbie Courtney
    Participant

    Ok I think I have the problem narrowed down. Part of the script i didn't show was at the beginning of the script it loads the ActiveDirectory module using implicit remoting. The computer I was testing on also has the RSAT tools installed. The ISE was using the RSAT ActiveDirectory module for the New-Aduser Cmdlet found out by running "Get-Command New-Aduser", and the PowerShell Console was running the Implicit remoting ActiveDirectory module. I need to fix the script to use Prefix for implicit remoting... (this is an old script I had wrote when I was just beginning).

    So besides the cmdlet naming clash issue which I need to fix. What would cause the Implicit remoting version to not executing the catch block? but the one using the RSAT module to work correctly?

    @Don: thanks for the tip, using -ErrorAction is what I originally had, but i changed to using the $erroractionpreference in testing when I was running in to the issues to see if that was the issue.

    @Rob: Thanks for the advise. (Some scripts I've used Splatting some I've used the back tick... The great debate splatting vs back tick 🙂 )

    #46157
    Profile photo of Robbie Courtney
    Robbie Courtney
    Participant

    I'm going to close this out and open a new post since I have narrowed down the issue. The problem is try/Catch not working with the active directory module imported via implicit remoting.

    #46223
    Profile photo of Don Jones
    Don Jones
    Keymaster

    That's expected. When the error occurs remotely, it has to be handled remotely. Instead of implicit remoting, you probably need to send the entire script as a script block to be executed remotely, or at least the entire Try/Catch chunk.

    #46278
    Profile photo of Robbie Courtney
    Robbie Courtney
    Participant

    I found a workaround to get it to work. By using the global error action preference variable and changing it to stop it works. Of course changing it back to continue right after the try catch block

    $Global:ErrorActionPreference = "Stop"
    
    #46287
    Profile photo of Dan Potter
    Dan Potter
    Participant

    Advantage of splatting you have the functionality to change one of the parameters on the fly without editing full command.

    If you had certain conditions like place a user into a different ou based on another department you could change it and change it back without much effort.

    $newusrparams.samaccountname = 'somethingelse'
    $newusrparams

    and it looks pretty.

    • This reply was modified 2 months, 3 weeks ago by Profile photo of Dan Potter Dan Potter.
    #46306
    Profile photo of Robbie Courtney
    Robbie Courtney
    Participant

    Not trying to start a debate and I do appreciate everyones input. I know the community at large has decided that splatting is the way to go, but there are advantages and disadvantages to both, and it is someones preference. The reason that lately I tend to use back ticks more now is that for one I think using backticks looks much better then using splatting (I know this is subjective). Number two it also has autocompletion when typing parameters. When using splatting i'm much more likely to have a typo causing an error due to a misspelled parameter. I've read and seen many debates on the topic and know of the disadvantages such as having a space after the backtick, but bottom line it is someones preference. If you look at a lot of Microsoft's code they use backticks probably more often then splatting. I don't know if Dave still has the view but this is a post on the subject that he made awhile back. https://davewyatt.wordpress.com/2014/12/11/long-powershell-commands-backticks-gasp/

    I think this

    $newUsrParams = @{
                Name              = $u.Name;
                DisplayName       = $u.DisplayName;
                SamAccountName    = $u.SamAccountName
                UserPrincipalName = $u.UPN
                Description       = $u.Description
                AccountPassword   = $AccountPassword
                Enabled           = $true
                Path              = $OUPath
            }
    
            New-ADUser @newUsrParams
    

    Does not look as good as this

    New-ADUser  -Name $u.name `
                -DisplayName $u.DisplayName `
                -SamAccountName $u.SamAccountName `
                -UserPrincipalName $u.UPN `
                -Description $u.Description `
                -AccountPassword $AccountPassword `
                -Enabled $TRUE `
                -Path $OUpath  
    
    #46316
    Profile photo of Dan Potter
    Dan Potter
    Participant

    I look at a lot of microsoft's code and shake my head =D

    #46328
    Profile photo of Robbie Courtney
    Robbie Courtney
    Participant

    @Dan Potter haha touche

    #46344
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    I usually tab complete all params and then copy and paste them into the splat. I also like that I can dynamically add\remove parameters to\from the hashtable when I build functions. Personally, I think the backticks are tough to see and there is no functional benefit, only "makin' it perty". 🙂

    #46354
    Profile photo of Dan Potter
    Dan Potter
    Participant

    True! Comes in real handy when you're running similar commands. I use it extensively with new dns server cmdlet's where you have to specify the type of dnsrecord to add A or AAAA. We can quickly provide the right switch without duplicating the command.

    #46356
    Profile photo of Robbie Courtney
    Robbie Courtney
    Participant

    @Rob Simmers I guess I can see that, but I can add/remove parameters directly from the function that i'm building out, and its all together in one place. And copying and pasting, and then removing all of the "-" in front of the parameter names and then adding "=" before the arguments seems like extra work without much benefit to me. Maybe I just haven't been bitten by the downsides to using the backtick but I haven't been convinced that splatting is better then using the backtick

    #46358
    Profile photo of Robbie Courtney
    Robbie Courtney
    Participant

    @ Dan Potter Ok I can see the benefit in that, I just haven't had a use case for that yet. In those circumstances I would use splatting, but for everything else... i would probably use backticks. I guess if I consistently ran into those situations, I would probably use splatting for consistency sake.

Viewing 15 posts - 1 through 15 (of 16 total)

You must be logged in to reply to this topic.