Script Wars: The Farce Awakens (part II)


Summary: Yesterday, we met a newly graduated IT professional, Rey Skyworker, as she discussed the ways of "The Farce." It was during this discussion that her instructor, Ben Kerberosie, discovered she had a natural gift in understanding how to implement some good practices into writing her scripts.

Today, we sit quietly (I mean all of you in the back too, no chattering and tossing about popcorn!), as Rey is about to embark on her new job.

The position: on the help desk. The company: Contoso Holly Jolly Hat Company.

She is being introduced to her new co-worker on the help desk, Jeremy Tinnison.

-----------------

Jeremy shook her hand.  "Welcome to Contoso, Rey, I'm Jeremy but everybody around here just calls me Tin."

She looked up. "Ok Tin. Interesting environment you have here. So what do you do here mostly?"

Ben looked over. "Go ahead Tin, let her know of the challenges you're having. She's well versed in Windows PowerShell and should be able to help you past some of your automation challenges."

Tin was about to speak when a small vacuum with googly eyes bumped into Rey's feet.

"What th…," she looked down as it rapidly began to try vacuuming her shoelaces. The battle to regain control of her feet was more than amusing. The small, football shaped object rolled about as if in disgust.

"That," muttered Ben, "is one of the experiments from R&D. It is the 'Trash Bagger 7.5' or 'TB-7' for short. It roams the office trying to find garbage, gum wrappers or bits of LAN cables. It occasionally makes mistakes like you just saw. Sometimes we find it picks up the odd power cord and unplugs systems. They are working on Release 8, which should resolve these unexpected issues."

Rey looked down, smiling at the rolling, blinking nightmare. "Silly thing."

"So!" burst out Tin, "Let me tell you about one of our current challenges. We have a Windows PowerShell script that creates a user in our Azure Active Directory environment. Most of the process is manual still for Office 365 for licensing. Our short-term issue is that we need to find a way to trap for errors in the script."

He showed Rey the initial script they used to provision users in Azure Active Directory.

$First=Read-Host 'Enter First Name:'

$Last=Read-Host 'Enter Last Name:'

 

Connect-AzureAd

 

$DisplayName=$First+' '+$Last

$Mailnickname=$First+$Last

$UserPrincipalName=$First+$Last+'@contoso.com'

 

$TempPassword='BadPassword4U!'

$PasswordProfile = New-Object -TypeName Microsoft.Open.AzureAD.Model.PasswordProfile

$PasswordProfile.Password=$TempPassword

 

New-AzureADUser -DisplayName $DisplayName -GivenName $First `

-Surname $Last -AccountEnabled:$true -PasswordProfile $PasswordProfile `

-MailNickName $MailNickname -UserPrincipalName $UserPrincipalName

Ben stepped up. "Occasionally some of the new staff don't follow the instructions, and the script throws an error. We'd like to find a way to trap for the various errors in PowerShell. It may cause the script to stop, but we'd like to find a way to clean up or return codes back to calling scripts down the road."

Tin ran the script to demonstrate, by deliberately giving blank values for the first and last name.

Screenshot of PowerShell

"Rather than this appear," continued Tin, "we'd like to be able to trap for the individual types of errors in PowerShell whenever possible. Logging them should happen but we want to be able to action the script in certain scenarios."

"You can if you like," ventured Rey. "Access the $Error variable in PowerShell. It's not just a text array, it's actually an object which contains all the information on errors."

Rey stored away the value of the last error on the screen to view its properties.

$ErrorToSee=$Error[0]

"If we pipe this into Get-Member, we can see it has many properties, including one called 'Exception.'"

Screenshot of PowerShell

"The 'Exception' property contains the actual object with the exception value PowerShell caught. We can view it like this."

Screenshot of PowerShell

Tin's eyes lit up. "Oh! If I run that against Get-Member, will it expose more information?"

Tin piped the output to Get-Member to view the additional properties.

Screenshot of PowerShell

Rey looked at the output. "In this case, it's not a property we need but the method type that failed. We can use the GetType() method to pull this information out."

Screenshot of PowerShell

"From the screen, we can see the error type is 'ApiException' but we need the full name for it.  Fortunately, we can look for other members with 'Name' in their description."

Screenshot of PowerShell

Tin looked down at the results. "I'm guessing 'FullName' is just too obvious?"

Rey nodded. "Just add it on to the gettype() and you'll have your answer," as she typed quickly into the console.

Screenshot of PowerShell

"Now to use this, we just use a 'Try Catch' statement in PowerShell. This block of script's job is to literally 'Try it out' and put in errors to 'Catch for'. This allows us to write code to mitigate, report, or trap the errors."

Rey added a simple Try Catch statement around the existing block of code in the PowerShell script, using the identified error.

$First=Read-Host 'Enter First Name:'

$Last=Read-Host 'Enter Last Name:'

 

Connect-AzureAd

 

$DisplayName=$First+' '+$Last

$Mailnickname=$First+$Last

$UserPrincipalName=$First+$Last+'@contoso.com'

 

$TempPassword='BadPassword4U!'

$PasswordProfile = New-Object -TypeName Microsoft.Open.AzureAD.Model.PasswordProfile

$PasswordProfile.Password=$TempPassword

 

Try

     {

     New-AzureADUser -DisplayName $DisplayName -GivenName $First `

     -Surname $Last -AccountEnabled:$true -PasswordProfile $PasswordProfile `

     -MailNickName $MailNickname -UserPrincipalName $UserPrincipalName

     }

Catch [Microsoft.Open.AzureAD16.Client.ApiException]

     {

     Write-Output 'A blank name was supplied.   Restart the script.'

     }

}

 

When they re-ran the script with the names supplied as blank, the results were far nicer.

Screenshot of PowerShell

Tin looked up. "Oh! I can trap for additional errors as well?"

Rey noted, "Just add an additional Catch statement for each unique error condition. I used Write-Output as an example, but you can put in any PowerShell code to deal with the errors."

Tin was excited! "What else can we do with this script? I want to make all of this seamless for the staff!"

Stay tuned for tomorrow's episode of "Script Wars," as Rey touches on more ways to make the script stronger with "the Farce."

Sean Kearney, Premier Field Engineer

Enterprise Services Delivery, Secure Infrastructure

 

 

Comments (0)

Skip to main content