Link to home
Start Free TrialLog in
Avatar of brianroma
brianroma

asked on

Powershell logon script that would map drives and printers based on group (or possibly OU?) memebership

Hey guys,

We have approximately 30 scripts that map drives for them each time they log in. The script currently disconnects mapped drives (with letters that we might want to use) and then maps the drives:

@echo off
net use s: /d
net use g: /d
net use s: \\mydomain.com\departments
net use g: "\\mydomain.com\Departments\Accounting"
exit



There is one script for each group in the organization and each one of these scripts is linked to each department OU in our AD structure. We added a new share on the file server and it was then (I am new here) that I found out how many logon scripts there are.

My questions are:

Can powershell disconnect drives/map drives based on OU or group memebership?

Can powershell map printers based on OU or group memebership?

Would it be faster (for users to log on) to create 30 powershell scripts for these tasks? Or one big script?

Would powershell be slower than a VB script? (a manager here feels that powershell would have "too much overhead to be fast")

Thanks for the help, all!!
Avatar of Chris Dent
Chris Dent
Flag of United Kingdom of Great Britain and Northern Ireland image


Sure but...

To use a PowerShell logon script PowerShell must be installed on every client system. For a very simple script I would expect PowerShell to be slower as well, the overheads of running PowerShell are higher than the script engine.

For now at least I would recommend VbScript over PowerShell for logon scripts. Native support, plenty of samples, and capable of checking any of the items mentioned above.

Chris

> the overheads of running PowerShell are higher than the script engine.

Should include a caveat... depending on what the script is doing of course. PowerShell is can do more in general, and do more with ease, but logon scripts aren't generally very complex.

Chris
ASKER CERTIFIED SOLUTION
Avatar of Don
Don
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of brianroma
brianroma

ASKER

Hey All!

My PC at the office died and I have been off radar for a few days. I am looking at this VBScript option now.

Thanks for the suggestions so far!

B
Ok, the parameters of this task have shifted a bit. I am now being asked to map drives based on OU instead of group. Is anyone aware of a VB option? Would powershell be a good option in this case?

Thanks for everyone's help!

Brian

> Would powershell be a good option in this case?

Definitely no easier in PowerShell than VbScript.

In both cases you have a choice of parsing the name out of the string (as in the first example provided by dstewartjr), or you can pull the Parent property from a user object. In VbScript...

Dim objADSysInfo : Set objADSysInfo = CreateObject("ADSystemInfo")
Dim objUser : Set objUser = GetObject("LDAP://" & objADSysInfo.UserName)
strParentADSPath = objUser.Parent

Chris

> In both cases

Erm that is for finding the OU. Finding group membership ranges from very simple to complex but very capable.

Chris
I am having issues with getting a functioning script in VB or PowerShell. Our users are nested in several OUs.

Standard Users reside in (as an example):

Departments/Information Technology/Users

The script examples I am looking at only point at parent OUs. Am I stuck with using group filtering based on groups because of our OU structure?

Thanks for everyone's help and patience!

Brian


Show us what you have so far? And let us know what you'd like it to do?

Chris
Ok, we have an OU Structure like this (I will use IT as an example):

Departments
                     Information Technology    
                                                         Users          


I looked at the VB script links posted above and I cannot figure out how to map drives for accounts that are in the Users OU. I then tried to get a drive mapped if an account was in the Departments OU.

I modified the below VBScript but i keep getting an this error


Script: c:\Drive Map OU.vbs
Line: 17
Char: 9
Error: The network path was not found
Code: 80070035
Source WSHNetwork.MapNetworkDrive

If I run a net use for either of the above shares, they drive maps fine.



'=================
Set objSysInfo = CreateObject("ADSystemInfo")
strName = objSysInfo.UserName

arrUserName = Split(strName, ",")
arrOU = Split(arrUserName(1), "=")
strUserOU = arrOU(1)

Set objNetwork = CreateObject("WScript.Network")

Select Case strUserOU
    Case "Service Accounts"
        objNetwork.MapNetworkDrive "T:", "\\mydomain.com\departments",True
    'Case "Departments"
        objNetwork.MapNetworkDrive "U:", "\\mydomain.com\process",True
    'Case "Human Resources"
        objNetwork.MapNetworkDrive "Y:", "\\servername2\sharename3",True
    Case Else
        ' do not map any drives
End Select
'=================


I was also asked to come up with a PowerShell equivalent of this script so we can compare/contrast them in our test environment.


I have a couple of other projects off my plate, so I will be responding more quickly.


Thanks Chris--

Brian

Given the structure above, if you want the department name then this will give you it:

arrUserName = Split(strName, ",")
arrOU = Split(arrUserName(2), "=")
strDeptOU = arrOU(1)

It's difficult to know what to say about the error it's giving you. It's rare for it to be wrong :) We could always set it to ping the server name and tell us what happened.

For PowerShell... It's a tad more complex, ADSystemInfo isn't quite as accessible, but something like the below.

Chris
$ADSysInfo = New-Object -ComObject ADSystemInfo
$UserDN = [System.__ComObject].InvokeMember("UserName", `
  [System.Reflection.BindingFlags]::GetProperty, $Null, $ADSysInfo, $Null)
 
$DepartmentOU = ($UserDN.Split(",")[2]).Split("=")[1]
 
$Network = New-Object -ComObject WScript.Network
 
Switch $DepartmentOU {
  "Service Accounts" { $Network.MapNetworkDrive("T:", "\\mydomain.com\departments", $True) }
  "Departments"      { $Network.MapNetworkDrive("U:", "\\mydomain.com\process", $True) }
  "Human Resources"  { $Network.MapNetworkDrive("Y:", "\\servername2\sharename3", $True) }
}

Open in new window

I have this as a test for a dummy IT user account:

$ADSysInfo = New-Object -ComObject ADSystemInfo
$UserDN = [System.__ComObject].InvokeMember("UserName", `
  [System.Reflection.BindingFlags]::GetProperty, $Null, $ADSysInfo, $Null)
 
$DepartmentOU = ($UserDN.Split(",")[2]).Split("=")[1]
 
$Network = New-Object -ComObject WScript.Network
 
Switch $DepartmentOU {
  "Information technology" { $Network.MapNetworkDrive("Q:", "\\mud.com\departments", $True) }
 
}





I get the following error in PowerGui Script Editor:

Unexpected token '}' in expression or statement.
At :line:9 char:2
+ }
 <<<<


Apologies, missed some parentheses :)

It should work with this:

Switch ($DepartmentOU) {
  "Information technology" { $Network.MapNetworkDrive("Q:", "\\mud.com\departments", $True) }
 
}


Chris
The additional parenthesis made it so the script ran without errors in PowerGUI Script Editor. However, the drive still does not map.

The OU where the test account resides is

Departments\Information Technology\Users



I don't see a place in the script where it identifies the users sub OU (then again, I am a PS noob).

I can run a net use Q: \\mud.com\departments and my test account has a Q drive mapped.

The current PS script:


$ADSysInfo = New-Object -ComObject ADSystemInfo
$UserDN = [System.__ComObject].InvokeMember("UserName", `
  [System.Reflection.BindingFlags]::GetProperty, $Null, $ADSysInfo, $Null)
 
$DepartmentOU = ($UserDN.Split(",")[2]).Split("=")[1]
 
$Network = New-Object -ComObject WScript.Network
 
Switch ($DepartmentOU) {
  "Information technology" { $Network.MapNetworkDrive("Q:", "\\mud.com\departments", $True) }
 
}

$DepartmentOU contains that value. Have it echo perhaps? Added Write-Host to do that below.

Note that if the value for the OU is "Information Technology" it won't match, case is important with this comparison method (same for VbScript). If case is likely to be an issue we could just use:

$DepartmentOU = $DepartmentOU.ToLower()

With:

Switch ($DepartmentOU) {
  "information technology" { $Network.MapNetworkDrive("Q:", "\\mud.com\departments", $True) }
}

As long as all departments were referred to in their lower case form it would (should) work.

Chris
$ADSysInfo = New-Object -ComObject ADSystemInfo
$UserDN = [System.__ComObject].InvokeMember("UserName", `
  [System.Reflection.BindingFlags]::GetProperty, $Null, $ADSysInfo, $Null)
 
$DepartmentOU = ($UserDN.Split(",")[2]).Split("=")[1]
Write-Host "User was found in $DepartmentOU"
 
$Network = New-Object -ComObject WScript.Network
 
Switch ($DepartmentOU) {
  "Information technology" { $Network.MapNetworkDrive("Q:", "\\mud.com\departments", $True) }
}

Open in new window

PowerGUI Script Editor runs the script now:

User was found in Users


But the drive still does not map.


My code:

$ADSysInfo = New-Object -ComObject ADSystemInfo
$UserDN = [System.__ComObject].InvokeMember("UserName", `
  [System.Reflection.BindingFlags]::GetProperty, $Null, $ADSysInfo, $Null)
 
$DepartmentOU = ($UserDN.Split(",")[2]).Split("=")[1]
Write-Host "User was found in $DepartmentOU"
 
$Network = New-Object -ComObject WScript.Network
 
Switch ($DepartmentOU) {
  "Information technology" { $Network.MapNetworkDrive("Q:", "\\mud.com\departments", $True) }
}


SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I'm looking for a solution to this also. I currently use a VBscript for this purpose, but I would like to find a PowerShell alternative.

Has anyone found a way to do this with PowerShell?

Which bit?

PowerShell is a great language, but it has a few problems competing with VbScript for logon scripts. It has an unfortunate tendency to introduce complexity rather than remove it.

And, of course, there's the requirement for you to make sure PowerShell is installed on every client.

Chris
Powershell on the clients isn't a problem: a simple gpo can push that out. As for complexity it can't be any worse than what I'm already dealing with using my vbscript.

Here's the overall goal: I want to be able to set the default printer on all of my workstations based on the logged on security group membership. The vbscript I use works, however I'm only able to use it with the cscript interpreter (not wscript). Cscript requires admin privileges to execute, so the users where I have this implemented have to be local admin (scary I know).

I was thinking about using powershell for this purpose, but any help you could provide with my vbscript would be helpful.

Thanks

We can do both and compare, but would you mind raising it as a new question so everything is clear?

Chris
Roger that.
Hi, I stumbled upon this discussion trying to learn more about what people are doing with Powershell these days and I'm not sure if you guys already figured all this stuff out or not but I wanted to see if you guys have ever used the ifmember.exe.  VBscripting and Powershell is far too complicated for me as I don't have much VB or PS experience but for something as simple as a login script, you might want to look into ifmember.exe with a simple batch file if you haven't already.  I've been using it for years and it does exactily what I need it to do and never fails and most importantly, I have ONE script that works for all the users, simply called logon.bat.  For each OU with users in it, i.e. Tampa, the users would be put in a security group called "Tampa" or if they aren't in any specific OU the could belong to just a security group like "Accounting" and the batch file looks like this below and done in about 1 minute:  Download the ifmember program and put the exe in the same folder as your scripts, \\server\sysvol\domain\scripts and the script is as follows:
@echo off
REM Disconnect any currently mapped drives except for A-D and the u drive
net use f: /delete
net use f: /delete
net use g: /delete
net use h: /delete
net use i: /delete
net use j: /delete
net use k: /delete
net use l: /delete
net use m: /delete
net use n: /delete
net use o: /delete
net use p: /delete
net use q: /delete
net use r: /delete
net use s: /delete
net use t: /delete
rem net use u: /delete
net use v: /delete
net use w: /delete
net use x: /delete
net use y: /delete
net use z: /delete

REM Mapping drives per Group Membership
ifmember "Accounting"
if not errorlevel 1 goto endBatch
net use n:  \\ls-wtgl0f6\accounting
net use p:  \\ls-wtgl0f6\apps
net use q:  \\w2003server1\quickbooks
net use w:  \\ls-wtgl0f6\invoices
net use y:  \\ls-wtgl0f6\payroll
:EndBatch

ifmember "Tampa"
if not errorlevel 1 goto endBatch
net use t:  \\ls-wtgl0f6\Tampa
net use r:  \\ls-wtgl0f6\tampa\projects
REM Add printer
echo Installing [printer name] on [servername]!
RunDll32.EXE printui.dll,PrintUIEntry /in /n \\server\printer

echo Your default printer is [printername] on [server]
REM Set Default Printer
RunDll32.EXE printui.dll,PrintUIEntry /y /n \\server\printer
:EndBatch

ifmember "domain users"
if not errorlevel 1 goto endBatch
net use z:  \\ls-wtgl0f6\download
net use s:  \\ls-wtgl0f6\Shared
:EndBatch

:Exit
 Exit
Very compelling, but some of your commands in this demo script aren't understood by PowerShell: rem, net use, if not (ifnot instead).

How can I adjust this script for these allowances?
The script above is just a simple batch file in notepad.  It isn't for Powershell.  
Modus,

This was my question originally. Am I still not allowed to comment on it??
jhill,

Thanks for the tip. It would have helped if I read your post thoroughly!

Thanks.
Modus,

Belay that. Wrong question!

My apologies.
I believe brianroma originally asked the question
I thought my comment applied to the original question.  Basically, no need to use powershell for what he was trying to do when a batch file works fine.  No need to reinvent the wheel, right?  lol

Sure, but almost a year too late :)

I would suggest:

Accept: dstewartjr http:#24642937 & Assist: Chris-Dent http:#24763205

The code in principal works, the errors we faced were environment specific.

Chris
haha...yeah, a year later and there hadn't been points assigned to you guys yet either.  I just figured I'd throw in my two cents for any network admins googling a rather simple task like mapping drives and printers since the author never seemed to get it all wrapped up or never acknowledged such.