Solved

We need to execute a VBS script at the log off for a group of computers.

Posted on 2012-03-22
9
540 Views
Last Modified: 2012-06-21
Hi,

We are trying to run a vbs (the code is attached below) that basically copies some file on over share. We need for the script to be executed at the log off and only for a group of computers.

So far I have created an test OU and moved a test workstation to it. Then I have created a GPO and configured the computer side with the "Log off" option and finally attached the vbs script that we want to run.

I have done some testing but I haven't been successful.

Could someone help us out?

Thank you





-------------------------------------------------------------------

Dim sOutlookCommand
Dim fso
Dim wshShell
'--------------------------


'--------------------------
'SET OBJECTS
On Error Resume Next
Set wshNetwork = CreateObject("WScript.Network")
Set ADSysInfo = CreateObject("ADSystemInfo")
Set CurrentUser = GetObject("LDAP://" & ADSysInfo.UserName)
Set fso = CreateObject("Scripting.Filesystemobject")
set wshShell = CreateObject("wscript.shell")


'--------------------------

'--------------------------
'DETERMINE THE GROUPS THE USER IS IN.
'NOTE THAT IF THE PERSON IS IN ONE GROUP, THE JOIN COMMAND WILL ERROR.
'THIS IS WHY ISARRAY IS NECESSARY.
If IsArray(CurrentUser.MemberOf) Then
        strGroups = LCase(Join(CurrentUser.MemberOf))
Else
        strGroups = LCase(CurrentUser.MemberOf)
End If
'---------------------------
'GET CURRENT USERS LOGON NAME
Set wshShell = CreateObject("WScript.Shell")
strUser = wshShell.ExpandEnvironmentStrings("%USERNAME%")
msgbox strUser

'THIS SUBROUTINE COPIES THE USERs NME PROFILE TO A HIDDEN SHARE

Set nFSO = CreateObject("Scripting.FileSystemObject")

Dest="\\ss1\nmeprofiles$\"+StrUser+"\"

If nFSO.FolderExists(Dest) Then
  '
else
  nFSO.CreateFolder(Dest)

end if

nFSO.CopyFile "C:\WINDOwS\nmpag.ini" , Dest
nFSO.CopyFile "C:\windows\newsmake.ini" , Dest
nFSO.CopyFile "C:\Program Files\Microsoft Office\Office\Custom.dic" , Dest
nFSO.CopyFile "C:\Program Files\Microsoft Office\Templates\Normal.dot" , Dest
0
Comment
Question by:llarava
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
9 Comments
 
LVL 9

Expert Comment

by:Dan Arseneau
ID: 37754471
Are you returned any errors on the screen or the Event Logs?  Also, is the vbs file located in a Public place where all machines can access?

EDIT:  You shouldn't have a msgbox command in a login/logoff script.
0
 

Author Comment

by:llarava
ID: 37754545
The script is placed is the netlogon.

Event Logs don't show anything.

By the way I put a comment on the code below for the following statement 'msgbox strUser
0
 
LVL 65

Expert Comment

by:RobSampson
ID: 37754917
Hi, I think you've mixed things up a bit.  You are assigning a "user" logoff script, but want to check the group membership of a "computer", right?

So what you need to do is assign logoff script to an OU that contains your users (or is higher than that, it doesn't really matter), then have the script determine the group membership of the *computer*, an then decide whether to do anything or not.

Something like this should work.

'--------------------------
'DETERMINE IF THE COMPUTER IS A MEMBER OF A SPECIFIC GROUP
On Error Resume Next
Set objADSysInfo = CreateObject("ADSystemInfo")
Set objGroup = GetObject("LDAP://CN=Computer_Normal_Template_Copy_Group,CN=Users,DC=Domain,DC=Com")
blnMember = False
For Each objMember In objGroup.Members
	If LCase(objMember.distinguishedName) = LCase(objADSysInfo.ComputerName) Then blnMember = True
Next

' Exit the script if the computer was not in the specified group
If blnMember = False Then WScript.Quit

'--------------------------
'SET OBJECTS
On Error Resume Next
Set wshNetwork = CreateObject("WScript.Network")
Set nFSO = CreateObject("Scripting.FileSystemObject")

strUser = wshNetwork.UserName

'THIS SUBROUTINE COPIES THE USERs NME PROFILE TO A HIDDEN SHARE

Dest= "\\ss1\nmeprofiles$\" & strUser & "\"

If nFSO.FolderExists(Dest) = False Then nFSO.CreateFolder(Dest)
nFSO.CopyFile "C:\WINDOwS\nmpag.ini" , Dest, True
nFSO.CopyFile "C:\windows\newsmake.ini" , Dest, True
nFSO.CopyFile "C:\Program Files\Microsoft Office\Office\Custom.dic" , Dest, True
nFSO.CopyFile "C:\Program Files\Microsoft Office\Templates\Normal.dot" , Dest, True

Open in new window


Regards,

Rob.
0
NEW Veeam Agent for Microsoft Windows

Backup and recover physical and cloud-based servers and workstations, as well as endpoint devices that belong to remote users. Avoid downtime and data loss quickly and easily for Windows-based physical or public cloud-based workloads!

 

Author Comment

by:llarava
ID: 37755195
Hi Rob,

All I want to do is to apply a log off script to a group of workstation. What we want is for every user works on any of these computers to run the script when they log off from them works. The script will copy some files to the a network share on a per user profile basis.

The script creates a folder based on the user logon and then it places the files within that folder.

When the users logon to the workstations we need the files to be pushed from their folder (at the file server) and replace the ones that are local within the workstaiton.

Then when the log off we need the files to be pushed up to the file server and placed into the users folder.

This is more like a roaming type of solution where these files are following the users when they roam between workstations.

I am currently trying to figure out the "Log off" part (where the files are copied from the local workstation when a log off is performed and they are placed on a file server within the user folder)


My understanding is that all I need to do is:

1.) Create a GPO computer and then configure the script to run at the Log off
2.) Link the GPo to the OU where I have my workstations

The computers do not belong to any group just an OU.

Do I need to use LoopBack process policy in order to get this done?
0
 
LVL 65

Accepted Solution

by:
RobSampson earned 500 total points
ID: 37755285
Yes, loopback processing can run *user* logoff scripts based on computer membership.

Since I don't use loopback processing though, I apply such a script to all users (the entire AD), and just check whether the computer is part of a group of OU.  To change my script to check an OU, change this section:
'--------------------------
'DETERMINE IF THE COMPUTER IS A MEMBER OF A SPECIFIC GROUP
On Error Resume Next
Set objADSysInfo = CreateObject("ADSystemInfo")
Set objGroup = GetObject("LDAP://CN=Computer_Normal_Template_Copy_Group,CN=Users,DC=Domain,DC=Com")
blnMember = False
For Each objMember In objGroup.Members
	If LCase(objMember.distinguishedName) = LCase(objADSysInfo.ComputerName) Then blnMember = True
Next

' Exit the script if the computer was not in the specified group
If blnMember = False Then WScript.Quit

'--------------------------

Open in new window


to this:
'--------------------------
'DETERMINE IF THE COMPUTER IS A MEMBER OF A SPECIFIC GROUP
On Error Resume Next
Set objADSysInfo = CreateObject("ADSystemInfo")
Set objOU = GetObject("LDAP://OU=Special Computers,OU=Sites,DC=Domain,DC=Com")
blnMember = False
WScript.Echo objADSysInfo.ComputerName
For Each objMember In objOU
	If LCase(objMember.distinguishedName) = LCase(objADSysInfo.ComputerName) Then blnMember = True
Next

' Exit the script if the computer was not in the specified group
If blnMember = False Then WScript.Quit

'--------------------------

Open in new window


But, you should be able to enable loopback processing and use the script you have written, except, change this:
strGroups = ";"
If IsArray(CurrentUser.MemberOf) Then
	strGroups = strGroups & LCase(Join(CurrentUser.MemberOf)) & ";"
Else
	strGroups = strGroups & ";" & LCase(CurrentUser.MemberOf, ";") & ";"
End If

Open in new window


And then use
If InStr(strGroups, LCase(";YourUserGroupName;")) > 0 Then
	' Move the files
End If

Open in new window


The semi-colons should remain in the strings.  They separate the group names.

Regards,

Rob.
0
 

Author Comment

by:llarava
ID: 37757455
Here is what I have done to get it working.

Since I wanted the script at user logoff I have assigned it at user level, not computer level. I wanted to run for certain computers only so I have to created an OU and move those computers into it. Then I have created a new GPO and name it "Loopback processing" - then enable  at the Computer configuration level the Group policy loopback processing option, setting it to Merge. Then created another GPO and name it "Logoff data transfer" - and and set the logoff script at User configuration level. Finally link both GPO at the new created OU level. Both GPO are now applied to Authenticated users group (default setting).

I have used the original script with Rob's modification. I also like the script that Rob provided, It might work really well for something else I had in mind.

Rob can you please explain the change in my original script?

If InStr(strGroups, LCase(";YourUserGroupName;")) > 0 Then
      ' Move the files
End If

Thank you!
0
 

Author Closing Comment

by:llarava
ID: 37757465
Sorry I keep asking you questions...but I can't get tired of asking you always have a great solution or you come back with a different approach. Thank you!
0
 
LVL 65

Expert Comment

by:RobSampson
ID: 37764386
Hi, thanks for the grade.

To explain the groups string check, you originally had this
If IsArray(CurrentUser.MemberOf) Then
        strGroups = LCase(Join(CurrentUser.MemberOf))
Else
        strGroups = LCase(CurrentUser.MemberOf)
End If

Open in new window


in which strGroups could contain
Finance,Human Resources,IT

With my code of
strGroups = ";"
If IsArray(CurrentUser.MemberOf) Then
	strGroups = strGroups & LCase(Join(CurrentUser.MemberOf)) & ";"
Else
	strGroups = strGroups & ";" & LCase(CurrentUser.MemberOf, ";") & ";"
End If

Open in new window


what you end up with is
;Finance;Human Resources;IT;

The reason is that if a group name had a comma (say "Human, Resources"), your original code would produce
Finance,Human, Resources,IT

and my change would produce
;Finance;Human, Resources;IT

Now, if you wanted to determine if a user was in a group *also* called just "Resources", and you only used
If InStr(strGroups, "Resources") > 0 Then
  'Member
End If

Open in new window


Then it would match, even though the user is not in Resources, but they are in Human, Resources.

So, with the semi-colons, if you search for
If InStr(strGroups, ";Resources;") > 0 Then
  'Member
End If

Open in new window


Then it wouldn't match, as expected, but if you used
If InStr(strGroups, ";Human, Resources;") > 0 Then
  'Member
End If

Open in new window


then it would match.

I hope that explains it well enough.  It's an odd concept, but it avoids false positives.

Regards,

Rob.
0
 

Author Comment

by:llarava
ID: 37765475
Got it. Thank you again for your help!
0

Featured Post

Office 365 Training for IT Pros

Learn how to provision tenants, synchronize on-premise Active Directory, implement Single Sign-On, customize Office deployment, and protect your organization with eDiscovery and DLP policies.  Only from Platform Scholar.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

A project that enables an administrator to perform actions within a user session context not just at the time of login but any time later on day(s) or week(s) later.
Auditing domain password hashes is a commonly overlooked but critical requirement to ensuring secure passwords practices are followed. Methods exist to extract hashes directly for a live domain however this article describes a process to extract u…
This tutorial will walk an individual through the process of transferring the five major, necessary Active Directory Roles, commonly referred to as the FSMO roles to another domain controller. Log onto the new domain controller with a user account t…
This tutorial will walk an individual through the process of configuring their Windows Server 2012 domain controller to synchronize its time with a trusted, external resource. Use Google, Bing, or other preferred search engine to locate trusted NTP …

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question