Jump to content

Shutdown Script


Recommended Posts

Guest monkeyx
Posted (edited)

I wrote this vbscript to help with an agrument between staff at another school about who should shut down PC's!

 

Also helps with your green credentials, can be useful to run via scheduled task to shutdown at a certain time.

 

Once you point the script at an OU it will enumerate all OUs and shutdown all machines, so make sure you point at write OU :) Also an example of a script that can run against all computers in OU and sub OUs.

 

This script works on a couple of domains I have tested it on, but had to remove references and make generic for public release. If you are interested could you runthe script and let me know how it works or doesn't :)

 

'***************************************************************************************
' Shutdown Script written by [email protected]
' Before running, set strDomain to your domain and strOU
' Create Reference to Wshell object for running command line programs
' Also creates a text file for logging in same folder script is run.
'***************************************************************************************
Set WSHShell = WScript.CreateObject("WScript.Shell")
Set FSO = CreateObject("Scripting.FileSystemObject")
Set logFile = FSO.CreateTextFile("logfile.txt", True)

'***************************************************************************************
' Create Reference for OU to be enumertated
'***************************************************************************************
' Point at top level OU to shutdown all machines in an OU and sub OUs
strOU = "ou=Level 1,ou=toplevel" 
'***************************************************************************************
' Create Reference to OU Domain
'***************************************************************************************
strDomain = "yourdomain.local" 
shutdownMessage="""End of day power down. Please save your work within 5 minutes to prevent data loss"""

'***************************************************************************************
' Connect to Domain using default Naming Contect
'***************************************************************************************
set objRootDSE = GetObject("LDAP://" & strDomain & "/RootDSE")
set objParent = GetObject("LDAP://" & strOU & "," & objRootDSE.Get("defaultNamingContext"))

Call ouTree(objParent)
logFile.Close

Function ouTree(objParent)
'***************************************************************************************
' Enumerate All Computer Objects in selected OU
'***************************************************************************************
'objParent.Filter = Array("computer")
objParent.Filter = Array("OrganizationalUnit")
for each objChild in objParent	
'Wscript.Echo "Processing OU " & objChild.Get("Name") & objChild.Name 
logfile.WriteLine ("Processing OU " & objChild.Get("Name") & objChild.Name)
ouComp(objChild)
ouTree (objChild)
next
End Function

Function ouComp(objChild)
For each objUser in objChild
If objUser.class="computer" then
select case ucase(objUser.Get("Name"))
	'***************************************************************************************
	' List Machines not to shutdown when find in OUs
	'**************************************************************************************
	Case  "COMP1","COMP2","COMP3","COMP4","ETC"
		'Wscript.Echo "Will not Shutdown " & objUser.Get("Name")
		logfile.WriteLine ("Will not Shutdown " & objUser.Get("Name") & " " & Now)
	Case Else
		'***************************************************************************************
		' run command prompt options /c closes after run 1,True shows command 0,True Hides command
		'**************************************************************************************
		'Wscript.Echo "Will now try and Shutdown " & objUser.Get("Name") 
		logfile.WriteLine ("Will now try and Shutdown " & objUser.Get("Name") & " " & Now)
		'***************************************************************************************
		' Shutdown Options /f force log off /t 1200 is 20 minute warning
		'**************************************************************************************
'			ShellRun = WSHShell.Run ("cmd /c shutdown /f /s /m \\" & objUser.Get("Name") & " /t 240 /c " & shutdownMessage,0,True ) 
end select

End If
next
End Function

Edited by monkeyx
minor typo in script
  • 3 weeks later...
Guest monkeyx
Posted (edited)

Tried to edit old version, but unable todo so. This new version attempts to ping a machine before shutting it down, as it speeds up the process.

 

'***************************************************************************************
' Shutdown Script written by [email protected]
' Before running, set strDomain to your domain and strOU
' Create Reference to Wshell object for running command line programs
' Also creates a text file for logging in same folder script is run.
'***************************************************************************************
Set WSHShell = WScript.CreateObject("WScript.Shell")
Set FSO = CreateObject("Scripting.FileSystemObject")
Set logFile = FSO.CreateTextFile("logfile.txt", True)
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
'***************************************************************************************
' Create Reference for OU to be enumertated
'***************************************************************************************
' Point at top level OU to shutdown all machines in an OU and sub OUs
strOU = "ou=Level 1,ou=toplevel" 
'***************************************************************************************
' Create Reference to OU Domain
'***************************************************************************************
strDomain = "yourdomain.local" 
shutdownMessage="""End of day power down. Please save your work within 5 minutes to prevent data loss"""

'***************************************************************************************
' Connect to Domain using default Naming Contect
'***************************************************************************************
set objRootDSE = GetObject("LDAP://" & strDomain & "/RootDSE")
set objParent = GetObject("LDAP://" & strOU & "," & objRootDSE.Get("defaultNamingContext"))
'Process computers in first level of OU.
objParent.Filter = Array("computer")
Call ouComp(objParent)
Call ouTree(objParent)
logFile.Close

Function ouTree(objParent)
'***************************************************************************************
' Enumerate All Computer Objects in selected OU
'***************************************************************************************
objParent.Filter = Array("OrganizationalUnit")
for each objChild in objParent	
'Wscript.Echo "Processing OU " & objChild.Get("Name") & objChild.Name 
logfile.WriteLine ("Processing OU " & objChild.Get("Name") & objChild.Name)
ouComp(objChild)
ouTree (objChild)
next
End Function

Function ouComp(objChild)
For each objUser in objChild
If objUser.class="computer" then
select case ucase(objUser.Get("Name"))
	'***************************************************************************************
	' List Machines not to shutdown when find in OUs
	'**************************************************************************************
	Case  "COMP1","COMP2","COMP3","COMP4","ETC"
		'Wscript.Echo "Will not Shutdown " & objUser.Get("Name")
		logfile.WriteLine ("Will not Shutdown " & objUser.Get("Name") & " " & Now)
	Case Else
	Set colItems = objWMIService.ExecQuery _
	    ("Select * from Win32_PingStatus " & _
	    "Where Address = '" & objUser.Get("Name") & "'")
		For Each objItem in colItems
		    If objItem.StatusCode = 0 Then 
    			'Wscript.Echo "Will now try and Shutdown " & objUser.Get("Name") 
			logfile.WriteLine ("Will now try and Shutdown " & objUser.Get("Name") & " " & Now)
			'***************************************************************************************
			' run command prompt options /c closes after run 1,True shows command 0,True Hides command
			'**************************************************************************************
			ShellRun = WSHShell.Run ("cmd /c shutdown /f /s /m \\" & objUser.Get("Name") & " /t 240 /c " & shutdownMessage,0,True ) 
		    End If
		Next			
end select

End If
next
End Function

Edited by monkeyx
Add extra functions
Posted

Yes it would be intresting if it worked as at the moment we have a shutdown script that has all the machine names in - so if they have been rebuilt with new names we have to manually edit the script.

 

This is a lot better because from what I can see in the posts above it checks the AD for machines.

 

GJE

Posted
Yes Shtdowatron looks good. I had a quick look at the instructions and wasn't clear about something. If you do not want the local client config settings do you have to install the client. If you do the script method is obviously more efficient as it doesn't require a client residing on the machine.
Posted
Yes Shtdowatron looks good. I had a quick look at the instructions and wasn't clear about something. If you do not want the local client config settings do you have to install the client.

 

Yes (because the point of it is decentralisation), just don't include the optional local config tool, or leave its default of install-on-demand.

 

 

If you do the script method is obviously more efficient as it doesn't require a client residing on the machine.

 

Depends on how you define 'more efficient'.

Posted (edited)
Depends on how you define 'more efficient'.

 

I thought networks were all about centralised management. But my view is if you need one less piece of software pushed out and one less service or program running on a machine the better.

 

But still shutdownatron does look good and may give it a try. We currently use the scripting method with a list of machines.

Edited by jsnetman
Posted

We wrote a multi purpose system here. Every time anyone logs in it gets logged in an SQL server with the PC details/username/time etc. The trick is to store the MAC addresses etc as well for startup scripts.

 

Then each of us has a console to view the logins etc. We can use the console to shutdown/restart PCs or simply shutdown all PCs or start them all up using the magic packet method. You can also watch for certain users :rolleyes:

 

This works really well - especially the morning startup is only a mouse click!

 

I'll see if I can package this up in a more generic format. It should work on an Windows server/AD based network but it will need to be tweaked to fit.

Posted

I had a colleague that created a script like that, it works ok, but when we scheduled it staff weren't happy because it shutdown their PC in the middle of something (why they are still in the school at 7pm, I'll never know).

 

So now we use something else, that doesn't use AD to check for PCs, it just shuts down every PC running a M$ OS on the network. :eek: Don't worry though, it checks the PCs name against a Skiplist txt file, so for things like servers, and admin workstations, we just get it to skip those, so they keep on running (They do have to be in UPPERCASE for some reason, I guessed it was because its using netbios). It also use's a different version of the shutdown.exe, so that the end user has an option to cancel the shutdown if they are still working. Not bad going for 3 files all freely available. I can't remember where I got them from, but if you PM me I can send them to you, or if I get to many requests I'll just attach it to a post. Its all free stuff too (my favourite price).

 

I didn't create it by the way, I stood on the shoulders of giants to get where I am, I understand how it works though. :p

Guest monkeyx
Posted
Tried the script here and it did not work. Interesting script if I could get it to work.

 

What error message did the script give?

 

Did you set strOU and strDomain with valid values?

Posted
We wrote a multi purpose system here. Every time anyone logs in it gets logged in an SQL server with the PC details/username/time etc. The trick is to store the MAC addresses etc as well for startup scripts.

 

Then each of us has a console to view the logins etc. We can use the console to shutdown/restart PCs or simply shutdown all PCs or start them all up using the magic packet method. You can also watch for certain users :rolleyes:

 

This works really well - especially the morning startup is only a mouse click!

 

I'll see if I can package this up in a more generic format. It should work on an Windows server/AD based network but it will need to be tweaked to fit.

 

Yeh im strugling on morning when turning on pcs. if there is a handy tool it will be gr8. if you can package that, most of us will love it.:troll:

Guest monkeyx
Posted
Yes set the domain and the following ou structure:

 

strOU = "ou=D7,ou=Desktops,ou=Resources"

 

It does not give any errors.

 

The script writes all output to logfile.txt rather than the screen.

 

Is that showing anything?

Posted
The script writes all output to logfile.txt rather than the screen.

 

Is that showing anything?

 

No nothing, it creates the file but it is empty.

Posted

what time do you shut them down?

 

I have a scheduled script that does ours at 4pm but takes note of anyone logged in, doesnt shut them down and then a later scheduled script takes care of those ones.

Guest monkeyx
Posted
No nothing, it creates the file but it is empty.

It must be because you are pointing an OU with no sub OUs?

 

I will amend the script so that it process the parent and children OUs.

Someone else has also asked if I can add a section to skip OUs as well computers.

 

A few people have mentioned freeware or commercial alternatives.

 

The script is totally free and open for anyone to use and change. So has an advantage over freeware, also does not need a client. It forcefully throws people off to prevent them being logged in and leaving equipment on over night, part of an eco drive at our school!

 

The warning time can be changed, or individual computers can be left out of the shutdown scheme.

Guest monkeyx
Posted (edited)

I have added the following to the script I posted yesterday to process computers in the parent OU, before going on to process child OUs and computers.

 

'Process computers in first level of OU.

objParent.Filter = Array("computer")

Call ouComp(objParent)

 

Hopefully that should work for you now.

 

PS a couple of people asked about where this should be run from. We run it from a server as a scheduled task, that runs all our scheduled tasks and monitoring tasks. But it can be run from any PC or server that has admin access to the PCs, that you are wanting to shutdown.

Edited by monkeyx
Posted
I have added the following to the script I posted yesterday to process computers in the parent OU, before going on to process child OUs and computers.

 

Thanks for trying but I don't have any PC's in the parent OU my Ou structure is like this:

 

OU.JPG

Guest monkeyx
Posted

The parent in relation to the script starting OU, not parent in the domain?

 

Did you try the new script?

Guest monkeyx
Posted
Cheers for the script monkeyx

 

Will it shutdown machines that are locked? As our current psshutdown seems to struggle with locked machines.

 

Cheers.

 

It uses the force option from shutdown, so in theory yes?

 

In theory could also shutdown ising WMI to force issue, but not sure if this would be more reliable?

 

This script is a proof of concept for a c# application that will add extra functionality etc to force and monitor shutdown success.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...