3

I've written a logon script in PowerShell. The Script is embedded in GPO and runs when a user is logging into the domain.

My Problem is, that the drives I deploy in the Script don't get deployed. I'm sure the logon script runs because in the end of the script i send an email to myself and I always receive it. So running the script should not be the problem. I'm also logging the whole $Error Variable each time the script runs and there is no indication to why this error occurs.

I'm almost certain that the error is not in the script itself - it has to be a permission error i think.

I think that this could be solved when I specify the -NoProfile Parameter when running the script, but I don't know where to put this in the GPO. I don't want a batch file calling the script because of beauty reasons :-).

Edit: specifying -noprofile didn't solve the issue

Edit: Since there was a comment saying there is not enough information about how the drives are mapped, I pasted the whole mapping part below:

# UserOU as a parameter, value set in GPO
Param([string]$UserOU)

# preparing some stuff...
Import-Module .\SecureStringFunctions.psm1
[Byte[]]$key = (1..16)
$pw = Get-Content .\LocalAdminCred.txt | ConvertTo-SecureString -key $key

# Tried this to elevate the Script IF it's needed. Didn't solve my problem. works only on PS 4.0 but didn't solve the issue on my 5.0 machine
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) 
{ Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }

# Import CSV with drive information based on username and userOU to get every maps that the current user needs
# also replacing a string inside the CSV for current session to map the homedrive of each user
$Drives = (Get-Content .\NetworkDrives.csv) -replace "userhome",$env:username | ConvertFrom-CSV -Delimiter ';' | ? {
    (($_.Group.split(',') -contains $UserOU) -or ($_.Group.split(',') -contains $env:username)) -and (!(Test-Path $_.Letter))
} 

# When I export the $Drives Variable at this point, all drives were read correctly, so the failure must occur in the mapping

# map all drives for current user. Drives to DMZ with password in plain text because ".mapnetworkdrive" only accepts plain text.
$Drives | % {
    if (![system.string]::IsNullOrEmpty($_.Username)) {
        if (($UserOU -like 'admin*') -and (($_.Server -ne $env:computername) -or ([system.string]::IsNullOrEmpty($_.Server)))) { 
            Continue
        }
        [string]$pwplain = ConvertFrom-SecureString $pw -AsPlainText -Force
        $Map = New-Object -comobject Wscript.Network
        $Map.MapNetworkDrive($_.letter,$_.path,$false,$_.username,$pwplain)
        $pwplain = ""
    } else { 
        $Map = New-Object -comobject Wscript.Network
        $Map.MapNetworkDrive($_.letter,$_.path,$false)    
    }
}
SimonS
  • 767
  • 3
  • 13
  • 28
  • 3
    Why are you using logon scripts to map network drives instead of Group Policy Preferences? – Massimo Apr 04 '16 at 15:44
  • @Massimo we are using group policy preferences to map drives inside the internal network. For all network drives that connect to DMZ we use a script because as far as I know, you can't pass credentials inside GPP anymore. Since we already have to use the script, it also checks if GPP mapped the drive correctly and if it hasn't, the script will map them again – SimonS Apr 04 '16 at 18:40
  • 1
    "My script Test-Paths all drive letters and if they weren't mapped by GPO, it will map it"... this doesn't make any sense. Drive mapping done via GPO shouldn't fail, and if it fails it should be fixed, not worked around by redoing the same thing with a script. – Massimo Apr 04 '16 at 18:40
  • Oh, and BTW, you *can* pass credentials when mapping drives using GPP: https://technet.microsoft.com/en-us/library/cc770902.aspx. – Massimo Apr 04 '16 at 18:41
  • 1
    @Massimo either I did something wrong or you can not pass credentials anymore since KBxy. The option is greyed out on my DC 2012 R2. I think I also got an answer on technet that says the same. – SimonS Apr 04 '16 at 18:48
  • @Massimo The script should not be a workaround. it's just another check to see if something doesn't work. if GPO fails, the script creates a log immediately so I know there's an error right as it occurs. I think that's not bad. If it is, I'll gladly delete those code lines in my script, it only makes it run faster ;-) – SimonS Apr 04 '16 at 18:51
  • 1
    Looks like you are correct about not being able to store credentials in GPP: https://support.microsoft.com/en-us/kb/2962486. They removed the functionality, but forgot to update the docs. – Massimo Apr 04 '16 at 18:54
  • 2
    Unfortunately, the script snippet you provided doesn't really provide a tremendous amount of value. Without seeing the whole thing, all we can do is guess that the values in the variables end up being what you want. Have you tried running the script in a test environment and seeing if it maps the drives you want? – Naryna Apr 04 '16 at 18:55
  • 1
    @BrandynBaryski The script works correctly whenever I start it inside powershell_ise or call it inside a powershell session. the script doesn't work when I set it up in GPO. I'm adding some information to my question how it selects all drives to map for each user. – SimonS Apr 04 '16 at 19:09
  • It's worth noting that these scripts run at the local user level, as already stated, which means that if any of your statements that draw in variables would fail without elevated permissions then the script won't execute properly. Creating a test user with basic permissions and running the script from their account would rule out that possibility. Also, check GPO and make sure you aren't restricting powershell execution for basic users (remote-signed has gotten me a number of times). Other than that, I'll take a look at the updated information when it comes. – Naryna Apr 04 '16 at 19:18
  • @BrandynBaryski remote signed. that could be it. I will test that and come back to you afterwards. thanks. – SimonS Apr 04 '16 at 19:31
  • @BrandynBaryski unfortunately not. I will test anything else that comes to my mind, maybe i'll even set up a little test network without any security preferences. thank you all for your help. – SimonS Apr 04 '16 at 19:47
  • Does the script run in the user context or under some service context? – Brian Lewis Apr 04 '16 at 17:48
  • Well, now that I've looked at the code I have a basic idea. Have you tried testing to make sure the LocalAdminCred.txt exists? Just do a basic test at the beginning of the script and maybe write the result to a log file or include it in your email. I am going off the comment in your code saying that drives were read into the variables properly which means that username, drive and path are all correctly loaded. – Naryna Apr 04 '16 at 21:52
  • @BrandynBaryski the credential is also loaded correctly. I first `set-location` to the sysvol share, and read everything from there. did not paste that in my code above, but it happens right before the `#preparing` part – SimonS Apr 05 '16 at 05:46
  • Is your GPO calling this .ps1 under Computer>Logon Script or User>Login Script? – Skeer Apr 04 '16 at 22:46
  • @skeer: User > Login Script. Tried the "Script" and "PowerShell Script" Tab. – SimonS Apr 05 '16 at 05:40
  • Ok thats good.. Just making sure you didnt have it under Computers. – Skeer Apr 05 '16 at 13:06
  • you should be able to avoid all of this by simply ACLing the share properly. Then you can use GP prefs – Jim B Apr 05 '16 at 16:54

2 Answers2

6

I've got a solution now.

What creates this behaviour of your logon script not wanting to map drives?

If you have Windows 10, you want to use Edge, Calculator and PDF App. Microsoft says you need UAC enabled for that, otherwise it won't work. So you enable UAC by GPO (Reg. Key EnableLua). https://technet.microsoft.com/en-us/library/dd835564%28v=ws.10%29.aspx

BUT: if you're deploying a logon script inside the GPO and your User is a local Admin on the Computer on which he's logging on - which in my case is on every computer because I'm a Domain Admin - UAC will drop your account to a non privileged user, and as we know, if they're not running in the same context, you won't get your drives deployed in your admin account.

This is in fact by design, and it’s caused by the way UAC works. When you’re a member of the Administrators group and you log in, your account is busted down to a non-privileged user by UAC. This running context is completely separate from the context you get when you right-click Command Prompt and launch as an administrator. As you’ll probably have noticed, network drives connected in one context are not visible in the other. The problem is that GPO-based login scripts are being executed in the Administrator context – not the ordinary user context.

Quote from http://pcloadletter.co.uk/2010/05/15/missing-network-drives/

So you're disabling UAC and your GPO-Logon-Script will work. You're happy for a moment but then you realize you can't use edge anymore.

So how can we enable UAC and have our Logon Script working?

I did it with this by Microsoft not supported Registry Hack. I guess it's a vulnerability to your system security, keep that in mind if you're doing this the same way as I do:

HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System
New Entry: Type: DWORD Name: "EnableLinkedConnections" Value: 1

And BAM! you can use logon scripts, UAC, edge, whatsoever.

Other things you could try - I didn't try any of those yet:

  • Call your PS File in a batch script which is stored in GPO
  • Set up your PS Script as a scheduled Task inside GPO

So hopefully this will be useful for other Administrators that have problems with their logon script.

Cheers!

SimonS
  • 767
  • 3
  • 13
  • 28
  • Interesting and probably the last thing I would have thought of. This definitely isn't the case in Windows 8.1. My domain admin account gets mapped drives from logon scripts just fine (Note, these are batch scripts and not powershell). Yet another reason to not yet move to Windows 10. – Naryna Apr 05 '16 at 16:03
  • @BrandynBaryski and you also have UAC enabled? strange. @ downvoter Who downvoted this answer? Please explain why. – SimonS Apr 05 '16 at 16:52
0

I think your problem may exist with your calling the files that you are importing. Are these files stored in the sysvol for your GPO in question? The .\ implies that it's looking in the same directory as the script for the file in question.
Now if the "Get-content" files are in the proper place, it may be that you are calling the username environment variable which may not yet be initialized. Try testing proper loading and variables with a log like Brandyn suggests.

  • I first `set-location` to the sysvol share and read everything from there. the problem should really not be in the script itself. If my script would have problems with credentials, he would output it in `$error`. Everything is loaded correctly, only mapping the drives is a problem. When using `New-PSDrive` in a Logon script, you have to refer this to a global scope. maybe I need to do this with the `MapNetworkDrive` method too? – SimonS Apr 05 '16 at 05:42