Why Didn’t You Tell Me That Isn’t a Valid Property?


 

As you might expect, writing for the Lync Server PowerShell blog is perhaps the most exciting and glamorous job  on the face of the planet: millions of people would literally give their right arm for the opportunity to trade jobs with us.

 

Note. Well, OK, so maybe they wouldn't literally give their right arm for the opportunity to trade jobs with us. In fact, most people would literally give their right arms if they didn't have to change jobs with us. But either way, our point remains the same.

 

Whatever that point might happen to be.

 

Despite all the glamour and all the excitement, however, there is at least one drawback to spending most of your time writing about Lync Server PowerShell: while you end up knowing a little bit about Lync Server and a little bit about Windows PowerShell, you definitely don't learn everything there is to know about either technology.

 

You say you'd like to see an example of that? Well, to be honest, we weren't expecting that question; for some reason, people never seem to need any proof that we don't have any idea what we're doing. But sure, we can give you an example. And here it is.

 

As we noted, writing for the Lync Server PowerShell blog has at least one drawback. As it turns out, Windows PowerShell also has at least one drawback: sometimes PowerShell is just too darn forgiving of your mistakes.

 

What do we mean by that? Here's a classic example. Suppose we use the Get-CsAdUser cmdlet to retrieve information about the user Ken Myer, and then store that information in a variable named $x:

 

$x = Get-CsAdUser "Ken Myer"

 

Let's further suppose that we want to use standard dot notation to view selected account information for Ken Myer. Here's what our screen looks like (including the Windows PowerShell prompt) when we ask to see Ken's department:

 

PS:> $x.Department

Finance

PS:>

 

So what's wrong with that? Nothing. Obviously Ken is a member of the Finance department.

 

Now let's take a peek at his pager number:

 

PS:> $x.Pager

 

PS:>

 

As you can see, nothing came back. Why not? That's easy: because Ken doesn't have a pager.

 

Note. Good question: does anyone have a pager these days? Interestingly enough, they do. Pagers are still used in hospitals and other places where cell phone reception can be spotty, or where cell phone use is frowned upon. (Often for fear that the cell phones will interfere with other equipment used in the building.)

 

And, of course, restaurants still use pagers: in the US, at least, it's not uncommon to walk into a restaurant, be told that there will be a 10-to-15 minute wait for a table, then be handed a pager the size of a garbage can lid. The idea is that you can then go off and do something else until the garbage can lid rings and lets you know that your table is ready. The reality, of course, is that there isn't a whole heck of a lot that you can do while carrying a garbage can lid, so you just hang around in the foyer anyway, just like you would have done had they never given you a pager in the first place.

 

At any rate, we now know that Ken doesn't have a pager number. Let's check his phone number:

 

PS C:> $x.Pohne

PS:>

 

Interesting; apparently Ken doesn't have a phone number, either. Oh, well, that probably means that – say, wait a second here. If you look closely at the preceding output, you'll notice something: we misspelled the word Phone. We didn't ask to see Ken's Phone number; we asked to see his Pohne number. It's no surprise that he doesn't have a Pohne number; even hospitals and restaurants don't have Pohnes!

 

Like we said, it's no surprise that Ken doesn't have a Pohne number. What is surprising is that Windows PowerShell didn't tell us that Pohne is not a valid property of the user object returned by Get-CsAdUser. There are plenty of times when PowerShell is quick to jump in and point out that you made a mistake. Why doesn't it do so when you specify an invalid property?

 

Note. Incidentally, you get the same behavior if you specify an invalid property when using Where-Object:

 

Get-CsAdUser | Where-Object {$_.Departmetn –eq "Finance"}

 

If you run the preceding command, PowerShell won't bother to tell you that there's no such property as Departmetn. Instead, it just won't bother to return any data. At that point, you don't know if you failed to get back information because there isn't any information to get back, or because you made a mistake when calling Where-Object.

 

To be honest, we don't know why PowerShell doesn't tell you that you referred to an invalid property; it just doesn't. And, up until very recently, we would have told you exactly what you could do about that situation: absolutely nothing. And then, we saw the light ….

 

Well, actually, we inadvertently saw a reference to the Set-StrictMode cmdlet, a cmdlet we had never heard of. Upon doing a little investigation, we suddenly realized that we had had the solution to this problem all along.

 

Note. Just like Dorothy in The Wizard of Oz? Yes, exactly like Dorothy in The Wizard of Oz.

 

Well, assuming Dorothy needed to run a Windows PowerShell cmdlet in order to get back to Kansas. If she did, then yes, exactly like Dorothy in The Wizard of Oz.

 

As it turns out, the Set-StrictMode cmdlet has actually been around for a while; it was introduced in Windows PowerShell 2.0 According to the documentation, this cmdlet:

 

" … configures strict mode for the current scope (and all child scopes) and turns it on and off. When strict mode is on, Windows PowerShell generates a terminating error when the content of an expression, script, or script block violates basic best-practice coding rules."

 

That's nice (we suppose), but seeing as how pretty much everything we do here at the Lync Server PowerShell blog violates best-practice coding rules, well, we didn't see much use for Set-StrictMode.

 

But guess what? In yet another stunning surprise, we were wrong: Set-StrictMode can be incredibly useful to us, and to you. How? Let's show you how.

 

To begin with, let's change the strict mode settings for our current instance of Windows PowerShell. (Don't worry; we'll explain what that means in a second.) Here's a command that will do just that:

 

Set-StrictMode –Version "Latest"

 

Now let's check again to see if Ken has a Pohne number:

 

PS C:> $x.Pohne

Property 'Pohne' cannot be found on this object. Make sure that it exists.

 

Well, what do you know: PowerShell told us that we were referencing an invalid property! Let's try that same non-existent property with Where-Object and see what happens:

 

Get-CsAdUser | Where-Object {$_.Departmetn –eq "Finance"}

Property 'Departmetn' cannot be found on this object. Make sure that it exists.

 

Sacre bleu! The system works!

 

As it turns out, strict mode does pretty much what the name implies: it specifies how strict PowerShell is going to be about sloppy coding or poor typing. For example, suppose we've never used the variable $x before, and we now type the following at the Windows PowerShell prompt and then press ENTER:

 

$x

 

By default, PowerShell won't do anything. But if we've turned on strict mode, we'll get an error message like this one:

 

The variable '$x' cannot be retrieved because it has not been set.

 

See what that means? Under strict mode, not only do you get an error if you reference an invalid property, but you'll also get an error if you reference a variable that has never had a value assigned to it.

 

That, by the way, is an example of good coding practices.

 

The sharp-eyed among you might have noticed that, when we called the Set-StrictMode cmdlet, we set the Version parameter to Latest:

 

Set-StrictMode –Version "Latest"

 

What's that all about? Well, the Version parameter specifies just how strict strict mode will be. If you set the Version to 1.0 strict mode will generate an error if you use an uninitialized variable; that's pretty much it. If you set the Version to 2.0, however, the following conditions will generate an error:

 

·         References to uninitialized variables (including uninitialized variables in strings).

·         References to non-existent properties of an object. (Hey! That's ours!)

·         Function calls that use the syntax for calling methods.

·         A variable without a name (for example, ${}).

 

And, at the moment, setting strict mode to Latest is the same thing as setting it to 2.0; that's because 2.0 is the latest. But because that will change one of these days, setting strict mode to Latest is probably the safer bet.

 

Note. Or, more properly, the better coding practice.

 

And what if you decide that you don't like strict mode? That's fine; just turn it off:

 

Set-StrictMode –off

 

One thing to keep in mind here: when you change the strict mode, that change only lasts until you close that particular instance of Windows PowerShell. The next time you start PowerShell the application will revert to its default behavior and it will not let you know that you referenced an invalid property. If you'd like to run in strict mode every time you start Windows PowerShell, your best bet would be to add the appropriated command (e.g., Set-StrictMode –Version "Latest") to your Windows PowerShell profile.

 

Note. Would that be a good coding practice? Well, you're definitely asking the wrong people that. But it sounds like a good thing to do, doesn't it?

 

So there you have it: a way to get PowerShell to stop ignoring mistakes and to start letting you know that you've referenced an invalid property. Considering the fact that Windows PowerShell 2.0 was released a couple of years a

Comments (1)
  1. Enigma says:

    That’s great and all…and thanks for pointing out that referencing properties that don’t exist is "bad coding". But you never actually mentioned how you would code around that. For example, IF($x.UniqueProperty){} …PS evaluates the value of the property
    before returning TRUE/FALSE on the existence of the property. What would be the equivalence of IF EXISTS($x.UniqueProperty) ?

Comments are closed.

Skip to main content