Tuesday, February 25, 2014

One adventure ends, another begins!

Alas, my adventures in vbscript are at an end, but this isn't the end for me kids.  A new adventure awaits in Powershell.  I have begun converting many of my scripts from vbscript to Powershell and it has been quite an eye opener.  There are many more possibilities since it opens up more access to .Net runtimes.   I've been converting one of my most complex HTA scripts over and it has mostly been a breeze while still adding a ton of cool new functionality. 

Powershell functions are much more advanced and allow some great capabilities for re-use.  As I create useful functions, I will wrap them up and post at our new blog location for you all to enjoy.

I can't wait to get up to speed and share my new adventures with you all!

See you soon,

Oh, guess you probably need a link to the new Adventures in Powershell

Saturday, May 4, 2013

Script requests and the ultimate computer object

I hope everyone is finding this blog helpful.  I recently (finally) finished my BS in Information Technology and have been brushing up my resume.  Time to hit the job market and see if there are any bites! If you have any ideas for a new subroutine or function and would like me to cover it on this blog, let me know.  I would be glad to write the code and explain it here.

Also, I have an on-going piece of code that I update from time to time that may be useful for some of you.  It's a class object for a computer that will let you perform many tasks such as getting and setting all kinds of info and preforming actions like rebooting.  The class object is only about 70% complete at the moment but works like this:

Set objComputer = New Computer

objComputer.Name = "myComputerName"

Wscript.Echo objComputer.FreeRAM
Wscript.Echo objComputer.TotalRAM
Wscript.Echo objComputer.SystemDrive
Wscript.Echo objComputer.SystemDirectory
Wscript.Echo objComputer.WindowsDirectory
Wscript.Echo objComputer.Role
Wscript.Echo objComputer.LocalDate
Wscript.Echo objComputer.LocalTime
Wscript.Echo objComputer.IP
Wscript.Echo objComputer.DN
Wscript.Echo objComputer.DC
Wscript.Echo objComputer.CurrentUser
Wscript.Echo objComputer.SerialNumber
etc, etc, etc....

And there are functions too.  Like getting the current users, shutdown, restart, log off, enable DHCP, auto-assign DNS, assign specific DNS,  set WINS, etc.

The code as a mix of local and remote capability which means that once you set the Name property, it can use that to pull or set information for remote machines.  However, not all properties and methods use this.  I need to document that better and add more feedback to notify the coder.  By default, when you declare the new object, it automatically determines the local PC name and sets the Name property.  So if you are using it local, you don't have to set it.

In all, this class is very modular and robust.  It's just not quite finished.  I'm always finding new stuff to add and there is soo much more to add.  If any of you are interested in this, let me know.  I'd be glad to send you what I have to help you code faster!


Friday, April 20, 2012

File paths and backslashes

If you stumbled across this post, be glad you did.  There are a few times in a scripters life where a script goes out and something breaks.  Usually it’s the code not working and it’s a matter of finding the bug and fixing it.  And then there is a worst case scenario where your code breaks every computer in the company.

This is that case.

Now before I continue, I should stress the script in question was not created by me.  I’m very careful about file paths but this particular coder was not.

So this person’s script, let’s call him Bob, had a sub routine that was designed to take in a folder path, enumerate the files in that path, and delete them.  Many of us have similar code and there is certainly nothing wrong with putting this in a sub routine.  Let’s look at some example code:

strFolderPath = “C:\Temp”

set objFSO = CreateObject(“Scripting.FileSystemObject”)

set objFolder = objFSO.GetFolder(strFolderPath & “\”)

In the example above, Bob sets the C:\Temp folder path to strFolderPath.  Next he properly initializes the FSO object.  The last line is correct too, however, he appended the file path to add a backslash.  Here’s the problem:  If the strFolderPath variable never gets set, the net file path used by objFSO.GetFolder is “\”. 

Why is a net path of “\” a bad thing?  The script engine treats “\” as a valid file path to the root of the drive.  Now, remember what Bob’s sub routine was designed to do.  After it connected to a valid file path, it enumerated every file in that path and deleted them.  Now you’ve got a real problem.  Then consider that the root folder also contains your boot files.  If that machine reboots, it will not boot back up until those files are replaced.  Now you’ve got an even bigger problem.  Then start thinking about how many machines this code has touched as part of some GPO or logon script and you’ve got one really bad week.

So what should Bob have done?  Well first off, he never should have appended a file path with a backslash.  In the old days of command lines, that was sometimes needed to make copy and delete routines know your target was a folder, not a file.  But the FSO is much more exact that that.  If you tell it to GetFolder, it won’t GetFile.  There is no need for a backslash on the of a file path.  Even if you think you are saving some time, don’t. 

Also, since this was a sub routine, Bob could have added a quick line to the top of his script that would have checked the folder path variable before doing anything with it.  Such as If Not objFSO.FolderExists(strFolderPath) Exit Sub.  It’s not the most elegant way to check but it would have prevented the problem.  If you absolutely knew you’d never ever connect to the root of a drive to delete files, you could even add   If Len(strFolderPath) <4 Then Exit Sub.   This would also have worked since the root paths are generally in the format of C:\.

So remember, be very careful in your file paths and if you are ever deleting files from FSO, remember to always try and break your own code before someone else does.