Hey, Scripting Guy! Quick-Hits Friday: The Scripting Guys Respond to a Bunch of Questions (05/01/09)

How Can I Get Help with Scripts I’m Writing?


Hey, Scripting Guy! Question

Hey, Scripting Guy! I am a novice scripter but am being diligent about learning more specifically around VBScript. I am following the Microsoft Press book, Windows Scripting Self-Paced Learning Guide, and I find it very helpful. Is there someplace people may post scripts that they want someone to take a look at to try to determine why a certain behavior is occurring? Thanks for anything that you can offer!

– JM

SpacerHey, Scripting Guy! Answer

Hi JM,

The best place to find anything on VBScript is the TechNet Script Center. As you find things that you are interested in learning about, you may want to check out the “Hey, Scripting Guy!” archives in addition to the daily article. The Getting Started Guide targets VBScript and provides a road map into the learning resources we have on the Script Center. We have several different scripting hubsthat are useful for finding information related to specific areas such as Active Directory or Microsoft Office.


How Do I Convert a CSV File to a Tab-Delimited File?


Hey, Scripting Guy! Question

Hey, Scripting Guy! I liked the article, How Can I Convert a Tab-Delimited File to a Comma-Separated Value File? Now, how do I convert from a .csv file (saved from Excel) to a tab-delimited file?

– NA

SpacerHey, Scripting Guy! Answer

Hi NA,

I am glad you liked the article; it took us a while to write. Here is a replacement pattern that you can use to replace a comma with a tab:

Foreach-object { $_ -replace “,”,”$([char]0009)” }

You see 0009 is Unicode for a tab. (You can also use the \t Meta character). I love the [char] .Net Framework class because it lets me create all kinds of cool things. The revised script resembles this:

Get-Content –path C:\fso\CSVDelimited.csv | Foreach-object { $_ -replace “,”,”$([char]0009)” } |`
Out-File -filepath C:\fso\tabDelimited.txt

Top of pageTop of page

How Can I Expire PCs and Delete Them from an Organizational Unit?


Hey, Scripting Guy! Question

Hey, Scripting Guy! I was curious if there was an easy way to set PCs to expire and then be deleted from an organizational unit (OU) automatically. This would be a fixed time (say three or four years) after their initial creation on that OU. Together with that, is there a way to warn users of this impending action in a prearranged advanced notification? The notification I had in mind was something similar to the network password expiration notification. Basically, the scenario behind this is that the PCs are leased and must go back within the lease term. In order to do this the least painful way, the client is warned (encouraged to replace the current PC) automatically at intervals and then the PC is dumped from the OU after expiration.

– DF

SpacerHey, Scripting Guy! Answer

Hi DF,

Each object in AD has a whencreated attribute. You could query for “objectcategory=computer” and then for each object evaluate the whencreated attribute. If it is greater than 3 years, call the delete method. You could then create a scheduled task to run one time per month and perform your cleanup. It would not be that difficult to write (although easier in Windows PowerShell). However, I think I would be a bit scared to run such a script. But then I am a fraidy cat when it comes to deleting objects from Active Directory. Generally, I prefer to disable objects for a while to see whether anyone complains. But what the heck, I am sure that you have a good backup and are experienced in doing directory restores.

You can find scripts for searching AD in the Script RepositoryThese scripts enable you to delete computer objects via Active Directory (I tremble to think about this.) Here is some information about how to work with dates and the like. However, this article may be better for you in learning date arithmetic. Here are two articles for working with scheduled tasks: Part 1 and Part 2.


How Can I Retrieve the Process ID of a Script?


Hey, Scripting Guy! Question

Hey, Scripting Guy! I was reading your blog entry recently, and I began to wonder, “How can I retrieve the Process ID of my own script?”

– JV

SpacerHey, Scripting Guy! Answer

Hi JV,

The best way to capture your own Process ID (PID), is to use something else to start the script, and then capture the PID in this manner. For example, the WshScriptExec object has a processID property. You get a WshScriptExec object when you use the execmethod. This is talked about in these two articles: Running Programs from WSH Scripts and How Can I Hide the Command Window When Executing a Command Such as Net Localgroup Administrators?

Another method that you could use to retrieve the PID is to use the WIN32_Process WMI class, and call the create method. This Script Shop article goes into more detail by using that method.

Also know that the WIN32_Process WMI class also has a command-line property. This will give you the name of the script that was started. You examine either the cscript or wscript process. This information can help you track down the PID if you did not happen to capture it when the script started.


How Can I Use a Command-Line Zip Application to Archive All User Profiles?


Hey, Scripting Guy! Question

Hey, Scripting Guy! How can a user run a VBScript, as the local administrator, that will archive all user profiles by using a zip command-line application?

When a user has to re-image their workstation, we want to archive all user profiles to a mapped drive before starting the actual re-imaging process. We want to be able to have the user start the process by running a VBScript that will capture the computer name, gateway IP, and other specific information to a CSV file (this section of the script already works). However, we cannot make the zip application Run As Administrator.  If the ZIP application runs as the current user, the other user profiles on the computer cannot be archived because none our users are part of the local Administrators or Domain Admins groups. We can use WinBatch to perform these operations. But we are trying to avoid third-party applications, and we do not want to develop a VisualBasic application that will have to be maintained. Any assistance would be greatly appreciated. Thank you.

– RP

SpacerHey, Scripting Guy! Answer

Hi RP,

I have been thinking about your particular problem, but I do not think I can give you a definitive answer. However, I do have some ideas that I hope can get you started in the right direction. You may want to investigate preceding your call to the command-line zip command with a call to runas.exe. This may do what you’re looking to do.

One of the frustrating things about VBScript is that by default there is no runas option. You can easily do this, however. Here is a script I wrote to add direct runas functionality for a VBScript. This will enable you to right-click a VBScript and select runas from the shortcuts menu.


‘ VBScript:  AUTHOR: Ed Wilson , MS,  4/13/2009
‘ NAME: AddRunAs.vbs
‘ COMMENT: Key concepts are listed below:
‘1.Adds the run as script to the registry for the .vbs file extension. 
‘2.Have to ADD in the RUNAS key FIRST, AND assign the &Run AS … value.
‘2a. CAN not use &RunAS here, as it will TRY to add the runas.exe program…
‘3. THEN we add in the Runas.exe program. 
‘4. IF you go into “folder options” for example … choose fileTypes, and select vbs, 
‘4a. and choose the advanced button, you will see Actions: Edit, open,print,
‘4b. edit with primal script, open with command prompt, printto … 
‘4c. Tto add RUNAS … so I choose NEW, and then ADD runas in the program box… 
‘5. Below is how to do it Programatically. 
Option Explicit
Dim objShell
Dim strReg,strReg1
Dim strValue, strValueDEF

strReg = “HKCR\VBSFile\Shell\RunAS\” strReg1 = “HKCR\VBSFile\Shell\RunAS\Command\” strValueDEF = “&Run As …” strValue = “runas.exe “”%1″””

Set objShell = CreateObject(“WScript.Shell”) objShell.RegWrite strReg,strValueDEF,”REG_SZ” objShell.RegWrite strReg1,strValue,”REG_SZ”

If Err.Number <> 0 Then              WScript.Echo Err.Number,Err.Description,Err.Source Else              WScript.echo strReg1,strValue,”added” End if

How Can I Get the 2008 Task Scheduler to Recognize When a Task Is Complete?


Hey, Scripting Guy! Question

Hey, Scripting Guy! I have been using Windows Scheduler and some very (very) simple scripts to do file transfers and cleanups at set intervals. We have some new Windows Server 2008 servers in our environment and the 2008 Windows Scheduler never seems to recognize that the script has completed its task. As a result, it remains in run status.

Is there something I can append to my existing scripts that will cause 2008 Windows Scheduler to recognize that the script has completed successfully?

– AO

SpacerHey, Scripting Guy! Answer

Hi AO,

I checked our internal Knowledge Base tool, and I do not see anything related specifically to your question. I did not experience this problem when I wrote all my scheduled task scripts that appeared in the “Hey, Scripting Guy!” column the week of April 3, 2009.

If your task is running an external program, you can specify a return code that will return to the script to indicate success. Here is an example of doing that:


Dim WshShell, oExecSet WshShell = CreateObject(“WScript.Shell”)Set oExec    = WshShell.Exec(“%comspec% /c dire”)Function ReadAllFromAny(oExec)     If Not oExec.StdOut.AtEndOfStream Then          ReadAllFromAny = oExec.StdOut.ReadAll          Exit Function     End If     If Not oExec.StdErr.AtEndOfStream Then          ReadAllFromAny = oExec.StdErr.ReadAll          Exit Function     End If          ReadAllFromAny = -1End FunctionDim allInput, tryCountallInput = “”tryCount = 0Do While True     Dim input     input = ReadAllFromAny(oExec)     If -1 = input Then          If tryCount > 10 And oExec.Status = 1 Then               Exit Do          End If          tryCount = tryCount + 1          WScript.Sleep 100     Else          allInput = allInput & input          tryCount = 0     End IfLoopIf oExec. ExitCode<> 0 Then     WScript.Echo “Warning: Non-zero exit code”End IfWScript.Echo allInput

The Task Scheduler is seen here in Windows Vista:

Image of the Task Scheduler in Windows Vista


Here are some general troubleshooting things to try with Task Scheduler:

Confirm that the Task Scheduler service has started and is in the running state. Otherwise, refer to the Task Scheduler Service Issue template.

If none of the scheduled jobs is running, try to delete and recreate the job by using your script.

Make sure that the task is enabled. You have to open the task’s properties, under the Task tab, and make sure the Enabled check box is selected.

Check the executable and make sure that you have correctly defined its path.

If this is only occurring on one specific task or batch file, try to implement some checkpoints in your script by echoing out time (time /t in a batch file; wscript.echo now in a VBScript), and create checkpoints in the script.

If the task worked previously, check the user name and password that are used to start the task. Check the Group Policy settings on the computer to make sure the user still has rights to perform the task.

Check the error messages in SchedLgU.txt and try to see whether you can find any System or Application log events at the same time.

If the existing tasks run but you cannot create any new tasks, some Task Scheduler files in %windir%\system32 folder might be missing or corrupted. In Windows Server 2003, check for Mstask.dkk, Mstinit.exe, and Schedsvc.dll. In Windows 2000, check for Mstask.dll and Mstask.exe.

Here are some Knowledge Base articles that may help:

308558: How to Troubleshoot Scheduled Tasks in Windows XP and in Windows Server2003

246183: You receive error message 0x80090016 or error message 0x8009000f when you try to schedule a task

223375: Cannot Configure Scheduled Tasks to Use System Account

313111: Scheduled tasks may not start if you used a System Preparation image to install Windows XP or Windows 2000

814596: How to use Schtasks.exe to Schedule Tasks in Windows Server 2003

313565: How to use the AT Command to Schedule Tasks

That wraps up another Quick-Hits Friday. We hope that you have a safe weekend, and we will see you next week. Until then, peace.


Ed Wilson and Craig Liebendorfer, Scripting Guys


Comments are closed. Login to edit/delete your existing comments