How can I shutdown a computer using different computer?
Printable View
How can I shutdown a computer using different computer?
Use InitiateSystemShutdown API Call
VB Code:
Option Explicit Private Type LARGE_INTEGER LowPart As Long HighPart As Long End Type Private Type LUID LowPart As Long HighPart As Long End Type Private Type LUID_AND_ATTRIBUTES pLuid As LUID Attributes As Long End Type Private Type TOKEN_PRIVILEGES PrivilegeCount As Long Privileges(0 To 0) As LUID_AND_ATTRIBUTES End Type Private Declare Function GetCurrentProcess Lib "kernel32" () As Long Private Declare Function OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As Long Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long Private Declare Function GetTokenInformation Lib "advapi32.dll" (ByVal TokenHandle As Long, TokenInformationClass As Integer, TokenInformation As Any, ByVal TokenInformationLength As Long, ReturnLength As Long) As Long Private Declare Function AdjustTokenPrivileges Lib "advapi32.dll" (ByVal TokenHandle As Long, ByVal DisableAllPrivileges As Long, NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Long, PreviousState As TOKEN_PRIVILEGES, ReturnLength As Long) As Long Private Declare Function LookupPrivilegeValue Lib "advapi32.dll" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, lpLuid As LUID) As Long Private Const SE_SHUTDOWN_NAME As String = "SeShutdownPrivilege" Private Const SE_PRIVILEGE_ENABLED = &H2 Private Const READ_CONTROL = &H20000 Private Const STANDARD_RIGHTS_ALL = &H1F0000 Private Const STANDARD_RIGHTS_EXECUTE = (READ_CONTROL) Private Const STANDARD_RIGHTS_READ = (READ_CONTROL) Private Const STANDARD_RIGHTS_REQUIRED = &HF0000 Private Const STANDARD_RIGHTS_WRITE = (READ_CONTROL) Private Const TOKEN_ASSIGN_PRIMARY = &H1 Private Const TOKEN_DUPLICATE = (&H2) Private Const TOKEN_IMPERSONATE = (&H4) Private Const TOKEN_QUERY = (&H8) Private Const TOKEN_QUERY_SOURCE = (&H10) Private Const TOKEN_ADJUST_PRIVILEGES = (&H20) Private Const TOKEN_ADJUST_GROUPS = (&H40) Private Const TOKEN_ADJUST_DEFAULT = (&H80) Private Const TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or TOKEN_ASSIGN_PRIMARY Or TOKEN_DUPLICATE Or TOKEN_IMPERSONATE Or TOKEN_QUERY Or _ TOKEN_QUERY_SOURCE Or TOKEN_ADJUST_PRIVILEGES Or TOKEN_ADJUST_GROUPS Or TOKEN_ADJUST_DEFAULT) Private Const TOKEN_READ = (STANDARD_RIGHTS_READ Or TOKEN_QUERY) Private Const TOKEN_WRITE = (STANDARD_RIGHTS_WRITE Or TOKEN_ADJUST_PRIVILEGES Or TOKEN_ADJUST_GROUPS Or TOKEN_ADJUST_DEFAULT) Private Const TOKEN_EXECUTE = (STANDARD_RIGHTS_EXECUTE) Private Const TokenDefaultDacl = 6, TokenGroups = 2 Private Const TokenImpersonationLevel = 9, TokenOwner = 4 Private Const TokenPrimaryGroup = 5, TokenPrivileges = 3 Private Const TokenSource = 7, TokenStatistics = 10 Private Const TokenType = 8, TokenUser = 1 Private Declare Function InitiateSystemShutdown Lib "advapi32.dll" Alias "InitiateSystemShutdownA" (ByVal lpMachineName As String, ByVal lpMessage As String, ByVal dwTimeout As Long, ByVal bForceAppsClosed As Long, ByVal bRebootAfterShutdown As Long) As Long Private Declare Function AbortSystemShutdown Lib "advapi32.dll" Alias "AbortSystemShutdownA" (ByVal lpMachineName As String) As Long 'Purpose : Starts a timed remote shut down 'Inputs : sMachineNetworkName The name of the network machine. If sMachineNetworkName ' is an empty string the function shuts down the local computer ' lTimeOut The time in seconds to display the shutdown dialog. While this ' dialog box is displayed, the shutdown can be stopped by the ShutDownAbort function ' sMessageTitle The message sent to the remote machine during the shutdown ' bForceAppsToClose Specifies whether applications with unsaved changes are to be forcibly closed. ' If this parameter is TRUE, such applications are closed. If this parameter is FALSE, ' a dialog box is displayed prompting the user to close the applications ' bReboot Specifies whether the computer is to restart immediately after shutting down. ' If this parameter is TRUE, the computer is to restart. If this parameter is FALSE, ' the system flushes all caches to disk, clears the screen, and displays a message ' indicating that it is safe to power down. 'Notes : To shut down the local computer, the calling process must have the SE_SHUTDOWN_NAME privilege. To shut down a remote computer, ' the calling process must have the SE_REMOTE_SHUTDOWN_NAME privilege on the remote computer. By default, users can enable the ' SE_SHUTDOWN_NAME privilege on the computer they are logged onto, and administrators can enable the SE_REMOTE_SHUTDOWN_NAME privilege on remote computers. Public Function ShutDownTimedBegin(sMachineNetworkName As String, Optional ByVal lTimeOut As Long = 60, Optional ByVal sMessageTitle As String = "Your Machine is going to be Shutdown", Optional ByVal bForceAppsToClose As Boolean = False, Optional ByVal bReboot As Boolean = True) As Boolean Dim lRet As Long On Error Resume Next 'Make sure we have enabled the privilege to shutdown 'for this process If zEnableShutDown(sMessageTitle) = True Then 'carry out timed shutdown lRet = InitiateSystemShutdown(sMachineNetworkName, sMessageTitle, lTimeOut, bForceAppsToClose, bReboot) If lRet Then 'Succeeded ShutDownTimedBegin = True Else 'Failed ShutDownTimedBegin = False End If Else 'Failed ShutDownTimedBegin = False End If On Error GoTo 0 End Function 'Purpose : Aborts a shut down process 'Inputs : sMachineNetworkName The name of the network machine Public Function ShutDownAbort(ByVal sMachineNetworkName As String) As Long ShutDownAbort = AbortSystemShutdown(sMachineNetworkName) End Function Private Function zEnableShutDown(ByRef sMsg As String) As Boolean Dim tLUID As LUID Dim hProcess As Long Dim hToken As Long Dim tTP As TOKEN_PRIVILEGES, tTPOld As TOKEN_PRIVILEGES Dim lTpOld As Long Dim lR As Long 'Under NT we must enable the SE_SHUTDOWN_NAME privilege in the 'process we're trying to shutdown from, otherwise a call to 'try to shutdown has no effect 'Find the LUID of the Shutdown privilege token lR = LookupPrivilegeValue(vbNullString, SE_SHUTDOWN_NAME, tLUID) If (lR <> 0) Then 'Get the current process handle hProcess = GetCurrentProcess If (hProcess <> 0) Then 'Open the token for adjusting and querying (if we can - user may not have rights) lR = OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, hToken) If (lR <> 0) Then 'Adjust the shutdown priviledges With tTP .PrivilegeCount = 1 With .Privileges(0) .Attributes = SE_PRIVILEGE_ENABLED .pLuid.HighPart = tLUID.HighPart .pLuid.LowPart = tLUID.LowPart End With End With 'Now allow this process to shutdown the system lR = AdjustTokenPrivileges(hToken, 0, tTP, Len(tTP), tTPOld, lTpOld) If (lR <> 0) Then zEnableShutDown = True Else 'You do not have the privileges to shutdown this system zEnableShutDown = False End If CloseHandle hToken Else 'You do not have the privileges to shutdown this system zEnableShutDown = False End If Else 'Can't enable shutdown (Can't determine the current process) zEnableShutDown = False End If Else 'Can't enable shutdown (Can't find the SE_SHUTDOWN_NAME privilege value) zEnableShutDown = False End If End Function
Gee, isn't that a bit of an overkill?
How about this?
Option Explicit
Public gobjWshShell
Sub ScriptInit()
Set gobjWshShell = CreateObject("WScript.Shell")
'WScript.Echo "Inside the Init subroutine."
End Sub
Function Sleep(lintNumOfSeconds, lblnUseMilliseconds)
' Put False as the second argument to use standard seconds.
' Put True to use milliseconds.
If lblnUseMilliseconds = False Then
lintNumOfSeconds = lintNumOfSeconds * 1000
End If
WScript.Sleep lintNumOfSeconds
End Function
Sub ShutDown(lintShutdownType)
Dim strComputer
Dim OpSys
Dim OpSysSet
strComputer = "."
If lintShutDownType = "" then
lintShutDownType = 4
End If
Set OpSysSet = GetObject("winmgmts:{(Debug,Shutdown)}//" & strComputer & "/root/cimv2").ExecQuery("select * from Win32_OperatingSystem where Primary=true")
For Each OpSys in OpSysSet
OpSys.win32Shutdown(lintShutdownType)
Next
' The numbers in the Decimal column are for the lintShutDownType variable.
' Action Decimal Binary
' Logoff 0 0000
' Reboot 2 0010
' Force Logoff 4 0100
' Force Reboot 6 0110
' Powerdown 8 1000
' Force Powerdown 12 1100
End Sub
Sub RunFor30()
'WScript.Echo "Inside the RunFor30 subroutine."
On Error Resume Next
Dim lblnIsDone
Dim lintNumMinutes
lintNumMinutes = 0
Do
lblnIsDone = False
Sleep 5, False
lintNumMinutes = lintNumMinutes + 1
'WScript.Echo "lintNumMinutes = " & lintNumMinutes
Select Case lintNumMinutes
Case 2
gobjWshShell.Popup "Attention!! " & vbCrLf & vbCrLf & "This workstation will be logged off in 15 seconds!" & vbCrLf & "AHLTA Version 2.1.837.4 has been detected and must be upgraded to version 2.1.837.9." & vbCrLf & "Please call the Helpdesk at 7-9966." & vbCrLf & vbCrLf & "This box will close in 15 seconds.", 15, "Logoff Warning", vbExclamation + vbOKOnly + vbSystemModal
Case 5
lblnIsDone = True
ShutDown 4
'WScript.Echo "Shutdown would have occurred here ... click OK button to continue."
Case Else
' Do nothing
End Select
Loop Until lblnIsDone = True
End Sub
' Processing starts here
ScriptInit
RunFor30
WScript.Quit
if you have admin rights on the system
considering shelling shutdown.exe
Code:Usage: shutdown.exe [-i | -l | -s | -r | -a] [-f] [-m \\computername] [-t xx] -c "comment"] [-d up:xx:yy]
No args Display this message (same as -?)
-i Display GUI interface, must be the first option
-l Log off (cannot be used with -m option)
-s Shutdown the computer
-r Shutdown and restart the computer
-a Abort a system shutdown
-m \\computername Remote computer to shutdown/restart/abort
-t xx Set timeout for shutdown to xx seconds
-c "comment" Shutdown comment (maximum of 127 characters)
-f Forces running applications to close without warning
-d [u][p]:xx:yy The reason code for the shutdown
u is the user code
p is a planned shutdown code
xx is the major reason code (positive integer less than 256)
yy is the minor reason code (positive integer less than 65536)
I admit you don't need all that code but it ensures you have all the correct token priveliges.
Wolfess's code is ok providing you have wmi scripting and admin rights for wmi on the remote machine.
The shutdown.exe method is easiest but some people might not want to use it in certain circumstances and would raher write their own