PowerShell Logon Scripts Revisited
Just about a year ago, I posted an article here about using Windows PowerShell for logon scripts.
As noted in that post, to start you off, I presented a “Basic” example (and I’m not referring to VisualBasic script here) in quoting a Microsoft example. Also in that post were several other tips such as “the scripts must be accessible at a path visible to the client” and (although I could have been more clear in my choice of words by adding “if”) “unqualified, therefore in the local folder – that PowerShell script will run at the same location as the VBscript.” In other words, I intentionally drew the dots yet didn’t connect them for you. But now I think it’s time that I spell it out and be more clear. Here’s a recent request from someone regarding last years post:
“Unfortunately, that sample is as useless as every time people quote it. It seems to be the standard accepted non-functional answer. The problem: c:\scripts\logon.ps1
[…] The location of the logon script is never a mapped drive. It’s something like: \\%userdomain%\sysvol\domain.com\Policies\{AAD5280F-A3B7-4F65-B15B-27E6F92BA431}\User\Scripts\Logon.
So, the .vbs script mentioned is not going to know where it is and presumably the .ps1 script will be in the same location. Now please, it would be great if you could show us how one could actually run a logon script using powershell.” (ellipsis mine)
Indeed, I think that’s a great idea. Thanks for asking. Let’s start with one slight modification of that earlier example, and then go with the even more beautifully straightforward answer to the question without any fancy explicit paths.
Let’s treat the following as a proof of concept on which we’ll improve once you have it working in a test environment. Success with simple examples is often good prior to getting into realistic solutions. I hope this helps. If you have assigned the following VBscript as a logon script via Group Policy, it will reveal several things.
’ logon.vbs – brief example
set objShell = CreateObject( “Wscript.Shell” )
objShell.run( “powershell.exe –noexit c:\scripts\logon.ps1” )
Before getting into what running that can reveal, let us consider a change from my earlier post. Assume that the contents of this c:\scripts\logon.ps1 is as follows:
“Hello, world!”
“Thus is redirected at $(get-date)” >logon.$($(get-date).ticks).txt
What do you get when you run it? Two things. First, due to the –noexit parameter used when logon.vbs launches logon.ps1, the shell window stays open and reveals the current path to be that of the folder with the logon.vbs script. In other words, this is typically a UNC file sharing path into the GPO’s User\Scripts\Logon folder. For example, for a certain GPO in the domain sp.wernerconsulting.com the path is:
\\sp.wernerconsulting.com\SysVol\sp.wernerconsulting.com\Policies\{C7872F8D-79E0-4770-BCC4-8A4B6E1A6C33}\User\Scripts\Logon
Secondly, even though the logon.ps1 ran from the c:\scripts folder, its current location is also in the GPO’s User\Scripts\Logon folder. For example, the file created when the script runs is stored in that folder (if you have permissions to it).
So why does that basic example use the local path c:\scripts\logon.ps1? Signing. If the PowerShell execution policy is set to RemoteSigned, the script will not run from the remote UNC path, even if you are testing this locally on a domain controller. For instance, if we changed logon.vbs to simply use either a relative path .\locallogon.ps1 or implicitly local path locallogon.ps1 as follows, we would get a PSSecurityException “cannot be loaded … is not digitally signed. The script will not execute on the system.”
’ logon.vbs – same path example
set objShell = CreateObject( “Wscript.Shell” )
objShell.run( “powershell.exe –noexit locallogon.ps1” )
So we see in reality the .vbs script does intrinsically know where it is running and can easily launch a PowerShell script residing in the same location. Again, my older post included suggestions regarding not using –noexit yet including other parameters. But which remedy would you choose for the execution policy issue? We have several choices.
Option 1. Code sign the script file(s) used as logon scripts and use the “same path example” shown above for the .vbs glue. Alternately, another UNC path could be used beside that of the GPO’s subfolder, however the code signing would still be necessary.
Option 2. Adjust the execution policy. This approach also requires adjustment of the options used to run the script.
Option 3. Adjust the trusted locations relative to the code signing and execution policy.
Option 4. Use a local path for the script file repository and use the “basic example” referenced earlier as the .vbs glue. Note that Group Policy Preferences may be used to create the local script repository and populate it. Alternately, the script repository could be deployed using Group Policy software deployment. Note that in this is a local path rather than a mapped drive.
There are several other options, as well as permutations, details, rationale, ramifications, and possibilities for PowerShell logon script execution. I hope this helps. Please let me know of any further questions.
Author: Brad Werner
Related Courses
Configuring, Managing, and Maintaining Server 2008 R2 (M6419)






Leave your response!