Video Screencast Help
Symantec to Separate Into Two Focused, Industry-Leading Technology Companies. Learn more.

Shutdown Windows 7 with Message and Cancel Option for Logged on User

Created: 12 Mar 2012 • Updated: 12 Mar 2012 | 7 comments
Language Translations
mike_plichta's picture
+2 2 Votes
Login to vote

Shutdown computers with opt out message at a specific time.

Budget concerns are bringing out the energy committees to help reduce power consumption these days.  While windows has built in sleep and hibernate options, these settings cause some challenges in our environment.  Specifically we have lots and lots of public machines that need to have different staff members logging on to them all the time.  Putting a machine to sleep just locks it so that others cannot use it and that not mentioned the small percentage of machines that just don’t want to wake properly afterwords.  Thus we needed a method to shut down computers and give a half hour opt out message to anyone who might be using them.  Here’s how. 

Get a hold of Beyond Logic’s shutdown tool.  It says it’s only for XP but it works fine in Windows 7 provided that you run it in the logged on users context.  It’s the logged on users context that I’ve only been able to achieve with Altiris and cannot find a free 3rdparty tool capable of doing this. The whole reason I use this tool is that you can customize the message and it has a cancel (opt out) button unlike the built in shutdown.exe.  You could make your own using autoit or autohotkey with msgboxes and the shutdown.exe command but it’s more work.   http://retired.beyondlogic.org/solutions/shutdown/shutdown.htm

Create two tasks in your Altiris Console.  The first is a task to copy the BLShutdown.exe file to the local C drive of all your machines.  I tried using the built in copy task with Altiris, but kept getting failures when I tried to deploy it with a managed software delivery.  This is true even though I could just schedule the task outside of managed software delivery and it would run fine.  Thus, I used a script task to accomplish this. 

Make sure you click Advanced and run the job with an account that has local admin rights on the computer and can access the network share that you want to copy the file from. 

The second task actually runs BLshutdown.  This task must be run as the currently logged on user or the message will not display to them.

 

Note that the script window is hidden.  That’s so you don’t see a black command prompt window open to the user but they will still see the message box generated by BLShutdown.exe

 

Create the managed software delivery policies.

Navigate to Manage->Policies->Managed Software Policies in the console

Create a new policy

Add your two previously created tasks to the  policy

 

The key is in the schedule section.  Create a new scheduled time (repeat daily).  Make sure that the task is only set to run if the computer is available at the specified time.  Make sure you set it to only run if a user is logged on.

 

If all goes well, BLShutdown will copy itself and run at 5:30PM in my example and then ultimately shut down the computer at 6PM if a user does not click “cancel”. 

 

But what about machines with no logged on user?

For these machines you need another task of Altiris’ built in “shutdown with force programs to close”

Create a new managed software delivery task and set it’s schedule to only run if there is no user logged in. 

 

 

These machines need no warning or opt out message since there is nobody using them.

Comments 7 CommentsJump to latest comment

mike_plichta's picture

It seems that Altiris doesn't respect the option "A user is not logged on to the computer" so I used this VB script (written by someone else) to manually detect if someone is was logged on before shutting down.

 'Set error capture
On Error Resume Next

'Get local computer name
Set wshNetwork = WScript.CreateObject( "WScript.Network" )
strComputerName = wshNetwork.ComputerName
'strComputerName = "ComputerABC" 'For testing specific computer

'Setup WMI calling for logon name and shutdown assignment
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputerName & "\root\cimv2")

'Get currently logged on user's username
Set colComputer = objWMIService.ExecQuery _
    ("Select * from Win32_ComputerSystem")
For Each objComputer in colComputer
    If IsNull(objComputer.UserName) Then 'If no one is logged on
        strLoggedOn = "No"
    Else
        strLoggedOn = "Yes"
    End If
Next

'If no one is logged on shut down the computer
If strLoggedOn = "No" Then
    Set colComputer = objWMIService.ExecQuery _
        ("Select * from Win32_OperatingSystem")
    For Each objComputer in colComputer
        objComputer.Win32Shutdown(1)
    Next
End If 

I'll be checking what the "Computer is connected to network" box does.  I want it to not run the script if the Altiris NS server is unavailable so that administrator laptops are not shut down when admins are using them at home.  I suspect that a script with a ping command will be required. 

0
Login to vote
CBZ9104's picture

Hi mike

I done the steps which you saying copy shutdown.exe and trigger script its working fine 

but can we get report of the systems means how many systems are really shutdown or like that

0
Login to vote
mike_plichta's picture

I have since moved to a custom shutdown script compiled with autohotkey into an executable.  There is no reason that you couldn't add some lines to that package to append a log file if someone cancels the shutdown.  It could also send append the log before it actually initiates the shutdown as well if that's what you're looking for.  Here is the AHK code.  Save it to a shutdown.ahk file and once you install auto hotkey, you should have a right click option to compile it to an exe file.  The ifExist part is to make sure the computer is on site by looking for a network share.  We don't want machines turning off if they have been taken home and someone is working late there.

WinSetTitle, Energy Conservation Shutdown at 6PM

ifExist, \\server\share
  {
    Gui, font, s14
    Gui, -sysmenu
    Gui, Add, Text, W520 Center, To conserve energy, XXX has created a policy to turn off computers at the end of the day.`n`nClick Cancel to prevent the shutdown.
  Gui, Add, Button, GCancelShutdown x230,Cancel
    Gui, Show,,D204 Energy Conservation 6PM Shutdown
  
    SetTimer, ShutdownPC, -1800000
  }
    
return

ShutdownPC:
Shutdown, 5
ExitApp, 0

CancelShutdown:
ExitApp, 0

0
Login to vote
JimChud's picture

Nice article. Its exactly what i was going to start investigating in the next few weeks, definately saved me some time :)

Thanks

Regards Jim.
Connect Etiquette: "Mark as Solution" those posts which resolve your problem and give a thumbs up to useful comments, articles and downloads.

0
Login to vote
JimChud's picture

Hi Mike,

A note on the above article. i found it impossible to get the policy to run both steps (copy file and execute) when it ran from policy. it always ran the copy but the second step always didnt run. i found that it was related to the execute only when device is active.

The way i got around it was to remove the copy of the file from the policy and then added a software package to NS with the tool in which went in to my base software policies on the machines. Then changed the execute script to be if exist execute.

the next time the machine is restarted my base software policy will kick in and install the software its missing and then the following evening it should start running.

Regards
Jim

Regards Jim.
Connect Etiquette: "Mark as Solution" those posts which resolve your problem and give a thumbs up to useful comments, articles and downloads.

+1
Login to vote
mike_plichta's picture

These days I run this script because I found the SMP scheduling engine to be unreliable with out of date information about users being logged in or not.  The whole thing and runs as a task that is scheduled via Managed Software Delivery.  It is not a software package.  From JimChud's suggestion, you might want to schedule copying the required files separately, but that’s up to you.  Since these tasks generally run as the local system account, the share the files are copied from in my script has to allow “domain computers” to connect to the share with read-only access. 

From here, I just choose scheduled time and repeat daily, and “only if the computer is available at the specified time” in advanced.

This file is required so that the you can run the shutdown opt-out message as the logged on user and they can see it to click cancel.  http://software.bigfix.com/download/bes/util/RunAsCurrentUser-2.0.3.1.exe

The "Shutdown_when_user_logged_On.exe" file was created by me using Auto HotKey and the script for that is in the comments above.

Don't forget to replace the smart quotes with regular ones if you are copy/pasting from the web.

'Set error capture
On Error Resume Next

'check if domain is available.  Exit if computer is off site.
pingResult = Ping( "IPOFDOMAINCONTROLLER" )
if pingResult = "False" then 
  WScript.quit(0)
end if

'Get local computer name
Set wshNetwork = WScript.CreateObject( "WScript.Network" )
strComputerName = wshNetwork.ComputerName

'Setup WMI calling for logon name and shutdown assignment
SET WSHShell = CreateObject("WScript.Shell")
SET filesys=CreateObject("Scripting.FileSystemObject")
Set objWMIService = GetObject("winmgmts:" _
  & "{impersonationLevel=impersonate}!\\" & strComputerName & "\root\cimv2") 

'Get currently logged on user's username
Set colComputer = objWMIService.ExecQuery _
      ("Select * from Win32_ComputerSystem")

For Each objComputer in colComputer

  If IsNull(objComputer.UserName) Then 
    'no user logged on, shutdown now
    WSHShell.Run "C:\windows\system32\shutdown.exe /s /t 00"
    WScript.quit(0)
  
  Else
    'user is logged on, check for shutdown files
    
   if filesys.FolderExists("C:\tools") Then 
      strFolderPath = "c:\tools"
    else
      strFolderPath = "c:\tools64"
    end if

    if not filesys.FileExists(strFolderPath & "\RunAsCurrentUser.exe") then 
      filesys.CopyFile "\\server\share\Automation\AutoShutDown\RunAsCurrentUser-2.0.3.1.exe",strFolderPath & "\RunAsCurrentUser.exe",True
    end if

    if not filesys.FileExists(strFolderPath & "\shutdown_when_user_logged_on.exe") then 
      filesys.CopyFile "\\server\share\Automation\AutoShutDown\shutdown_when_user_logged_on.exe",strFolderPath & "\shutdown_when_user_logged_on.exe",True
    end if

    WSHShell.Run strFolderPath & "\RunAsCurrentUser.exe " & strFolderPath & "\shutdown_when_user_logged_on.exe"

  End if

NExt

Function Ping( myHostName )
' This function returns True if the specified host could be pinged.
' myHostName can be a computer name or IP address.
' The Win32_PingStatus class used in this function requires Windows XP or later.
' This function is based on the TestPing function in a sample script by Don Jones
' http://www.scriptinganswers.com/vault/computer%20m...

    ' Standard housekeeping
    Dim colPingResults, objPingResult, strQuery

    ' Define the WMI query
    strQuery = "SELECT * FROM Win32_PingStatus WHERE Address = '" & myHostName & "'"

    ' Run the WMI query
    Set colPingResults = GetObject("winmgmts://./root/cimv2").ExecQuery( strQuery )

    ' Translate the query results to either True or False
    For Each objPingResult In colPingResults
        If Not IsObject( objPingResult ) Then
            Ping = False
        ElseIf objPingResult.StatusCode = 0 Then
            Ping = True
        Else
            Ping = False
        End If
    Next

    Set colPingResults = Nothing
End Function

0
Login to vote
Krunal Solanki's picture

Hi all,

i would like to ask you that can we have a report for the same??

I am using these policy in my environment but still not able to fetch the report for the same.

0
Login to vote