PowerShell, Make it do something useful!

powershell2xa4$users = ((Get-ADUser -filter * | where-object { $_.GivenName -ne $null }) | foreach{ $_.Name})
foreach ($user in $users)
        $FirstName = (Get-ADUser -filter {Name -eq $User} | foreach {$_.GivenName}).ToString()
        $SurName = (Get-ADUser -filter {Name -eq $User} | foreach {$_.SurName}).ToString()
        $DisplayName = ("$Firstname" + " " + "$Surname")
        Set-ADUser $User -DisplayName $DisplayName
        Set-ADUser $User -Description "User Created by Windows Server 2012 Essentials Dashboard"

You might be wondering what the hell that means?

Anyone who recently came along to any of the three SBSC User Groups i presented at, will have been forced to listen to me attempt, and fail, to enthuse the audience about PowerShell. I should really leave it to the experts, however i have been so excited by what i have picked up recently i wanted to share that with the masses.

In a recent  discussion with some people about Windows Server Essentials we were puzzling over a bug/feature in the Essentials OS whereby if you created a user via the Dashboard, it did not have all of it’s attributes set correctly in Active Directory. The gist of which was that the Dashboard should populate the ‘Display Name’ field in the user account properties, which it didn’t.



You might think, well, that’s no big deal. Well you’d be right. Except you might find an issue like this.

Susan, being Susan opted to bug it using Microsoft Connect. Me, being me, decided to write a script to fix it.

It took me about two hours to figure it all out and write/test it., and you can download it from here.

I shared the resulting script with those that were part of the conversation, and the response was – ok, but how did you do that? What resources did you use?

I wrote out a pretty verbose email on exactly that, and sent it along.

Over the weekend i have been following some tweets from @GuyGregory about the UK PowerShell ‘PowerCamp’ put on by @doctordns, a PowerShell MVP (an event i really should have gone to) and again, that has inspired me to try and tweak peoples interest into PowerShell. If i can get you interested to the point where you might want to go along to one of these (apparently excellent) events, then i will rest easy. But be warned, i will just keep on about PowerShell until you do, and that is not going to be good for either of us.

For better or worse, i have decided to post it up here as well (slightly edited) and also drop in some videos i made recently on other PowerShell scripts i have written. One tip i can definitely give you is rather than use the default PowerShell window, i would suggest you use PowerShell ISE (integrated Scripting Environment).

Starting Point

What is the starting point? Well first you need to know what is your script going to do. In this case i want my script to update the display name field in a users AD properties. I guess it would be useful then, to start by trying to find that info with PowerShell.

A quick Bingle Search will probably lead you to the Get-ADUser CmdLet.

If you then search on that term, you will find this very useful TechNet page, and another here.

You can also use a command inside the PowerShell window,

Get-Help Get-ADUser

The output of which will display some basic help about the CmdLet and also show you how to find more detailed information and examples.


We can use Get-ADUser to find all users in the domain.

If we type Get-ADUser, we will be prompted to filter that query, using a * we can display all of our users.

Get-ADUser –Filter *

* meaning, show me everything.

It is important to note at this point, that the results returned are ‘Objects’. A user that is returned, and all the properties that user has, are contained within that Object. This will become clearer a little further on.


Given that, lets narrow down our research and just chose one user object to look at.

Get-ADUser –Identity JamesBond


You will see here a small subset of the most common properties of the user account. Interestingly we don’t see the DisplayName value shown. We can expand on our results by adding the Properties to our query.

Get-ADUser –Identity JamesBond –Properties *

This will result in a huge amount of properties being shown, too many to screen shot. but you can now find the DisplayName value in the list.


We can also query for a specific value, by doing the following,

Get-ADUser –Identity JamesBond –Properties DisplayName


So, now we know how to find the value we want to change, how do we change it?

With most PowerShell tools/commands, if you have a Get command, there is most likely a Set command. A quick search on ‘setting a users properties via PowerShell’ would most likely lead you to Set-ADUser (amazing really)

We can then use a command like,

Set-ADUser  JamesBond –DisplayName “James Bond”


We can then run our Get command again, and see that the DisplayName is now updated.


OK, Now what?

Now we know the two commands we need to use to Find and Set the information we want, we can star to put together the script to do this automatically for all users.

Taking our Get-ADUser command though, and filtering out only those accounts added by the Essentials dashboard is a little bit more involved.

We need to find something common to all those users that is not shared by any other user or service account in the domain. Fortunately that appears to be quite easy, and if you filter for users using the ‘GivenName’ attribute, looking for Users that have a value, you will find that all of the Essentials users match that criteria.

In other words, find all the users who have a first name set in their account.

So, how do we do that?

We know we can use Get-ADUser  to find all the users in the domain, and we want to narrow down those results.

We can do that using a filter.  There are some good examples of filtering on the ‘Get-ADUser’ page.

Starting again with our command to find all users..

Get-ADUser –filter *

We can then add on some additional filtering with a pipe and  then use the ’Where-Object’ filter.

As you can read in that excellent explanation..

“..the $_ notation is used to represent the default object (that is, the object being transferred across the pipeline)..”

Get-ADUser –filter * | Where-Object

We now need to enter in something to check against our Object. (Remember Objects?)

We place our object within two curly brackets { } as well as the criteria we are searching for.

Using the default notation of $_ we can chose a specific property of the object to check by adding it on like this,


This tells my ‘Where-Object’ query to look at the Object returned for it’s ‘GivenName’ attribute.

We can then add any one of a number of things to check the attribute for example:

  • -lt — Less than
  • -le — Less than or equal to
  • -gt — Greater than
  • -ge — Greater than or equal to
  • -eq — Equal to
  • -ne — Not equal to
  • -like – Like; uses wildcards for pattern matching

We want to check for objects, that do not have an empty value for their GivenName, so our query becomes..

Get-ADUser -filter * | where-object { $_.GivenName -ne $null }


Running this command will return all of the user objects who don’t have an empty ‘GivenName’ which you will find is all of the Essentials users.

We now want to work with those objects individually, to do that we can use the ‘ForEach Object’ CmdLet.

Using ForEach allows us to process additional commands against each object that is returned from our query. When you get the hang of it, it is really very cool.We place our action inside two curly brackets { }.

An example of that would be something like this..

Get-ADUser -filter * | where-object { $_.GivenName -ne $null } | ForEach { Set-ADUser $_ –Displayname “Meh” }


This would set everyone’s DisplayName to ‘Meh’ which is probably not that useful.



What we actually want to do is take a User Objects Given Name and Surname and set those as the DisplayName.

It is important to note that the DisplayName has to be a text string, which means whatever information we take from the User Object, we must then convert to a string of text.

For example, if we run this query.

Get-ADUser –Identity JamesBond | ForEach { $_.GivenName }

We would get a result returned, but that result is not plain text it is still part of the Object.


To convert that to plain text, we need to use the ToString CmdLet.

That would make our command look a bit more like this..

(Get-ADUser –Identity JamesBond | ForEach { $_.GivenName }).ToString()

The result is the same when displayed on the screen (ie, the word James) however they are very different when it comes to working with them.


We can run the same command to take a Surname out to text string.

(Get-ADUser –Identity JamesBond | ForEach { $_.SurName }).ToString()

Now we know how to create text strings, we can put that together to create our DisplayName string. We can make use of variables to make it all a little easier to follow. Here is a great tutorial on variables.

First we can store the Given Name & Surname under their own Variables.

$FirstName = (Get-ADUser –Identity JamesBond  | foreach {$_.GivenName}).ToString() 
$SurName = (Get-ADUser –Identity JamesBond   | foreach {$_.SurName}).ToString()


We can then check the result of that, by simply typing that variable into the PowerShell window.


Then we can create another variable using these.

$DisplayName = (“$Firstname” + “ “ + “$Surname”)

I have inserted a space into the string using “ “.


Now our $DisplayName variable is created we can run the following command.

Set-ADUser “JamesBond” –Displayname $DisplayName


This would set 007s display name to “James Bond”,


Now, imagine we have a full Active Directory of users we want to do this for, we can start to put this altogether and build something that will run against all the users.

We will create a variable to store all the user objects in.

$users = ((Get-ADUser -filter * | where-object { $_.GivenName -ne $null }) | foreach{ $_.Name})

(I added an additional ForEach at the end of this line to only keep the the objects UserName in the variable.)


We will add in a ForEach statement for all of the Objects returned, and give each object it’s own variable $user.

foreach ($user in $users)

Then finally we can set the action to be applied to those objects.

        $FirstName = (Get-ADUser -filter {Name -eq $User} | foreach {$_.GivenName}).ToString()
        $SurName = (Get-ADUser -filter {Name -eq $User} | foreach {$_.SurName}).ToString()
        $DisplayName = ("$Firstname" + " " + "$Surname") 
        Set-ADUser $User -DisplayName $DisplayName 

Our script becomes..


As you can see from the above i also added another action, which was to update the users description field.

As you can see for another use in the network, Luke Skywalker the DisplayName and Description are updated.


I’m really hoping that i have explained this well, and i am also hoping that i might have shown you that it is quite simple to do something in PowerShell that you might think is difficult. I don’t have any development experience and everything i have outlined above i have picked up from the links i have put in, and other general searching for how to do things in PowerShell. I really am not trying to suggest i am an expert, i am just a beginner, but i think PowerShell is going to become a massive part of Administration in the future and i think those of us in the SMB space may need to start to embrace it, where perhaps we have ignored it in favour of the GUI or the SBS Console.

As i mentioned the PowerShell ISE is a really great tool for learning, and in Server 2012 it is even better because it actually suggests things to you as you type!


Here are some videos i put together going through some of the other scripts i have written.

More Links:








About Robert Pearman
Robert Pearman is a UK based Small Business Server enthusiast. He has been working within the SMB IT Industry for what feels like forever. Robert likes Piña colada and taking walks in the rain, on occasion he also enjoys writing about Small Business Technology like Windows Server Essentials or more recently writing PowerShell Scripts. If you're in trouble, and you can find him, maybe you can ask him a question.

10 Responses to PowerShell, Make it do something useful!

  1. Anything that you do in Where-Object can be moved to the filter with Get-ADuser. Your expression will be more efficient letting Get-ADUser doing the work. Otherwise, you are retrieving ALL users and THEN filtering.

    $users = Get-ADUser -filter “GivenName -like ‘*'”

    To retrieve just the Name property, you can use Select-Object and expand the property.

    $users = Get-ADUser -filter “GivenName -like ‘*'” | Select-Object -expandproperty Name.

    But you don’t even have to do that. In your foreach loop you are working harder than you need to by making repeated calls for the same object. This code should achieve the same result but much more efficiently.

    $users = Get-ADUser -filter “GivenName -like ‘*'”
    foreach ($user in $users) {
    $Displayname = “$($user.GivenName) $($User.Surname)”
    Set-ADUser $user -Description “User Created…” -DisplayName $displayname

    • $me = PowerShell Novice


      Thanks, that is great, much appreciated.

      Where i struggle with PowerShell, is in finding the sort of info from your comments.

      For example, Select-Object -expandproperty Name, i did not know about -expandproperty.

      Whilst i know my code is inefficient, it works, which is kind of the point ;0); But by reading your comment it is really useful to see how it can be improved.

      Also, $Displayname = “$($user.GivenName) $($User.Surname)”

      Knowing that i can use the “$(… in that manner is also very useful.

  2. I’m glad to see you enthusiastic about using PowerShell. The challenge is to think about objects and not messing about with strings and text. You know your code works, which on one hand means don’t worry about it. But I’m motivated to help people maximize their efficiency with Powershell.

  3. auldreeker says:

    /me loves powershell
    Used it this week to delete 11,000 (eleven thousand) exchange mailboxes this week.

  4. Tim Bolton says:

    Jeffery is correct of course, but very nice post. Keep it up!

  5. martinklein says:

    thanks, great help!!!

  6. Guru says:

    Hi, how can I append some info, like a project name or contractor or location to a displayname. Example: if I have one person’s display name as “Display Name” I would want to change it to “Display Name (Location)”. Please help. – Rgds, Guru.

    • You need to make sure you collect the attribute on line 40. you do that by adding in the attribute after -properties.

      then you need to put that in to the email by adding the attribute $user.Attribute whereever it fits in the body of your message.

Leave a reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: