This is a quick post to document a shutdown script that I have written to automatically shutdown a PC after a specified amount of time. This prompts the user to let them know and gives them the opportunity to cancel the shutdown. It utilises the AT scheduler (interactive mode) to schedule the task and can be deployed and updated via a group policy.
As with all of my scripts, this works for what I needed it but you should be sure to completely understand what other people scripts do before running them yourself.
' This script is designed to be deployed via group policy and
' ask the user whether it is OK to shutdown their PC, if there is
' no response, the script will shutdown the PC (it will assume that
' there is no one there after a timelimit specified by timeout.
'
' As the application is designed to be deployed via group policy and
' triggered using the AT scheduler in Windows XP SP 3, I have decided
' to use this script to write the AT command (if none found) and then
' write the file to be called by the scheduler in c:\shutdown.vbs.
' The file is rewritten every time this script is called to ensure that
' we can update the shutdown procedure if needed.
'
' Written with help from:
' http://blogs.technet.com/b/heyscriptingguy/archive/2005/03/14/how-can-i-automatically-dismiss-a-message-box-after-a-specified-length-of-time.aspx
' http://www.activexperts.com/activmonitor/windowsmanagement/adminscripts/taskscheduling/
' http://msdn.microsoft.com/en-us/library/windows/desktop/aa389389%28v=vs.85%29.aspx
' http://blogs.msdn.com/b/alejacma/archive/2008/03/04/how-to-get-the-logged-on-user-with-wmi-vbscript.aspx
'
' Modification History:
' 1/5/2012 AB Inception date
' 18/5/2012 AB Program has been modified to test for and (if necessary) create
' an AT (scheduled) job. As a result, the program now has to write
' the shutdown scripts to a file to be called by AT. The file
' is written *every* time to c:\shutdown.vbs. This means that any changes
' to this script will update the c:\shutdown.vbs file.
' 20/5/2012 AB Program modified to check if any user logged in. If not, then don't bother warning the user and
' dramatically shutdown the system
'
'
' To begin with, check if an AT job is already scheduled to run with
' c:\shutdown.vbs.
Set objShell=CreateObject("Wscript.Shell")
Set objFSO=CreateObject("Scripting.FileSystemObject")
Dim ATjob
ATjob=0
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colScheduledJobs = objWMIService.ExecQuery _
("Select * from Win32_ScheduledJob")
For Each objJob in colScheduledJobs
if objJob.Command="c:\shutdown.vbs" Then
' There is already a scheduled job, don't add another one.
' Here is where you would want to delete it if needed..
ATjob=1
end If
Next
If ATjob=0 Then
'Now, create a job if there isn't one with a name for c:\shutdown.vbs
'strComputer = "."
' Set objWMIService = GetObject("winmgmts:" _
' & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objNewJob = objWMIService.Get("Win32_ScheduledJob")
' http://msdn.microsoft.com/en-us/library/windows/desktop/aa389389%28v=vs.85%29.aspx
errJobCreated = objNewJob.Create _
("c:\shutdown.vbs", "********232800.000000+600", _
True, 64, , TRUE, JobID)
'("c:\shutdown.vbs", "********171000.000000+600", _
' True, 16, , TRUE, JobID)
' Wscript.Echo errJobCreated
End If
' Now, write the commands to a file in C:\shutdown.vbs
' My life for a HERE document convention in VBS
Set oFS=objFSO.CreateTextFile("c:\shutdown.vbs",TRUE)
oFS.writeLine("'DO NOT MODIFY THIS FILE")
oFS.writeLine("'It is written on each logon by GPO and local")
oFS.writeLine("'changes will NOT persist")
oFS.writeLine("Const wshYes=6")
oFS.writeLine("Const wshNo=7")
oFS.writeLine("' http://ss64.com/vb/popup.html")
oFS.writeLine("Const wshYesNoDialog=1")
oFS.writeLine("Const wshIcon=16")
oFS.writeLine("' Time before shutdown")
oFS.writeLine("Const timeout=600")
oFS.writeLine("")
oFS.writeLine("Set objShell=CreateObject(""Wscript.Shell"")")
oFS.writeLine("Set objFSO=CreateObject(""Scripting.FileSystemObject"")")
oFS.writeLine("strComputer = "".""")
oFS.writeLine("")
' From: http://blogs.msdn.com/b/alejacma/archive/2008/03/04/how-to-get-the-logged-on-user-with-wmi-vbscript.aspx
' The orig. script was awesome, I have modified it to simply test if a user is logged in (interactive session).
oFS.writeLine("' Connect to machine")
oFS.writeLine("Set objWMI = GetObject(""winmgmts:{impersonationLevel=impersonate}!\\"" & strComputer & ""\root\cimv2"")")
oFS.writeLine("' Get interactive session")
oFS.writeLine("Set colSessions = objWMI.ExecQuery _ ")
oFS.writeLine(" (""Select * from Win32_LogonSession Where LogonType = 2"")")
oFS.writeLine(" If colSessions.Count = 0 Then")
oFS.writeLine(" ' No interactive session found")
oFS.writeLine(" intResponse=1")
oFS.writeLine(" Else")
oFS.writeLine("intResponse=objShell.Popup(""This computer will shutdown in 10 minutes"" &vbcrlf &_")
oFS.writeLine("""unless you press cancel."" &vbcrlf & ""Pressing OK will shut this computer down immediately."" &vbcrlf&vbcrlf &_")
oFS.writeLine(" ""Please save all of your work now."", _")
oFS.writeLine(" timeout,""ALERT: Computer shutdown"",wshYesNoDialog + wshIcon)")
oFS.writeLine("' Wscript.Echo intResponse")
oFS.writeLine("End If")
oFS.writeLine("")
oFS.writeLine("' If the user confirms or does nothing, shutdown the PC.")
oFS.writeLine("if intResponse=1 OR intResponse=-1 Then")
oFS.writeLine("'http://www.activexperts.com/activmonitor/windowsmanagement/adminscripts/computermanagement/startup/")
oFS.writeLine("Set colOperatingSystems = GetObject(""winmgmts:{(Shutdown)}"").ExecQuery(""Select * from Win32_OperatingSystem"")")
oFS.writeLine(" For Each objOperatingSystem in colOperatingSystems")
oFS.writeLine(" ObjOperatingSystem.Win32Shutdown(1)")
oFS.writeLine(" Next")
oFS.writeLine("End if")