Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Remote shutdown of all computers in AD 1

Status
Not open for further replies.

bwgreen

Programmer
Mar 23, 2006
68
CA
I have been given the task of creating a script that will shut down all of our Windows workstations remotely. I have doen some searching on this and found that it can be done through a method in WMI, but where I am stuck is getting the computer names. I would like to retrieve them from Active Directory to always get a current list, regardless of where or when the script is run. I would also like to filter out servers, and the workstation the administrator is logged in to. I have been doing programming for a while, but VBScript is new to me - I'm sure this can be done, just not sure exactly how to do it!

Thanks for any help,

Brian
 
Hi, please use this with care. It is untested, but should put you in the right direction.
Code:
dim AD_RS
dim AD_objConn


open_ad
AD_RS.movefirst
do until AD_RS.eof
	
hostname = AD_RS("hostname")
	onlinestat = getping(hostname)
	if onlinestat = 1 then
		restart(hostname)
	else
	end if
	rs.movenext
	
loop
AD_RS.close
AD_objConn.close


'-------------------------------------------------------------------------------------------------------------------------------    
'	get the hostnames from AD
'-------------------------------------------------------------------------------------------------------------------------------    

sub open_ad
	Const ADS_SCOPE_SUBTREE = 2
	Set AD_objConn = CreateObject("ADODB.Connection")
	Set objCommand =   CreateObject("ADODB.Command")
	AD_objConn.Provider = "ADsDSOObject"
	AD_objConn.Open "Active Directory Provider"

	Set objCOmmand.ActiveConnection = AD_objConn
	objCommand.CommandText = "Select Name from 'LDAP://DC=yourDCName,DC=xxx' Where objectClass='computer'"
	objCommand.Properties("Page Size") = 1000
	objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 
	Set AD_RS = objCommand.Execute
end sub



'-------------------------------------------------------------------------------------------------------------------------------    
'	restart a computer
'-------------------------------------------------------------------------------------------------------------------------------    
sub restart(hostname)

	Set OpSysSet = GetObject("winmgmts:{impersonationLevel=impersonate,(RemoteShutdown)}!\\" & hostname & "\root\cimv2") &_
							.ExecQuery("select * from Win32_OperatingSystem where Primary=true")
	for each OpSys in OpSysSet
		OpSys.Reboot()
	next

end sub

'-------------------------------------------------------------------------------------------------------------------------------
'	check if online
'-------------------------------------------------------------------------------------------------------------------------------
Function getping(sys_name)
	Set objPing = 	GetObject("winmgmts:{impersonationLevel=impersonate}")_
					.ExecQuery("select * from Win32_PingStatus where address = '"& sys_name & "'")
	For Each objStatus in objPing
		If IsNull(objStatus.StatusCode) or objStatus.StatusCode <> 0 Then 
			getping = 0
		Else
			getping = 1
		End If
	Next

End function

Hope I could be of assistance
Regards
Thomas
 
Thanks Dollinger - I've tried this, but hit a snag - it seems the Select Name from 'LDAP:DC=... statement is having problems. I am getting an error on the ojbCommand.Execute statement telling me that Table Does Not Exist. Am I using the query right - for the first DC= option I have the name of the computer that AD is running on, and for the second I have xxx like you put in the script. I haven't used an LDAP query like this before so I am not sure what it is looking for - any help is appreciated!

Thanks!
 
The following script will reboot workstations from a list of computers. If you don't want to reboot but actually shut down, then replace [red]OpSys.Reboot[/red] with [red]OpSys.Shutdown[/red]

Code:
'==========================================================================
'
' NAME: RebootWSfromList.vbs
'
' AUTHOR: Mark D. MacLachlan , The Spider's Parlor
' URL: [URL unfurl="true"]http://www.thespidersparlor.com[/URL]
' DATE  : 7/6/2004
'
' COMMENT: <comment>
'
'==========================================================================

On Error Resume Next

'open the file system object
Set oFSO = CreateObject("Scripting.FileSystemObject")
set WSHShell = wscript.createObject("wscript.shell")
'open the data file
Set oTextStream = oFSO.OpenTextFile("wslist.txt")
'make an array from the data file
RemotePC = Split(oTextStream.ReadAll, vbNewLine)
'close the data file
oTextStream.Close
For Each strComputer In RemotePC
	Set OpSysSet = GetObject("winmgmts:{impersonationLevel=impersonate,(RemoteShutdown)}//" & strComputer).ExecQuery("select * from Win32_OperatingSystem where Primary=true")
		for each OpSys in OpSysSet
			OpSys.Reboot()
 		next
Next

You can generate the needed WSLIST file with the script found in my FAQ faq329-4871.

I suggest using this method so you can examine the list and be sure no servers are in the list.

I hope you find this post helpful.

Regards,

Mark
 
Or

Code:
strDomain = "Your Domain"
strGroup = "Clients" 'could be any name of group
Set objGroup = GetObject("WinNT://" & strDomain & "/" & strGroup & ",group")
objGroup.Filter = Array("Computer") 'Never put a server in same Container as a computer !?

For Each objMember in objGroup.Members
    Call Reboot(objMember.Name)
Next

Sub Reboot(strComputer)

Set OpSysSet = GetObject("winmgmts:{impersonationLevel=impersonate,(RemoteShutdown)}//" & strComputer).ExecQuery("select * from Win32_OperatingSystem where Primary=true")
    For Each OpSys in OpSysSet
        OpSys.Reboot()
    Next
End Sub
 
OK - now I am hitting a strange thing. When I run the script it gives an error on the line hostname=AD_RS("hostname") - it says "Item cannot be found in the collection corresponding to the requested name or control". I've tried using single quotes and no quotes - they result in compilation errors.

Help!

Thanks,

Brian
 
Never mind - should have used ("name") instead - works great now!

Thanks,

Brian
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top