Jump to content

Several Questions on Login Scripts


Recommended Posts

Posted

Howdy all.

New to this group. Have several questions related to login scripts:

 

Does the NetLogon directory need to have the user's name added to it

for read & execute permissions or would be be better to grant the

Every One object read and execute permission - might be better to

include the domain users group? Latter seems better as one may forget

to add new user to Netlogon directory.

 

In addition to the NetLogon directory, the login script

(GroupMaps.vbs) is also listed/included in a group policy for domain

users. It is listed under User configuration, Window Settings,

Scripts(logon/logoff), Logon. But it did not fire until I also listed

the file under the User Profile Tab of the user account...and here I

had to use the format \\ServerName\Netlogon\GroupMaps.vbs instead of C:

\Windows\sysvol\domain\sysvol\scripts\GroupMaps.vbs which did not

work.

Seems like the way it worked for me was to use the Netlogon directory

in conjunction w/User Profile path as testing w/just the group policy

did not work...Which is the correct way?

 

Finally, in the script my initial test account, test user (login

tuser), does not display the groups in which the account belongs, e.g.

BoeingGroup, thus it does not map the drive and printers. So I created

another user, John T. Doe (login jdoe) who does display being in the

same groups as test user and for whom the script runs correctly...

Any possible reasons for this?

 

Thanks in advance for your suggestions. Will have to do some more

reading...

 

Rey

 

Below is the login script being tested.

' purpose: map drive based on grp membership

' Example from http://www.computerperformance.co.uk/Logon/logon_group_membership.htm

' Modified for use on OEM domain

' Rey Collazo 8/30/2007, 12/18/2007

 

' GroupMap.vbs

' Author Guy Thomas http://computerperformance.co.uk/

' Version 3.3 - May 2006

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

Option Explicit

 

Dim objNetwork, objUser, CurrentUser

Dim strGroup

Dim objFSO

Dim strUserDIR

 

' printers

Dim prnBoeingDefault

Dim prnBoeingGeneral

Dim prnBoeingLS

Dim prnKittingCopier

Dim prnAdminCopier

 

' printer names

prnBoeingDefault = "\\oemphxdc00\HP LJ2420DN"

prnBoeingLS = "\\oemphxdc00\HP LJ2300N"

prnAdminCopier = "\\oemphxdc00\Admin_copier"

prnKittingCopier = "\\oemphxdc00\Kitting_copier"

 

 

' simple way of bypassing already connected drives...

On Error Resume Next

 

' Initialise Groups with Const

Const BoeingGroup = "cn=oem boeing seattle users"

Const ExecutivesGroup = "cn=OEM Executive - Sales"

'Const ManagersGroup = "cn=OEM Managers"

'Const Users_Group = "cn=users"

'Const Administrators_Group = "cn=administrators"

 

' Create objects and extract strGroup values

Set objNetwork = CreateObject("WScript.Network")

Set objUser = CreateObject("ADSystemInfo")

Set CurrentUser = GetObject("LDAP://" & objUser.UserName)

 

wscript.echo "Sleeping a bit..."

wscript.sleep 200

 

strGroup = LCase(Join(CurrentUser.MemberOf))

 

Wscript.echo "User name: " & objNetwork.username

wscript.echo "Current user: " & objUser.username

WScript.Echo "Member of " & strGroup

 

' add shared drive (S) for all users

'WScript.Echo "Shared Drive - all users" & vbcrlf & "User: " &

objNetwork.UserName

objNetwork.MapNetworkDrive "S:", "\\oemphxdc00\shared"

 

' set home directory for user if exists - not being created via script

'objNetwork.MapNetworkDrive "H:", "\\oemphxdc00\Users\" &

objNetwork.UserName

 

If InStr(strGroup, lcase(BoeingGroup)) Then

WScript.Echo "Boeing Seattle User "

' map drive persistent

objNetwork.MapNetworkDrive "M:", "\\oemphxdc00\Boeing Seattle\"

 

' setting default grp printer

objNetwork.AddWindowsPrinterConnection prnBoeingDefault

objNetwork.SetDefaultPrinter prnBoeingDefault

 

' adding other printers

objNetwork.AddWindowsPrinterConnection prnBoeingLS

objNetwork.AddWindowsPrinterConnection prnAdminCopier

 

ElseIf InStr(strGroup, lcase(ExecutivesGroup)) Then

'WScript.Echo " Executives "

objNetwork.MapNetworkDrive "N:", "\\oemphxdc00\Executive_Sales\"

 

End If

 

 

' setting default grp printer

' objNetwork.AddWindowsPrinterConnection prnBoeingDefault

' objNetwork.SetDefaultPrinter prnBoeingDefault

 

' ' adding other printers

' objNetwork.AddWindowsPrinterConnection prnBoeingLS

' objNetwork.AddWindowsPrinterConnection prnAdminCopier

' objNetwork.AddWindowsPrinterConnection prnKittingCopier

 

 

'Wscript.Echo "Finished Testing for Groups "

WScript.Quit

 

' End of GroupMaps

  • Replies 2
  • Created
  • Last Reply
Guest Richard Mueller [MVP]
Posted

Re: Several Questions on Login Scripts

 

See comments inline below:

 

"Rey" <reycollazo@cox.net> wrote in message

news:5492b1f9-3250-4130-874e-e2d66a604c9b@s12g2000prg.googlegroups.com...

> Howdy all.

> New to this group. Have several questions related to login scripts:

>

> Does the NetLogon directory need to have the user's name added to it

> for read & execute permissions or would be be better to grant the

> Every One object read and execute permission - might be better to

> include the domain users group? Latter seems better as one may forget

> to add new user to Netlogon directory.

 

By default the group "Everyone" has read permissions in the NetLogon share.

On the Security tab (in ADUC) the group "Authenticated Users" has Read and

Execute permissions. I've never altered this.

>

> In addition to the NetLogon directory, the login script

> (GroupMaps.vbs) is also listed/included in a group policy for domain

> users. It is listed under User configuration, Window Settings,

> Scripts(logon/logoff), Logon. But it did not fire until I also listed

> the file under the User Profile Tab of the user account...and here I

> had to use the format \\ServerName\Netlogon\GroupMaps.vbs instead of C:

> \Windows\sysvol\domain\sysvol\scripts\GroupMaps.vbs which did not

> work.

> Seems like the way it worked for me was to use the Netlogon directory

> in conjunction w/User Profile path as testing w/just the group policy

> did not work...Which is the correct way?

 

If you configure a logon script on the Profile tab and also in a Group

Policy it will run twice (or each will run). On the Profile tab for the user

in ADUC if you enter "GroupMaps.vbs" in the field labeled "Logon script",

the logon script becomes

 

\\ServerName\NetLogon\GroupMaps.vbs

 

where \\ServerName is the DC that authenticated the user. This is better

than being tied down to one DC. The way to configure logon scripts in a

group policy is to copy the logon script so it is on the Windows clipboard,

edit the Group Policy and navigate to the Logon script setting (User

Configuration, Windows Settings, Scripts), double click Logon, click the

"Show Files..." button, and past the logon script in the dialog. Otherwise

it's too difficult to figure out where the *.vbs file should go. Then close

the dialog and click the Add button and Browse to select the logon script.

 

For more on configuring logon scripts, see this link:

 

http://www.rlmueller.net/LogonScriptFAQ.htm

 

In testing the script you post below, the first step is to remove "On Error

Resume Next". This makes troubleshooting nearly impossible. Logon scripts

are too important; if there is a problem, you want an error message to alert

you and give you a clue where to start (like a line number). Most logon

scripts can be initially tested as normal scripts run after logon is

complete, but you test with a normal user account.

 

The most likely cause of your problem below is the statement:

 

strGroup = LCase(Join(CurrentUser.MemberOf))

 

I know this is freqently suggested (and I think Microsoft might even use

this), but it is flawed. The memberOf attribute is multi-valued. It can have

no values, one value, or more than one. Your code must work in all three

situations. In this case, the Join function will raise a type mismatch error

unless the user is a member of at least two groups, so that memberOf is a

variant array. In you case one of your test users was a member of two or

more groups (other than the "primary" group, usually "Domain Users", which

is never included) while the other was not.

 

If you want to use a similar method, I would suggest:

===============

Set objSysInfo = CreateObject("ADSystemInfo")

strUserDN = objSysInfo.UserName

 

Set objUser = GetObject("LDAP://" & strUserDN)

 

On Error Resume Next

 

arrGroups = objUser.GetEx("memberOf")

 

If (Err.Number <> 0) Then

 

On Error GoTo 0

 

strGroup = ""

 

Else

 

On Error GoTo 0

 

strGroup = LCase(Join(arrGroups))

 

End If

 

===========

Note that I use "On Error Resume Next", but only for the one statement I

expect might raise an error. Then I handle the error and restore normal

error handling with "On Error GoTo 0". I use the GetEx method because it

only raises an error if memberOf is empty (no group memberships other than

the "primary"). If the user is a member of only one group, GetEx returns a

variant array with one element. For more details, and other methods to check

direct membership in groups, see this link:

 

http://www.rlmueller.net/MemberOf.htm

>

> Finally, in the script my initial test account, test user (login

> tuser), does not display the groups in which the account belongs, e.g.

> BoeingGroup, thus it does not map the drive and printers. So I created

> another user, John T. Doe (login jdoe) who does display being in the

> same groups as test user and for whom the script runs correctly...

> Any possible reasons for this?

>

> Thanks in advance for your suggestions. Will have to do some more

> reading...

>

> Rey

>

> Below is the login script being tested.

> ' purpose: map drive based on grp membership

> ' Example from

> http://www.computerperformance.co.uk/Logon/logon_group_membership.htm

> ' Modified for use on OEM domain

> ' Rey Collazo 8/30/2007, 12/18/2007

>

> ' GroupMap.vbs

> ' Author Guy Thomas http://computerperformance.co.uk/

> ' Version 3.3 - May 2006

> ' -----------------------------------------------------------------'

> Option Explicit

>

> Dim objNetwork, objUser, CurrentUser

> Dim strGroup

> Dim objFSO

> Dim strUserDIR

>

> ' printers

> Dim prnBoeingDefault

> Dim prnBoeingGeneral

> Dim prnBoeingLS

> Dim prnKittingCopier

> Dim prnAdminCopier

>

> ' printer names

> prnBoeingDefault = "\\oemphxdc00\HP LJ2420DN"

> prnBoeingLS = "\\oemphxdc00\HP LJ2300N"

> prnAdminCopier = "\\oemphxdc00\Admin_copier"

> prnKittingCopier = "\\oemphxdc00\Kitting_copier"

>

>

> ' simple way of bypassing already connected drives...

> On Error Resume Next

>

> ' Initialise Groups with Const

> Const BoeingGroup = "cn=oem boeing seattle users"

> Const ExecutivesGroup = "cn=OEM Executive - Sales"

> 'Const ManagersGroup = "cn=OEM Managers"

> 'Const Users_Group = "cn=users"

> 'Const Administrators_Group = "cn=administrators"

>

> ' Create objects and extract strGroup values

> Set objNetwork = CreateObject("WScript.Network")

> Set objUser = CreateObject("ADSystemInfo")

> Set CurrentUser = GetObject("LDAP://" & objUser.UserName)

>

> wscript.echo "Sleeping a bit..."

> wscript.sleep 200

>

> strGroup = LCase(Join(CurrentUser.MemberOf))

>

> Wscript.echo "User name: " & objNetwork.username

> wscript.echo "Current user: " & objUser.username

> WScript.Echo "Member of " & strGroup

>

> ' add shared drive (S) for all users

> 'WScript.Echo "Shared Drive - all users" & vbcrlf & "User: " &

> objNetwork.UserName

> objNetwork.MapNetworkDrive "S:", "\\oemphxdc00\shared"

>

> ' set home directory for user if exists - not being created via script

> 'objNetwork.MapNetworkDrive "H:", "\\oemphxdc00\Users\" &

> objNetwork.UserName

>

> If InStr(strGroup, lcase(BoeingGroup)) Then

> WScript.Echo "Boeing Seattle User "

> ' map drive persistent

> objNetwork.MapNetworkDrive "M:", "\\oemphxdc00\Boeing Seattle\"

>

> ' setting default grp printer

> objNetwork.AddWindowsPrinterConnection prnBoeingDefault

> objNetwork.SetDefaultPrinter prnBoeingDefault

>

> ' adding other printers

> objNetwork.AddWindowsPrinterConnection prnBoeingLS

> objNetwork.AddWindowsPrinterConnection prnAdminCopier

>

> ElseIf InStr(strGroup, lcase(ExecutivesGroup)) Then

> 'WScript.Echo " Executives "

> objNetwork.MapNetworkDrive "N:", "\\oemphxdc00\Executive_Sales\"

>

> End If

>

>

> ' setting default grp printer

> ' objNetwork.AddWindowsPrinterConnection prnBoeingDefault

> ' objNetwork.SetDefaultPrinter prnBoeingDefault

>

> ' ' adding other printers

> ' objNetwork.AddWindowsPrinterConnection prnBoeingLS

> ' objNetwork.AddWindowsPrinterConnection prnAdminCopier

> ' objNetwork.AddWindowsPrinterConnection prnKittingCopier

>

>

> 'Wscript.Echo "Finished Testing for Groups "

> WScript.Quit

>

> ' End of GroupMaps

 

The only other comment I have is that the Sleep would only be useful if you

have Win9x clients. If errors are raised because of persistent drive

mappings, I would suggest a subroutine that maps and if there is an error

removes the existing mapping so it is no longer persistent, then tries

again. The subroutine should raise an error if the second attempt fails so

you are alerted to the problem (possibly permissions). For example:

===============

If InStr(strGroup, lcase(BoeingGroup)) Then

Call MapDrive("M:", "\\oemphxdc00\Boeing Seattle\")

End If

 

Sub MapDrive(ByVal strDrive, ByVal strShare)

' Subroutine to map a drive to a share.

' objNetwork must be defined in the main

' program so it has global scope.

 

On Error Resume Next

objNetwork.MapNetworkDrive strDrive, strShare

If (Err.Number <> 0) Then

On Error GoTo 0

' Remove drive mapping even if it is in use and

' make the removal persistent.

objNetwork.RemoveNetworkDrive strDrive, True, True

' Try again to map the drive to the share

objNetwork.MapNetworkDrive strDrive, strShare

End If

End Sub

===============

A more elaborate scheme (that handles more situations) is a function to map

the drives that returns True if successful, False otherwise. This way the

main program can alert the user to errors (so they can be fixed), but the

logon script does not halt. This is demonstrated in this snippet:

==========

' objFSO must have global scope.

Set objFSO = CreateObject("Scripting.FileSystemObject")

 

If InStr(strGroup, lcase(BoeingGroup)) Then

If (MapDrive("M:", "\\oemphxdc00\Boeing Seattle\") = False) Then

Call MsgBox("Unable to map drive M: to \\oemphxdc00\Boeing

Seattle\")

End If

End If

 

Function MapDrive(ByVal strDrive, ByVal strShare)

' Function to map network share to a drive letter.

' If the drive letter specified is already in use, the function

' attempts to remove the network connection.

' objFSO is the File System Object, with global scope.

' objNetwork is the Network object, with global scope.

' Returns True if drive mapped, False otherwise.

 

Dim objDrive

 

On Error Resume Next

If (objFSO.DriveExists(strDrive) = True) Then

Set objDrive = objFSO.GetDrive(strDrive)

If (Err.Number <> 0) Then

On Error GoTo 0

MapDrive = False

Exit Function

End If

If (objDrive.DriveType = 3) Then

objNetwork.RemoveNetworkDrive strDrive, True, True

Else

MapDrive = False

Exit Function

End If

Set objDrive = Nothing

End If

objNetwork.MapNetworkDrive strDrive, strShare

If (Err.Number = 0) Then

MapDrive = True

Else

Err.Clear

MapDrive = False

End If

On Error GoTo 0

End Function

============

This is demonstrated in the logon script in this link, along with a

membership checking procedure that handles nested groups.

 

http://www.rlmueller.net/Logon3.htm

 

--

Richard Mueller

Microsoft MVP Scripting and ADSI

Hilltop Lab - http://www.rlmueller.net

--

Posted

Re: Several Questions on Login Scripts

 

Howdy Richard.

Thanks for the suggestions. Implemented your GetEx("memberOf")

suggestion and it worked for test user.

 

As part of test, copied the script over to the appropriate directory

under sysvol\domain\Polices (windows 2003 server) as the group policy

editor did not display any dialog box into which I could paste the

script but then I could have been in the wrong place...

 

Found that I also had to keep the file in the Netlogon directory as I

was getting userinit.exe errors when loggin in a the test accounts;

review of the application events showed that file could not be found

under sysvol

 

Once this was done, seemed like nothing was working until I added the

servername\netlogon\GroupMaps.vbs to profile tab after adding domain

users and everyone grp to Netlogon directory.

 

In short, removed domain users, everyone grp and entry in profile tab

and it now works as a new employee logged in and the correct mapping

for a Boeing user occurred in addition to printers. Wonder if there

was any lag time in updating group policy?

Researching a different issue, had an existing user logged in to a

different machine and she received no mappings and no errs

displayed...logged out, logged back and she now had mappings. Guess

I'll try making mappins persistant...

 

Thanks again for the suggestions and links provided.

 

Rey

 

On Dec 19, 7:33 pm, "Richard Mueller [MVP]" <rlmueller-

nos...@ameritech.nospam.net> wrote:

> See comments inline below:

>

> "Rey" <reycoll...@cox.net> wrote in message

>

> news:5492b1f9-3250-4130-874e-e2d66a604c9b@s12g2000prg.googlegroups.com...

>

> > Howdy all.

> > New to this group. Have several questions related to login scripts:

>

> > Does the NetLogon directory need to have the user's name added to it

> > for read & execute permissions or would be be better to grant the

> > Every One object read and execute permission - might be better to

> > include the domain users group? Latter seems better as one may forget

> > to add new user to Netlogon directory.

>

> By default the group "Everyone" has read permissions in the NetLogon share.

> On the Security tab (in ADUC) the group "Authenticated Users" has Read and

> Execute permissions. I've never altered this.

>

>

>

> > In addition to the NetLogon directory, the login script

> > (GroupMaps.vbs) is also listed/included in a group policy for domain

> > users. It is listed under User configuration, Window Settings,

> > Scripts(logon/logoff), Logon. But it did not fire until I also listed

> > the file under the User Profile Tab of the user account...and here I

> > had to use the format \\ServerName\Netlogon\GroupMaps.vbs instead of C:

> > \Windows\sysvol\domain\sysvol\scripts\GroupMaps.vbs which did not

> > work.

> > Seems like the way it worked for me was to use the Netlogon directory

> > in conjunction w/User Profile path as testing w/just the group policy

> > did not work...Which is the correct way?

>

> If you configure a logon script on the Profile tab and also in a Group

> Policy it will run twice (or each will run). On the Profile tab for the user

> in ADUC if you enter "GroupMaps.vbs" in the field labeled "Logon script",

> the logon script becomes

>

> \\ServerName\NetLogon\GroupMaps.vbs

>

> where \\ServerName is the DC that authenticated the user. This is better

> than being tied down to one DC. The way to configure logon scripts in a

> group policy is to copy the logon script so it is on the Windows clipboard,

> edit the Group Policy and navigate to the Logon script setting (User

> Configuration, Windows Settings, Scripts), double click Logon, click the

> "Show Files..." button, and past the logon script in the dialog. Otherwise

> it's too difficult to figure out where the *.vbs file should go. Then close

> the dialog and click the Add button and Browse to select the logon script.

>

> For more on configuring logon scripts, see this link:

>

> http://www.rlmueller.net/LogonScriptFAQ.htm

>

> In testing the script you post below, the first step is to remove "On Error

> Resume Next". This makes troubleshooting nearly impossible. Logon scripts

> are too important; if there is a problem, you want an error message to alert

> you and give you a clue where to start (like a line number). Most logon

> scripts can be initially tested as normal scripts run after logon is

> complete, but you test with a normal user account.

>

> The most likely cause of your problem below is the statement:

>

> strGroup = LCase(Join(CurrentUser.MemberOf))

>

> I know this is freqently suggested (and I think Microsoft might even use

> this), but it is flawed. The memberOf attribute is multi-valued. It can have

> no values, one value, or more than one. Your code must work in all three

> situations. In this case, the Join function will raise a type mismatch error

> unless the user is a member of at least two groups, so that memberOf is a

> variant array. In you case one of your test users was a member of two or

> more groups (other than the "primary" group, usually "Domain Users", which

> is never included) while the other was not.

>

> If you want to use a similar method, I would suggest:

> ===============

> Set objSysInfo = CreateObject("ADSystemInfo")

> strUserDN = objSysInfo.UserName

>

> Set objUser = GetObject("LDAP://" & strUserDN)

>

> On Error Resume Next

>

> arrGroups = objUser.GetEx("memberOf")

>

> If (Err.Number <> 0) Then

>

> On Error GoTo 0

>

> strGroup = ""

>

> Else

>

> On Error GoTo 0

>

> strGroup = LCase(Join(arrGroups))

>

> End If

>

> ===========

> Note that I use "On Error Resume Next", but only for the one statement I

> expect might raise an error. Then I handle the error and restore normal

> error handling with "On Error GoTo 0". I use the GetEx method because it

> only raises an error if memberOf is empty (no group memberships other than

> the "primary"). If the user is a member of only one group, GetEx returns a

> variant array with one element. For more details, and other methods to check

> direct membership in groups, see this link:

>

> http://www.rlmueller.net/MemberOf.htm

>

>


×
×
  • Create New...