How’s your Windows Server 2003 migration going? Does that question scare you?

Remember 2003? 2003 was a good year. Camera phones got popular, XBox took off, and I was a 14 year old in 9th grade. 2003 was also, obviously, the year that Microsoft released Windows Server 2003. Are you still running it? You shouldn’t be, but I bet lots of you are. That should scare you because in less than six weeks from the time of this post, on July 14, 2015, Microsoft is ending support for Windows Server 2003. If you’re not done your Windows Server 2003 migration to newer operating systems (Windows Server 2012 R2 is an excellent choice), or worse – not even started, you could face some very serious consequences. Let’s answer a few questions you might have about that.

What does it mean to be unsupported?

In case “end of support” isn’t clear, here’s some of the highlights from the long list of concerns outlined in this IDC white paper on why you should upgrade (pdf). There’s tons of reasons but these were the ones that resonated with me.

  • Elimination of security fixes.

Holy smokes. No more patches? For a second that almost sounds like a good thing, right? You’re probably tired of patching servers. But, think of the consequences and implications of that. No more patches is a terrible, scary, awful thing. If I need to tell you why, you may consider a different career than the one that brought you to my blog. If you ever want to pass another audit, you better be receiving and applying security fixes for all your products, especially ones as fundamental as your Windows OSes.

  • Lack of support.

Do you ever call Premier Support? Read Technet blogs or forums? Microsoft is shutting down support for Windows Server 2003 once it hits end of life. If you want help upgrading, you better get it now because after the end of life date, it might be a challenge to get.

Saying “I can put this off, I’m just going to buy extended support!” is the wrong attitude to have. First, you could buy an Egyptian pyramid for the amount of money that extended support is going to cost. Second, all you’re doing is delaying the inevitable. You have to do this. Do it now. It’s going to hurt more to put it off and do it later.

Okay, so there are some good reasons to get off Windows Server 2003 BUT are there any good reasons to get on Windows Server 2012 R2?

There’s tons. Windows Server 2012 R2 came out Q4 2013 and is the result of decades of learning, improvement, technological landscape shifting, development and a bunch of other buzz-verbs that all mean that it’s better. It’s better. Windows Server 2012 R2 is better than Windows Server 2003. Here’s just a few articles that support that statement.

If you look at all, you’ll find thousands more articles, slides, posts, tweets, talks and more on the benefits and features of Windows Server 2012 R2 over its predecessors.

Upgrading is so intimidating. I need help! Where can I get some?

Microsoft has your back on upgrading and migrating. There are lots of guides and articles on these topics but Microsoft has assembled, in my opinion, the best resource hub out there. Did you click that link? It takes you to the page with all the resources. Click one of these links to go to that page. I can’t overstate how important I think it is that you go to this page and read about the resources to help you migrate away from Windows Server 2003. All the links in this paragraph go to the same page. This is the page: https://www.microsoft.com/en-ca/server-cloud/products/windows-server-2003/default.aspx . It’s in your very best interest to go there and check out what’s there. Need the link one more time? Here.

Does it feel like I’m using this subsection of this post to direct you to Microsoft’s page with tons of resources you can use to make your migration possible, if not easy? It’s because I am. There’s tons of other resources out there, too, and they are a simple search away.

I get it. I want to upgrade. I’ve been pushing my organization to upgrade but I can’t seem to get permission. What can I do?

Surely I’ve convinced you of the many great reasons to migrate away from Windows Server 2003 to Windows Server 2012 R2. These arguments make sense for an IT Pro but maybe not for an executive, business people, or sometimes even to a developer. Here are a few of the common ways I see resistance and my suggestions to overcoming them. Of course, every organization’s politics are different and you may need to figure it out yourself.

  • We have App XYZ that only runs on Windows Server 2003. It’s crucial to our business. There’s no new version.

Respectfully, if this is the honest to goodness truth for your organization, you might be on the Blockbuster/Kodak path of sustainability. Read this Wikipedia article on the theory of Diffusion of Innovations. Take special note of chart that describes the different stages: Innovators, Early Adopters, Early Majority, Late Majority, and Laggards. You don’t have to adopt every new innovation that comes across your desk, but if your entire business is dependent on a technology or product that is about to reach end of life, you’re in trouble. You’re already in the laggard stage of the adoption process if you’re still not off Windows Server 2003. Just don’t fall off the chart completely – get migrating!

There comes a point where you’re not upgrading to gain an advantage, but to catch up to competitors who have already surpassed you.

  • App XYZ is crucial to our business. There’s a new version but we can’t afford the down time to upgrade.

This one is easier to work with than the last one. Attack this resistance from two sides. First, reiterate the importance of upgrading and all the bad things that will happen if you don’t. Second, and most importantly, find business reasons that make migrating to Windows Server 2012 R2 or the new version of App XYZ desirable to your specific stakeholders. Often with executives and business groups, it’s even more important to PULL them towards something new as it is to PUSH them away from something old.

To address the downtime concerns, put effort into making a plan that makes the downtime as short and painless as possible. Do a side-by-side migration. Do the cut over at 3 in the morning when your customers are all asleep. Find a way to make the downtime as tolerable as possible.

  • We don’t need new features. We accept the risk of running in an unsupported fashion. It’s just not worth our time to migrate.

This is a naive attitude, in my opinion. If you can’t find a creative way to improve anything within your organization with even one new feature in Windows Server 2012 R2, you’re not looking. A willingness to accept the risk of running unsupported demonstrates a lack of complete understanding of the risk involved with doing so. What would your customers say if you told them that your systems don’t receive security updates any more? If you get resistance like this, you need to find a reason to pull your stakeholders towards the newer technologies and make sure they’re clear on the risks of maintaining status quo.

Alright, I’m ready to take this on! Now how about a summary of some kind?

Glad you asked. If you take anything out of this post, make it these few things.

  1. Being unsupported is bad. Really bad. You don’t want to be unsupported for a lot of reasons including no more security patches.
  2. Windows Server 2012 R2 has a ton of new features that make it a great OS to migrate to.
  3. Microsoft has a lot of resources available to help you upgrade.
  4. Getting stakeholder permission for an upgrade is as much about selling the benefits of moving to a new system as much as it is about the disadvantages of staying on the old one.

Good luck and happy migrating!


Quick Tip: Find All The Mail Enabled Groups A User Is A Member Of

Here’s a one-liner that will help you find all the mail enabled groups that a user is a member of. A little pre-requisite reading is this bit on group types to understand the difference between a security group and a distribution group: https://technet.microsoft.com/en-us/library/cc781446%28WS.10%29.aspx?f=255&MSPPError=-2147217396

Here’s the one-liner!

It might not be the epitome of efficiency but it works and served me well when I needed it to.

First, we’re running a Get-ADUser command on our interesting user and making sure to retrieve the MemberOf property in addition to the standard properties returned. Out of all of the returned properties, it turns out that MemberOf is the only one I’m interested in so I select only that property by wrapping the command in brackets and appending .MemberOf. Second, I’m piping all of the groups that the user is a member of into a foreach-object loop. For each of the objects returned, I’m performing a Get-ADGroup. I have to do this because I can’t necessarily tell which groups the user is a member of are mail enabled just from their name, I have to run the Get-ADGroup command to get more information. I’m piping these results into a where-object command where I select only the groups whose GroupCategory is equal to “Distribution” (see the pre-requisite reading above). Then I format the group names into a table.

I could have got every group in my Active Directory and searched for groups that contained my user as a member and were Distribution types, but in my situation, it was faster to only spot check the groups that the user was actually a member of. I have a lot of groups, you might not.


New Stuff: Get-Clipboard And Set-Clipboard – New In PowerShell 5.0

Predictably, there are lots of new cmdlets coming in PowerShell/Windows Management Framework 5.0. Two of them that just came out in build 10105 are the Get-Clipboard and Set-Clipboard cmdlets. The help docs aren’t all written at the time I’m writing this post but I wanted to introduce them and highlight a couple neat use cases I immediately thought of.

New Get-Clipboard and Set-Clipboard cmdlets

New Get-Clipboard and Set-Clipboard cmdlets (click for larger)

Back in the old days of PowerShell 4.0, you had to pipe output to clip.exe or use the PowerShell Community Extensions to interact with your clipboard. Not anymore!

Looking at the Get-Clipboard syntax, it’s quickly apparent that you can do more than just get the clipboard’s text content but let’s start with that anyway. So, what if I go and select some text, right click and copy it. What can I do with the Get-Clipboard cmdlet?

Not exactly mind blowing. Similarly, you can use the Set-Clipboard cmdlet to put text on the clipboard.

I’m probably not blowing your mind with this one either. Where this gets fun is when you consider the possibilities the using the -Format parameter. I can put more than just text on my clipboard, right? Let’s see what I get when I copy three files in my c:\temp directory to my clipboard. If I try to just use Get-Clipboard without any additional parameters or info like I did in the above examples, I won’t get anything returned, but what I can do is this.

Now we’re doing cool things. And what kind of objects are these?

FileInfo! We can do all the same things with this array of files that we would do to the results of a Get-ChildItem command. This means we can go the other way too and use the Set-Clipboard cmdlet to put a bunch of files onto the clipboard.

Note with all of the above examples, you can use the -Append parameter to simply add on to whatever is already on the clipboard.

I won’t cover the other formats (Image and Audio) or the text format types because you need something to discover for yourself. The last thing I’ll point out is that you can easily clear the clipboard, too.

I’m not going to cover every new cmdlet that comes out with PowerShell 5.0 but this one is very accessible and I think I’ll be able to use it all over the place.


Quick Tip: Search Remote Computer Certificate Store

It’s really easy to search your local certificate store using PowerShell. You simply run a command like this.

The above command will recursively look through all the certs in the local machine store and return the ones that have the word “Interesting” in the subject. Not exactly re-inventing the wheel here.

There’s not a ton of great options for snooping through the certificate store of remote computers, though. The solution I chose to get around this is dead simple. I used the Invoke-Command cmdlet to scan the certificate store of a remote computer. It’s so easy that it almost feels like cheating.



Invitation: MVP Virtual Conference

This is a canned post provided by the Microsoft MVP program. I’m sharing it because I think it’s going to be a valuable event that readers of this blog could get a lot out of. I’m definitely going to be there and I’m really looking forward to it. Take a look and see if it’s something you’re interested in.



Register to attend the Microsoft MVP Virtual Conference

I wanted to let you know about a great free event that Microsoft and the MVPs are putting on, May 14th & 15th.  Join Microsoft MVPs from the Americas’ region as they share their knowledge and real-world expertise during a free event, the MVP Virtual Conference.

The MVP Virtual Conference will showcase 95 sessions of content for IT Pros, Developers and Consumer experts designed to help you navigate life in a mobile-first, cloud-first world.  Microsoft’s Corporate Vice President of Developer Platform, Steve Guggenheimer, will be on hand to deliver the opening Key Note Address.

Why attend MVP V-Conf?  The conference will have 5 tracks, IT Pro English, Dev English, Consumer English, Portuguese mixed sessions & Spanish mixed sessions, there is something for everyone!  Learn from the best and brightest MVPs in the tech world today and develop some great skills!

Be sure to register quickly to hold your spot and tell your friends & colleagues.

The conference will be widely covered on social media, you can join the conversation by following @MVPAward and using the hashtag #MVPvConf.

Register now and feel the power of community!



Quick Tip: Protect Your Active Directory From Finger Slips

Do you ever worry about giving Domain Admin or other Active Directory privileges to people? I do, so I decided to protect some sensitive items in my AD from accidental deletion – or as I like to call it, protecting against finger slips.

3-16-2015 10-47-03 AM

We’re talking about this flag.

I’ve got some OUs that have user and group objects that I would really miss if they were to be accidentally deleted. Furthermore, I would really miss any entire OU if it were to be deleted. I’m not interested in protecting individual computer accounts or user/group accounts in non-sensitive OUs.

Here’s the script I used:

Line 1 defines an array of names of my sensitive OUs. Lines 2 and 3 are basically the same: they get all the AD objects in the sensitive OUs with an ObjectClass of group or user and protect them from accidental deletion. Why do this in two lines? I was getting inconsistent results (computer and other objects were returned) when I tried combining the filter. My AD isn’t that big so this works just fine for me. Line 4 protects all my OUs in my AD from accidental deletion.


Quick Tip: String Manipulation – First Name Last Name to Last Name, First Name

I’ve got kind of a silly post this week. I often get a list of names in the format…

John Doe

Jane Doe

Mike Smith

Mary Smith

… that I actually need to be in the format…

Doe, John; Doe, Jane; Smith, Mike; Smith, Mary

… and sometimes, especially with long lists of names, it’s a pain to do the manipulation in Notepad or Word. So what do you think I did? That’s right, I wrote a PowerShell script to handle it for me. I just throw the list of people into a text file and call up this script.

This isn’t the tidiest script but I break it up into a couple extra parts so it’s easier to edit on the fly. I might comment out the ” | clip.exe ” part of the last line if I don’t want the output on my clipboard.

The first line just gets the content of the text file and the second line initializes the variable $csnames (which stands for [semi]colon separated names). On the third line, I go through every value in the text file and put the part after the first space (the last name), a comma and space, and then the part before the first space (the first name) into the $csnames string. I throw a semicolon on and move to the next one.

This won’t do well with names like “John van Doe” that have multiple spaces. It just happens to suit my needs and might serve as a super simple example to some of you who are trying to wrap your heads around manipulating strings in PowerShell.


Imported PowerShell Sessions ErrorActionPreference Gotcha

I just bumped into something silly that I know I’ll forget about in the future. Using the function in my PowerShell profile to open an Exchange Management shell, I ran the following command as part of a script.

It’s a pretty self-explanatory command. I was trying to detect if a mailbox, in this case “doesntexist”, existed or not. Typically if the mailbox doesn’t exist, the Get-Recipient cmdlet will throw an error. My goal was to catch the error and do something productive with it but the above command doesn’t trigger the Catch block.

No problem, I thought to myself. My ErrorActionPreference is set to Continue by default so I’ll tweak it for this command.

The -ErrorAction Stop part should make the script stop executing on an error and hop into the Catch block. Wrong! The above command throws an error without triggering the Catch block, too.

It turns out I had to edit my $ErrorActionPreference variable to be Stop. Just using the flag in the command doesn’t work. I’ve run into this in other scripts where I import a PSSession, too. Now my command looks something like this.

First, I’m getting the current value of $ErrorActionPreference and storing it. Then I set the ErrorActionPreference to Stop. I run my Get-Recipient command which fails and now instead of getting an error, my Catch block is triggered. Afterwards, I set $ErrorActionPreference back to it’s previous value.

Now, because I’ve written a blog post about this, I’ll never forget again.


Quick Tip: Use PowerShell To Detect If A Location Is A Directory Or A Symlink

In PowerShell, symbolic links (symlinks) appear pretty transparently when you’re simply navigating the file system. If you’re doing other work, though, like changing ACLs, bumping into symlinks can be a pain. Here’s how to tell if a directory in question is a symlink or not.

Consider the following commands.

Here, we’re just running a Get-Item command on two locations, getting the Attributes property and converting to a string. The first item is a symlink and includes “ReparsePoint” in its attributes. The second item is a normal directory and does not include “ReparsePoint”.

So that means we can do something as easy as this.

Easy. If the above values have “ReparsePoint” in them, we know they are a symlink and not just a regular directory. In my case, my script to apply ACLs to a group of directories avoided symlinks with ease.


Bypassing PowerShell Execution Policy

Let me be absolutely clear about this post. I do not in any way encourage or support people who wish to use the below information to circumvent the controls put in place by companies and administrators. This post is strictly for academic purposes and for the sake of sharing information.

PowerShell Execution Policies control whether or not a system may run a PowerShell script based on whether the script is signed or not. See the about_Execution_Policies Technet page for more information if you are unfamiliar with execution policies or how to apply them. Execution policies do not, however, limit a user or service from running commands in a PowerShell shell (PowerShell.exe).

So what if you have an unsigned script you want to run but your execution policy is preventing it? Well, there’s a way to bypass the execution policy. And it’s run from a PowerShell shell.

Administrative users can easily bypass the execution policy with this command.

But what about limited users? Well there’s something for them, too.

That’s right, just one line. No registry hacking, no weird developer program strangeness, just a command that allows a user or service to subvert the execution policy of the machine.

Let’s break down the command. We’re launching PowerShell.exe, not exactly a puzzler. We want it with no profile and we’re telling it to run a command. The trick is that the command we’re running is effectively going to be the script that our execution policy would otherwise block.

The dot is basically an alias for “execute” and in this case, we’re telling it to execute what’s in the proceeding round brackets. The round brackets contain instructions to create a new ScriptBlock out of the contents of the .ps1 file that the execution policy would otherwise prevent from running.

I think it’s clear that this is not really something that Microsoft intends for you to do. Use (or not) wisely at your own discretion.