Many organizations use logon scripts for their users. Those scripts map network drives, install software utilities, and much more. But have you ever considered writing a logon script that applies to your servers? There are numerous reasons why you might want to do so, including tracking administrator activities, mapping specialized network drives, running utilities that display server information on the desktop wallpaper, and so forth. So how do you go about doing it, and what might your logon script include?


Startup = Computer, Logon = User


You’re doubtless aware that Windows supports two different kinds of “get started” script. Startup scripts apply to all users of a particular computer, are executed by the computer, and execute prior to a user logging on. That means they’re not useful for certain tasks, such as mapping drives, since there’s nowhere for the mapped drive to live at the time they’re run. Logon scripts apply to users, and of course do all of the neat things you’re used to.

These scripts are assigned by a Group Policy object (GPO), and therein lies the opportunity for server-specific scripts. While a logon script executes for the user, it gets assigned to that user based on the location of the GPO, and on the location of the computer and user objects within Active Directory. For example, suppose I have a set of servers contained within an organizational unit (OU) named, appropriately enough, “Servers.” I can create a GPO that includes a logon script, link it to the “Servers” OU, and that logon script will run whenever a user logs on to one of those servers. Voila, a “server-specific” logon script.


PowerShell or VBScript?


Old-school logon scripts were written in VBScript; Windows PowerShell is now an option. There are some pre-requisites to making PowerShell logon scripts possible, but they’re well worth the effort:

  • You need PowerShell v2 installed. This comes free and pre-installed with Windows 7 and Windows Server 2008 R2; on anything older, download it online.
  • You also need the Win2008R2 GPO templates. Get these from the Windows 7 Remote Server Administration Toolkit (RSAT), and just copy them to all of your domain controllers. These new templates contain settings to assign PowerShell logon scripts.
  • PowerShell requires .NET Framework v2 at a minimum, and prefers v3.51 SP 1 for maximum functionality.


If you’re not yet comfortable with PowerShell, it’s a good time to start. VBScript is eventually going to go away, and any new effort should be in PowerShell for maximum longevity. If you’re still using something else for logon scripts, such as KiXtart, get with the program: PowerShell is the way forward. It even works on Server Core (R2 and later).


Figure 1 – PowerShell Logon Script Setup for GPOs



Logon Script Tasks


Thinking about logon scripts for servers, as opposed to regular users, requires a bit of imagination. Think about what you do on your servers, what problems you’ve run into in the past, and use the logon script to try and solve those challenges. Here are some ideas.


Why Are You Logging On?


One of the first tasks I thought to put into a server logon script was a “why are you here?” log. I’ve always found it amusing that recent versions of Windows ask you why a server was rebooted, but they don’t bother asking why someone is logging onto the console. Back in my AS/400 days, logging on with a privileged account always generated some kind of prompt, asking you what you planned to do, and logging that information someplace. In Windows PowerShell, this is pretty easy to do.


$reason = Read-Host "Enter brief reason for server console access" Write-EventLog –logname Security –source LogonScript ` –eventID 30001 –entrytype Information –message $reason


This will write the reason directly to the server’s Security log, where you could forward it (if you’re using event log forwarding) to a central log for safekeeping. Other options would include writing it to a central SQL Server database that was set up for this purpose. Of course, if you’re using a third-party auditing package, it can pick up those events from the native log and forward them to a central database for you.


Mapping Drives


Server management often requires access to a shared drive. For example, you might store a repository of scripts or PowerShell modules on a file server, and want access to those from server consoles. Or, you might have a central “drop box” shared folder where admins can move files between servers. While accessing those via UNC should be well within your capabilities, a mapped drive can still provide a convenient shortcut.


Within PowerShell, the New-PSDrive cmdlet might seem to be what you want – and it’ll certainly work if all you want to do is access a remote location from within PowerShell. To map a new drive named REMOTE:


New-PSDrive –Name REMOTE –psprovider FileSystem –root \\server\share\whatever


However, this won’t create a drive that survives when you close PowerShell, nor will it create a drive accessible from Explorer and other applications. I’ve seen administrators struggle with mapping “normal” drives in PowerShell, mainly because they’re overthinking it. There isn’t a “PowerShell” way to do so because there’s already a perfectly-serviceable command-line way of accomplishing this task – and it works great from within PowerShell:


Net use z: \\server\share\whatever


Easy, right? The same way you always used to do it from Cmd.exe still works.


Running Utilities


In fact, nearly any command-line utility can be run in this fashion. Run BgInfo.exe (one of the System Internals tools) to update the server’s desktop wallpaper with its name, IP address, and other important information (this is super-helpful when using Remote Desktop to access the server, since it makes it very clear which server you’re on).


Write Info to a Database


Why not update a central database with the server’s pertinent information, the user name of the last person to log on, and so forth? This presumes that you have a SQL Server 2008 computer named SQLSERVER on your network, and that it’s already been set up with a SYSINFO database containing a SERVERS table – and that the table has the columns referenced below. It also assumes that your user account has read/write permissions to the table.



Figure 2 – PowerShell Logon script for tracking login info


$os = Get-WmiInfo Win32_OperatingSystem ↵
[assembly.reflection]::loadwithpartialname('System.Data') ↵
$conn = New-Object System.Data.SqlClient.SqlConnection↵
$conn.ConnectionString = "Data Source=SQLSERVER;Initial Catalog=SYSINFO;Integrated Security=SSPI;" ↵
$cmd = New-Object System.Data.SqlClient.SqlCommand↵
$cmd.connection = $conn↵
$cmd.commandtext = "INSERT INTO servers (servername,username,spversion) VALUES('{0}','{1}','{2}')" -f


Excuse the word-wrapping on that! It’ll look better if you type it into the PowerShell ISE. I’ve added a ↵ symbol so you know where to hit Enter. This will work well if the SERVERS table has a fourth column that automatically fills in the current date and time as a default value – that way you’ll have a complete logon record. Of course, you could add other information as needed to this technique.


Lockdown, Manageability, and More


This really just scratches the surface of what a server-specific logon script might do. You could also lock down the server’s desktop and perform other tasks. In fact, if you’re using a third-party lockdown toolset, that toolset might well have server-specific applications as well. Such tools might help deploy software, map printers, set up shortcuts, lock down I/O ports, and so forth. While those all have obvious use in the desktop world, if you get creative you’ll also find applications on the server consoles as well.

Want more related guidance? Try downloading our free Windows PowerShell Commands and then take a look at the latest consolidate management options.

Related Content