Summary: Rusty discovers the power of classes and enums in Windows Powershell 5.0.
Note This is Part 4 in a five-part series. To catch up, read:
- Rusty the Red-Eyed Scripter, Part 1
- Rusty the Red-Eyed Scripter, Part 2
- Rusty the Red-Eyed Scripter, Part 3
- Rusty the Red-Eyed Scripter, Part 4
When last we ran into our good friend Rusty, he had encountered the infamous Scripting Guy, Ed Wilson, and listened to his introduction about the ConvertFrom-String cmdlet. Now he was about to hear a session about classes. What could that possibly be about?
“For many of us, this will be a new concept—the ability to create classes and other types of new and more powerful custom objects in PowerShell.” Ed looked at Rusty, “How do you normally return an object in PowerShell?”
Rusty thought for a moment and was a bit embarrassed. “Well sir, I still am using PowerShell 1.0, so the only way I know is to define whatever I want in objects and use a Return statement, such as:”
Return $ValueA, $ValueB, $ValueC
Ed smiled, “Dude, here’s a cool trick for you then. If you’re using Windows 7 or higher, you can use the [PSCustomObject] type to return data in a single object. This was introduced in PowerShell 3.0”
Rusty was immediately interested because most of his client systems were running Windows 8.1, and they actually did have PowerShell 4.0 installed. He watched as the Scripting Guy provided an example.
“If I wanted to return the same three values, I can use [PSCustomObject] to produce a single object to parse on the other side, instead of using a confusing array, for example:”
$ValueA=”Isn’t”
$ValueB=”This”
$ValueC=”Cooler?”
[PSCustomObject]@{FirstOne=$ValueA;SecondOne=$ValueB;ThirdOne=$ValueC}
“This will give you a single object and you can tag the separate properties!”
Whoa! The speed of Rusty’s pen as he went to write that down was faster than Thomas had ever seen anybody move. Even Sean blinked!
“So you thought that was cool? Buckle down! It’s time to unleash classes. I’m going to show you an example that might be more familiar. How about a [PSCustomObject] that shows a First, Last, SamAccountName from a script generating users?”
Ed keyed in the example showing the format in Windows PowerShell 3.0:
[PSCustomObject]@{First=$FirstName;Last=$LastName;SAM=$SamAccountName;UPN=$UserPrincipalName}
“This works fine if everything is perfect. But we can define this same object as a class in PowerShell 5.” The Scripting Guy began to create simple class:
class ADUserAccountInfo
{
[string]$Sam
[string]$UPN
[string]$First
[string]$Last
}
“With this as the top of our script, we now have a new type accelerator called ADUserAccountInfo, which we can call up in this manner:”
$User=[ADUserAccountInfo]::new()
“Now we can set individual properties in the following manner:”
$User.First=’Joe’
$User.Last=’Bloe’
$User.Sam=’Joe.Bloe’
$User.UPN=’Joe.Bloe@Contoso.com’
“What this means to start with is that the code is a lot easier to read. But I can make classes do even cooler things. We can validate data like we did with PowerShell parameters. So this same class can be told to throw an error if you define something such as a first name with too little data.”
Rusty could see the strength in having a PowerShell object that was able to self-validate. He could already see using that in his scripts for creating users.
“In the following example, we have told the class in PowerShell that the First and Last names cannot be any shorter than 1 character. We have also told it the SamAccountName can never be longer than 20 characters.
class ADUserAccountInfo
{
[ValidateLength(1,20)]
[string]$SAM
[ValidateLength(1,50)]
[string]$UPN
[ValidateLength(1,1)]
[string]$First
[ValidateLength(1,1)]
[string]$Last
}
“Now when we create a user object, it can trap for errors without us having to write that in the script. In this example, I tried to fill in the first name with blank content:”
“As you can see,” he said gesturing to the large display, “without having to write any fancy error code, we can trap for those errors at the very minute data is going in.”
“OK,” Rusty piped up. “So If one of those was defined as something like a Date object, and I provided garbage, it would properly freak on whomever put in the information?”
Ed bobbled his head up and down in agreement, “You got it! Now who here wants to see me create an enum?”
Only a few hands went up since there were only a few developers in the room. There were chuckles here and there. “So for those of you who don’t write in C# on a daily basis, I’ll provide a quick overview of what an enum is. Developers are used to this. A quick description would be to say it’s a list.”
Ed pulled up an example of a simple enum on his display:
enum InternalDomain
{
Fabrikam = 1
ScriptingGuys = 2
Contoso = 3
}
“This is also useful in error trapping. As a simple example, here is a very basic function to create a new user. I’m going to use this enum to trap for a valid list of values.”
function Build-ADAccount ($First, $Last, $Initial, [InternalDomain]$Domain)
{
“I’ll then run the same function with some values, including one that is not valid. Watch as the enum helps flag the error.”
Build-AdAccount -first 'Joe' -last 'Bloe' -initial 'P' -Domain 'Fake'
“Now how cool is that?” Ed was beaming.
Rusty was definitely trying to wrap his head around some of the complexity of classes and enums, but he could certainly appreciate the raw power this would add to scripts and modules!
The night wrapped up. Ed waved goodbye and thanked everyone for coming to PowerShell Saturday.
Afterwards, Rusty found himself sitting at a table in the little coffee shop next door with Ed, Sean, and Thomas.
“So, Rusty,” Thomas jabbed him in the side, “What about PowerShell 5 blew you out the door?”
Rusty began talking so fast that only Sean understood him, “So much, so many. I need to get this tomorrow! The amount of time I’m going to save! I can finally get home at a decent hour! ConvertFrom-String! Classes! Enums! PSReadline!”
Poor Rusty’s eyes were a buzzing. He couldn’t wait to start using Windows PowerShell 5.0.
Ed looked at Rusty, “So dude, Rusty with your eyes so red…I’ll bet soon be able to go to bed?”
Rusty laughed. Bad pun or not, it was true. He would finally be able to rest properly and actually enjoy his holidays!
Thank you everybody for enjoying our little story and learning about some features in Windows PowerShell 5.0.
From the Scripting Guys to you, have a Happy Holiday to you and yours! And now for an added holiday bonus, enjoy this song I put together for the sixth Scripting Guys Holiday Special:
The Annual Scripting Guys UltraCheezy Holiday Tune!
I invite you to follow the Scripting Guys on Twitter and Facebook. If you have any questions, send email to them at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, always remember that with great PowerShell comes great responsibility.
Sean Kearney, Honorary Scripting Guy, Cloud and Datacenter Management MVP