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.
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.
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.
Here is the same client after User1 logged in.
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:
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()
|
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
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.