Skip to main content

Changing a Computers Description in Active Directory to Match the currently Logged On User

This is one that I picked up off of PowerShell.com.  The problem is that that the answer is a bit long so I’m posting it here.  The IT Pro in question wants to change the Computers Description in Active Directory to match the login name of the currently logged in user.  A few issues come to mind.

1 – Does all of the clients have RSAT installed?  I’m going to assume no.  That means that we cannot use the Active Directory Modules cmdlets.

2 - Does all of the users have the rights to modify the description field of a client in Active Directory.  By default, they do not.  We will set this up at the attribute specific level.

3 – How will this script run?  We will implement it as a login script.

Modifying User Rights

First off, let’s tackle the user rights issue.  All users in your domain are able to read the contents of Active Directory.  Only a hand full should be allowed to modify it.  We are going to modify AD to allow for our users to modify just the client Description attribute.  This follows the Principal of Least Privilege.   Remember, once you do this, you will allow them to make changes on their own, outside of this script, to all clients Description fields.

You need to access Active Directory Users and Computers (ADUC).  You can find this on a Domain Controller or by installing RSAT from Microsoft.

In ADUC, right click the OU or Container that holds your client objects and select Delegate Control…

Click Next.

Click Add.

Here you need to add a security group containing all the users that you are going to allow to modify the Description property of computer objects.  In this demonstration, I am using Authenticated Users.  Click Check Names to verify that the group has been found and then click OK.

Click Next.

In the Tasks to Delegate window, select Create a custom task to delegate and click Next.

In the Active Directory Object Type window, select Only the following objects in the folder.

Scroll through the option and check Computer objects.

Click Next.

image

Uncheck General and check Property-specific.

Scroll down the list and check Write Description.  Click Next.

Click Finish.

Close ADUC.

 

Our Login Script

OK, now that security has been set up we need to write a PowerShell script.  We will be using Active Directory Services Integration (ADSI) to connect to Active Directory since we will not have the Active Directory PowerShell cmdlets to call upon.

Here is our login script:

1

2

3

4

5

6

7

8

9

10

11

# Get the user name.

$UserName = $env:USERNAME

 

# Get the client object from AD

$filter = "(&(objectCategory=computer)(objectClass=computer)(cn=$env:COMPUTERNAME))"

$DN = ([adsisearcher]$filter).FindOne().Properties.distinguishedname

 

# Modify the object.

$ObjClient = [ADSI]"LDAP://$DN"

$ObjClient.Description = $UserName

$ObjClient.SetInfo()

We store the username in the variable $Username.  Next, we use ADSI to get the computer object from Active Directory.  Finally, we set the description property of the object to the user name and commit it to AD. I saved this script into \\lon-dc1\SYSVOL\Adatum.com\scripts as Login1.ps1.

 

Setting up the GPOs

Our next step is to configure a GPO to run our script. I call this GPO User Login Scripts. First we configure the login script in the GPO.

User Configuration / Windows Settings / Scripts / Logon.

Click the PowerShell Scripts  tab.

Click Add and browse to and select Login.ps1.

In the dropdown box labeled For this GPO, run scripts in the following order: select Run Windows PowerShell scripts first 

Next click OK.

image

Scope the GPO User Login Scripts to an OU containing the user accounts or at the Domain level.

 

Starting with Windows 8, the running of logon scripts is delayed by 5 minutes.  We are going to override this.

Create a second GPO called Client Login Scripts.

Computer Configuration / Administrative Templates / System / Group Policy

Modify the policy for Configure Logon Script Delay.

Enable the Policy and then set the minute value to 0.

Scope this policy to an OU that contains your clients, or at the domain level.

 

Testing the Script

Here is an image from ADUC showing the current description of client LON-CL1. 

image

Here is the same client after User1 logged in.

image

This opens up a few new possibilities.  Take a look at the modified code below.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

# Get the user name.

$UserName = $env:USERNAME

 

# Get the client object from AD

$filter = "(&(objectCategory=computer)(objectClass=computer)(cn=$env:COMPUTERNAME))"

$DN = ([adsisearcher]$filter).FindOne().Properties.distinguishedname

 

#Get the date/time stamp.

$Date = Get-Date

 

# Modify the object.

$ObjClient = [ADSI]"LDAP://$DN"

$ObjClient.Description = "Logon : $UserName at $Date"

$ObjClient.SetInfo()

Here is the result in ADUC:

image

Now you can see if someone is logged in at a quick glace.  If you set up a Logoff script for the users, ADUC can also report a log off.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

 

# Logoff script.

 

# Get the user name.

$UserName = $env:USERNAME

 

# Get the client object from AD

$filter = "(&(objectCategory=computer)(objectClass=computer)(cn=$env:COMPUTERNAME))"

$DN = ([adsisearcher]$filter).FindOne().Properties.distinguishedname

 

#Get the date/time stamp.

$Date = Get-Date

 

# Modify the object.

$ObjClient = [ADSI]"LDAP://$DN"

$ObjClient.Description = "Logoff : $UserName at $Date"

$ObjClient.SetInfo()

 

 

image

 

Conclusion

Using this technique, you can get a quick look of who is where, and the last time you had a logon on a client. If the user does not perform a normal logoff or shutdown while connected to the network, you will not see a logoff message from the second script.  Also, if the user logs in using cached credentials while offline and then connects to the network, the Description property will not be modified.

Comments

Arie H. said…
Hi,

Just a small addition to this will be to check if the server has terminal services installed and running as if a few people login, only the last one of them will be mentioned. On top of, if its an active server where people login and logoff often this will "spam" the object making the data irrelevant :)
Maybe adding a delay / timer / check when the last time the desription changed etc.

If we want to see all of them, can add them all up, but at some point the max limit of chars for description will be reached plus im not sure its the best place to put that sort of a long list of data.

Other options will be to set a constant description on servers that have terminal services that will not change per the login, something along the lines "Terminal Services Active" or simillar.

Thanks for the script !

Arie H.

Popular posts from this blog

Adding a Comment to a GPO with PowerShell

As I'm writing this article, I'm also writing a customization for a PowerShell course I'm teaching next week in Phoenix.  This customization deals with Group Policy and PowerShell.  For those of you who attend my classes may already know this, but I sit their and try to ask the questions to myself that others may ask as I present the material.  I finished up my customization a few hours ago and then I realized that I did not add in how to put a comment on a GPO.  This is a feature that many Group Policy Administrators may not be aware of. This past summer I attended a presentation at TechEd on Group Policy.  One organization in the crowd had over 5,000 Group Policies.  In an environment like that, the comment section can be priceless.  I always like to write in the comment section why I created the policy so I know its purpose next week after I've completed 50 other tasks and can't remember what I did 5 minutes ago. In the Group Policy module for PowerShell V3, th

Return duplicate values from a collection with PowerShell

If you have a collection of objects and you want to remove any duplicate items, it is fairly simple. # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   # Remove the duplicate values. $Set1 | Select-Object -Unique 1 2 3 4 5 6 7 What if you want only the duplicate values and nothing else? # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   #Create a second collection with duplicate values removed. $Set2 = $Set1 | Select-Object -Unique   # Return only the duplicate values. ( Compare-Object -ReferenceObject $Set2 -DifferenceObject $Set1 ) . InputObject | Select-Object – Unique 1 2 This works with objects as well as numbers.  The first command creates a collection with 2 duplicates of both 1 and 2.   The second command creates another collection with the duplicates filtered out.  The Compare-Object cmdlet will first find items that are diffe

How to list all the AD LDS instances on a server

AD LDS allows you to provide directory services to applications that are free of the confines of Active Directory.  To list all the AD LDS instances on a server, follow this procedure: Log into the server in question Open a command prompt. Type dsdbutil and press Enter Type List Instances and press Enter . You will receive a list of the instance name, both the LDAP and SSL port numbers, the location of the database, and its status.