How to use Try and Catch to export success and failure to a CSV output

HI there, This script takes user list input from csv file, collects user attributes in hashtable and pass in as argument in a foreach loop to create user objects. The output can be success where user is created, or failure where user is not created due to various error conditions. I am trying to add Try and Catch to export , success or failure to csv with simple success and faiure along wtih user ID
At this stage I cantch all failures, I also need success. May I get some help to how to improve try and catch to capture both success and failure?
Many thanks
Sa

#Connect-AzureAD -TenantId xxxxxxxxxxxxxxxx
#Testing Try and catch, takes user list from csv file and create AzureAD B2C consumer accounts.
Start-Transcript C:\data\Transcript1.txt -Append
$LogFile = "C:\data\Log.csv"
$users = @()
$Users = Import-Csv "C:\data\User-List.csv"
foreach ($User in $Users){
Try
{
# Instantiate a hashtable containing required transformed user details used to create their account.
        $Properties = @{
        AccountEnabled = $true
        UserPrincipalName = $($User.email).Replace("@","_")+"MyB2C-Tenant.onmicrosoft.com"
        DisplayName = $user.DisplayName
        GivenName = $user.GivenName 
        Surname =  $User.Surname 
        CreationType = 'LocalAccount' 
        TelephoneNumber = $User.TelephoneNumber
       # Mobile = $User.Mobile #remove this
        # Define user password profile; (Password, ForceChangePasswordNextLogin)
        PasswordProfile = [Microsoft.Open.AzureAD.Model.PasswordProfile]::New($user.Password,$True)
        # Define user SignInName; (Type, Value)
        SignInNames = [Microsoft.Open.AzureAD.Model.SignInName]::New('emailAddress',$User.email)
    }
# If user's 'TelephoneNumber' is blank, remove from properties hashtable.
    if ($User.TelephoneNumber -eq ""){
        $Properties.Remove('TelephoneNumber')
    }
<#  #Remove the comments from this block if you want the same logic to apply to blank mobile numbers.
    if ($User.Mobile -eq ""){
        $Properties.Remove('Mobile')
    } 
#>
       
# Create the new AzureAD user with the values from the $Properties hashtable.
    New-AzureADUser @Properties
 }
 #Catches only Failures to a csv file
 Catch
 {
   write-host "Failed! Error:$_"
        $user.UserPrincipalName
        ""| select @{name = "UserPrincipalName";exp = {$($user.UserPrinciPalName)}},@{name = "Result";exp = {"Failed"}} | Export-Csv $LogFile -Append -Encoding UTF8 -NoTypeInformation 
    }
    }
    Stop-Transcripttype or paste code here

Before we proceed … please take a look at your own post. Does it look ok to you?

Please edit your question and fix the formating of your code.

Thanks in advance.

Hi, Olaf. Thank you for pointing out. Yes, my question was not well presented. I have rephrased the question title and amended the description, I should have said hash table not array. Also formatted the code.
regards
Sa

Instead of exporting in the catch, simply track if it was successful or failed via the try/catch and output at the end. Also, the command needs to hit a terminating error in order for try/catch to work as expected. It sounds like it does already but to ensure it and all others generate terminating errors you can pass -ErrorAction Stop to the cmdlets individually or you can set $ErrorActionPreference = 'Stop' like I did in this example. I’ve made various other adjustments to your code, including the reverse logic on hash building. Only add if the property has a value vs adding and removing if it’s empty. The formatting of the code is awful and I really hope it was just due to copy paste, which you should definitely practice at. You left the “type or paste code here” text in the codeblock. :slight_smile:

Start-Transcript C:\data\Transcript1.txt -Append
$ErrorActionPreference = 'Stop'

$LogFile = "C:\data\Log.csv"

$Userlist = Import-Csv "C:\data\User-List.csv"

foreach ($User in $Userlist){

    Write-Host "Processing user '$($user.userprincipalname)'" -ForegroundColor Cyan

    # Instantiate a hashtable containing required transformed user details used to create their account.
    $Properties = @{
        AccountEnabled = $true
        UserPrincipalName = $($User.email).Replace("@","_")+"MyB2C-Tenant.onmicrosoft.com"
        DisplayName       = $user.DisplayName
        GivenName         = $user.GivenName 
        Surname           = $User.Surname 
        CreationType      = 'LocalAccount' 
        TelephoneNumber   = $User.TelephoneNumber
        PasswordProfile   = [Microsoft.Open.AzureAD.Model.PasswordProfile]::New($user.Password,$True)
        SignInNames       = [Microsoft.Open.AzureAD.Model.SignInName]::New('emailAddress',$User.email)
    }

    # If the current user has TelephoneNumber or Mobile set, add it to the property hashtable
    'TelephoneNumber', 'Mobile' | ForEach-Object {
        if ($User.$_ -ne ""){
            $Properties.Add($_)
        }
    }

    # Create the new AzureAD user with the values from the $Properties hashtable. Catch the success/fail output into variables
    $result,$color = try{
        $newuser = New-AzureADUser @Properties
        "Successful"
        "Green"
    }
    Catch{
        "Failed"
        "Yellow"
    }

    $user | Select-Object UserPrincipalName, @{name = "Result";exp = {$result}}

    Write-Host "Finished processing user '$($user.userprincipalname)' - Result: " -ForegroundColor Cyan -NoNewline
    Write-Host "$result" -ForegroundColor $color
}

Stop-Transcript
1 Like

HI krzydoug, Just there are born singers, there are born coders (:slight_smile: I am the one who struggle a lot with codes. But I will try to learn to format script better.
I am having error on this part.

 # If the current user has TelephoneNumber or Mobile set, add it to the property hashtable

  
  'TelephoneNumber','Mobile' | ForEach-Object {
  
      if ($User.$_ -ne ""){
  
         $Properties.Add($_)
            
        }

    }
The error is as below
ForEach-Object : Cannot find an overload for "Add" and the argument count: "1".
At line:46 char:33
+   'TelephoneNumber', 'Mobile' | ForEach-Object {
+                                 ~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [ForEach-Object], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest,Microsoft.PowerShell.Commands.ForEachObjectCommand

When I comment out this check, the script works fine. Lastly I ammended a line below to export failure and success to csv file whic was my core requiremen. So your Try and Catch working perfectly.
$user | Select-Object UserPrincipalName, @{name = “Result”;exp = {$result}} |Export-Csv C:\data\result.csv -Append -NoTypeInformation

My appology If I have messed up formating again. I am new to forum.
regards
Sa

This may help you …

I apologize, I totally screwed up the add. I blame lack of sleep. Here is a corrected version of this section.

    # If the current user has TelephoneNumber or Mobile set, add it to the property hashtable
    'TelephoneNumber', 'Mobile' | ForEach-Object {
        if ($User.$_ -ne ""){
            $Properties.Add($_, $User.$_)
        }
    }

Or you can also populate it directly without using add.

    # If the current user has TelephoneNumber or Mobile set, add it to the property hashtable
    'TelephoneNumber', 'Mobile' | ForEach-Object {
        if ($User.$_ -ne ""){
            $Properties[$_] = $User.$_
        }
    }

Hi @krzydoug … Great that worked like a charm. Many thanks for providing final piece of the puzzle and really appreciate your help.
Happy New year
Sa