Perpetual Logon Script using PowerShell

Greg BessoLead Systems Engineer
CERTIFIED EXPERT
Continually learning and practicing with Microsoft technology solutions to make positive impacts in user productivity.
Published:
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.

Recently I had the chance to work on an interesting project, related to setting desktop wallpaper backgrounds for all users at a chosen date and time in the near future. At first this seemed like a very simple cut and dry exercise, just to update desktop wallpaper settings for users. But after reviewing the details of the environment and of the request, it seemed some more consideration was needed. This gave me a chance to take the out of box “login script” capabilities of Active Directory and have some fun with them.

 

First, the request. This is what matters, what the users are expecting…

  • need to change the desktop wallpaper for all of the PC users across all locations, to a new to-be provided custom image.
  • need to make this change to everyone at the same local time, using their local office working hours.
  • need to ensure the change occurs even if the users don’t log into their computers that day (meaning if they stay logged in from a previous day).
  • need to avoid applying the change early for anyone, as the changes were part of a surprise campaign.
  • need to avoid any resource bottlenecks, such as having all computers copy down the solution files at the same time / at time of execution.
  • need to do this within the next week (short notice given for project to be performed).


Next, some details I noticed while planning how best to accomplish this…

  • Not everyone logs into their computer “clean” each morning, many folks leave their system locked or in sleep mode.
  • The users that don’t login every day, they sometimes don’t even login every week. These “old” sessions needed a way to still be touched after days of being logged in.
  • When making the change using existing system-level processes, the wallpaper didn’t actually refresh in most cases. Test users had to log out/back in, or lock/unlock their screen, and in some cases go to the actual wallpaper settings window to trigger the change (even after the wallpaper setting was changed in the registry for them).
  • A typical login script that was “sleeping” would be visible to the users, which was not ideal.


Here is what I thought up of a way to accomplish the request…

My preferred method to accomplish this was to create a phone home / heartbeat type of script that ran within the user’s session, initially triggered by the existing Active Directory login script.

Typically the login script runs right away, and then terminates after the contents of the script have been completed. I needed to hold onto that ability to run command(s) at a specific time later on, so I needed to keep the script “awake” long after the user had logged on. The first problem I ran into here was that the login script was visible to the users when I put a sleep task in there. We definitely didn’t want to have a little minimized CMD window showing to them. After some digging around, I found a way to get around that. There’s a little thought in my mind that there may be a better way to do the same thing, but for this first attempt, here is how I got around that…

Instead of a typical one or two file login script (two for using a batch file to call a PowerShell file), I set out to use five files (yes five, I know) to make up the login script. But there’s a good reason. Here is why each file exists…

  • loginScript.bat, This is the first file called, this is the file specified in the AD user’s “scriptPath” attribute. There’s nothing in here except a WScript call.
  • loginScriptInv.vbs, This file is called by the first file, it just creates a new WScript shell and in turn calls the next file.
  • loginScriptInv.bat, This is the actual login script file that normally would have been in the “scriptPath” attribute. This one is calling PowerShell.exe with the next file as the argument.
  • loginScript.ps1, This is the actual “meat and potatoes” of the login script, doing everything from drive mappings to other preferred tasks. But with one exception…
  • loginScriptDotSource.ps1, This file is re-imported each time the heartbeat time threshold is reached. Commands in here can be changed as needed / met by logic as the deadline gets closer.


The first two files only exist to make the traditional login script invisible to the user. The third file exists only to call PowerShell. The fourth file is the actual login script. The fifth file gives the flexibility to make changes to the actual script along the way.

Why would I want to make changes along the way? Here are a few things that I found useful…

  • Ability to speed up or slow down the frequency that phoning home users would continue to check in, such as ramping up the frequency to minutes-not-hours the day of the desired change, using a $lsSleepTimer variable.
  • Ability to end all the connections if desired, using a $lsContinue variable.
  • Ability to widen the computer/user audience to certain actions after they had already logged in, using functions within that dot sourced file.


Now, let’s revisit those request details and verify that each one is being accomplished…

  • need to change the desktop wallpaper for all of the PC users across all locations, to a new to-be provided custom image.

The dot source file is copying the file to the workstations ahead of time, day(s) before the actual change time, and is then making the changes when needed.

  • need to make this change to everyone at the same local time, using their local office working hours.

On the day of, the heartbeat is set to be every 5 minutes. All the computers will be able to perform the change within 5 minutes of each other. Afterwards the heartbeat is set back up to 1 hour.

  • need to ensure the change occurs even if the users don’t log into their computers that day (meaning if they stay logged in from a previous day).

User’s that logged in day(s) earlier without logging back out again are still phoning home, ensuring a successful wallpaper change on the desired time.

  • need to avoid applying the change early for anyone, as the changes were part of a surprise campaign.

PowerShell is ensuring that the timestamp of each heartbeat is being used to actually apply the wallpaper. No early previews here, except for test users!

  • need to avoid any resource bottlenecks, such as having all computers copy down the solution files at the same time / at time of execution.

Wallpapers are copied gradually by the different computers. On the day of the action, all the heavy lifting was already done.

  • need to do this within the next week (short notice given for project to be performed).

This luckily worked out very well. The “bones” of the project were put up quickly, while the actual wallpaper logic in the dot sourced file was figured out (and added) later on. 


This ended up to be a pretty fun and successful project, and I’m finding other uses for it afterwards. If you may find it useful let me now, or if there’s some glaring oversight and much simpler way to do the same thing also (please) let me know.  :-)

The files I've uploaded related to this project are on my GitHub section, the URL being: https://github.com/gregbesso/PerpetualLogonScript

1
1,690 Views
Greg BessoLead Systems Engineer
CERTIFIED EXPERT
Continually learning and practicing with Microsoft technology solutions to make positive impacts in user productivity.

Comments (1)

Albert WidjajaIT Professional
CERTIFIED EXPERT

Commented:
Many thanks for the sharing here Greg.
Let us for future update.

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.