Troubleshooting a VBScript

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! Maybe you can help me out. I have been using a script to schedule tasks to execute VBScripts on remote machines within my domain at work. I usually use this to send messages to specific users or to start a chain-updating event for my machines. The problem comes when setting the scheduled task and assigning the result to the errJobCreated variable. The only reason I am having such a problem is because of the horrible error messages VBScripts give at run time. I thought I would ask you guys. I am getting error 80041005 on the line with “errJobCreated = objNewJob.Create char 1. After looking up the error it says it is a type mismatch.

- CC

SpacerHey, Scripting Guy! Answer

Hi CC,

It probably means that you have a type mismatch. VBScript is a typeless language, which means that the only data type it knows about is a variant. In other words, it can be anything. However, WMI is strongly typed. This creates cognitive dissonance for many writers of VBScript who are not used to worrying about strings, integers, or dates. The signature for the create method of the WIN32_ScheduledJob class is listed on MSDN. You will notice that the first parameter must be a string, the second a dateTime, the third a Boolean, and so on. Because the signature for the WIN32_ScheduledJob class is so complicated, we actually prefer to store each parameter in a variable, and supply the values outside the method call. This is detailed in Ed’s book, Microsoft Windows Scripting with WMI: Self-Paced Learning Guide.

The other thing we dislike is trying to manually create the UTC dateTime object. This is, we suspect, where you are actually failing in your script. I prefer to use the SwbemDateTime object from WMI to create the dateTime object. This COM object was introduced in Windows XP and is available moving forward. It is a bit backward to use, but is documented in the previously mentioned book. It is also talked about in this article. And this article talks about creating a scheduled task. Here is a function I wrote that uses the SwbemDateTime object to convert a file time into UTC format. You can use this in your scheduled job script.

UseDateTimeObjectFunction.vbs

'test = Now
test = DateSerial(2006,04,12)
WScript.Echo funUTC(test)

Function funUTC(mydate)
Dim dateTime
Set dateTime = CreateObject("WbemScripting.SWbemDateTime")
dateTime.SetVarDate(mydate)
funUTC= dateTime
End Function
 

Troubleshooting an Issue with the WIN32_NetworkAdapter Class

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! First off, I’d like to start by thanking you for all the wonderful scripts. I recently found a neat script on the Script Center called How Can I Enable or Disable My Network Adapter. The only problem I found when trying it out is that disabling the network card does not work when the network card is disconnected. At home I’m using a wireless Internet connection and no cable. In this case, when I call "EnableDisableNetworkAdapters.ps1 -wired disable", the script does not return any errors and seems to work, but when I check the network connections, the card is still enabled (the query information does show the correct network card). When I call "-wireless disable", the wireless network card is disabled as expected. At my work it's the other way around. I'm on a cable Internet connection and not wireless. When trying to disable my wireless, which has at that moment a 169.254.x.x-address, nothing happens, even though the network card is disabled as expected. I'm running Windows PowerShell in administrative mode. Is this a glitch in WMI, is this by design, or am I doing something wrong? Thanks in advance.

- MW

SpacerHey, Scripting Guy! Answer

Hi MW,

We just heard back from the WMI team. This is in fact a bug in the WIN32_NetworkAdapter class. It has been fixed in Windows 7. In the meantime, if this is causing you problems, we suggest you modify the script and use the DevCon command-line utility instead. Hope this helps, and we are glad you are enjoying the scripts we write.

 

How Can I Change the Local Administrator Password in an International Environment?

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! Thanks a lot for your great work on VBScript. I came across this article and I have a question about the query process. I know your time is valuable, so I’ll keep it brief.

Goal: Change the local administrator password in an international environment.

Challenge: Local administrator account is spelled differently depending on operating system language.

I followed the usual suggestions to retrieve the information using WMI. The result is the following script.

ConnectToWMIAndQueryForUserAccountProperties.vbs

Set objResult= objWMIService.ExecQuery("Select * from Win32_useraccount `
Where domain = '" & strComputer & "' and LocalAccount = 'True'")
'Identify Local administrator account by SID
For Each objLocalUser In objResult
intLastDigit = Right(objLocalUser.SID, Len(objLocalUser.SID)-InStrRev(objLocalUser.SID, "-"))
If intLastDigit = 500 Then
LocalAdmin = objLocalUser.Name
Wscript.Echo  "Local administrator account identified as: " & LocalAdmin
End If
Next

The problem I have is that enumeration of the query takes more than 10 seconds. I assume that even though the query is limited to LocalAccount = True, WMI still has to enumerate all accounts it knows of. Because this is supposed to run on hundreds of machines, I’m wondering if there is a better way to translate the local administrator SID to the account name.

- DS

SpacerHey, Scripting Guy! Answer

Hi DS,

We could tweak the WMI query, but in the end, the performance will still be too slow for your purposes. The best thing is to use ADSI. In Windows PowerShell it would look something like the following code. Make sure you use the SID for the account you are attempting to work with.

adsi]"WinNT://SID=<S-1-5-21-1653536929-3210562549-3252621027-500>"

You can do something similar in VBScript.

 

How Can I Get the Windows Vista Sidebar to Work Again?

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! I have Windows Vista on new computer, and I have fallen in love with the Windows Vista Sidebar. Various programs were installed on my computer and then suddenly the Sidebar gadgets have quit working. When I try to start them, they still do not work. I know this is not very specific and is not really scripting related, but you seem like such nice young men, I thought I would ask you anyway. I will understand if you don’t answer.

- PD

SpacerHey, Scripting Guy! Answer

Hi PD,

I have been talking with the “Fix it for me” team for the last month or so, and as it turns out, I believe they have a solution to your exact problem. As you can see in the following image, the support article has a Microsoft Fix it button.

Image of the Microsoft Fix it button on a support page

 

Click the button, and it will apply the fix for the issue discussed in the earlier portion of the article. There is no mystery here. The article tells you exactly what it is doing, so you could perform the same steps manually if you want to do so. Why is this cool? For people such as PD, it now means she does not have to perform a bunch of confusing steps and risk making things even worse. But for network administrators, it also means these are solutions you may want to implement by yourself on your own network. Here is the link to their team blog.

 

How Can I Tell if the Desktop Experience Pack Is Installed on Windows Server 2008?

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! We need to find out if there is a way on Windows Server 2008 to detect whether the Desktop Experience Pack is installed on the system.

- AS

SpacerHey, Scripting Guy! Answer

Hi AS,

There is a new WMI class in Windows Server 2008 that you can use to solve your problem. It is called the WIN32_ServerFeature class, and it is documented on MSDN. You could use a query something like this to solve your problem.

DetectDesktopExperience.vbs

Set objWMIService = GetObject("winmgmts:")

Set colFeatureList = objWMIService.ExecQuery("SELECT * FROM Win32_ServerFeature`
 WHERE Name = 'Desktop Experience'")

For Each objFeature In colFeatureList
   WScript.Echo objFeature.ID & ": " & objFeature.Name & " (Parent: " & objFeature.ParentID & ")"
Next
 

How Can I Change Multiple Computer Profiles at Once?

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! I am glad to consult with you .We have over 1,000 POP3 e-mail clients. But recently our e-mail server changed to new IP addresses and even a new domain name. I do not want to change the profile one by one; could you teach me how to change the profiles for all clients by script?

- WF

SpacerHey, Scripting Guy! Answer

Hi WF,

You did not mention what kind of e-mail client you have. Each e-mail client has its own way of doing things. Many e-mail clients do not expose an automation interface. For example, Office Outlook does, but Outlook Express does not. It is possible that the connection information is stored in the registry; if it is, the process of editing it will be rather straight-forward. It is also possible that your e-mail program may expose an automation model. If it does, you would need to get the information about how to automate the program from the vendor. One of the advantages of using Office Outlook and Exchange Server is that they automatically update the configuration. Therefore, no scripting is needed when the server configuration changes.

If you cannot find the information you need from the vendor, you may try to see if the information is stored in the registry. You can use RegMon to monitor the registry while making the change in the client and see what gets updated. This may work, and it may not. It all depends on how the program is written. Because I suspect you will need it, here is some information about editing the registry remotely by using WMI. You may also be interested in the Getting Started section of the Script Center.

 

Where Did the “Scripting Newswire” Go?

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! Subscribe.

- LM

SpacerHey, Scripting Guy! Answer

Hi LM,

Obviously, you wish to subscribe to the Scripting Newswire (archive). (It was a review of what had happened recently on the Script Center.) It is now retired and is living in South Florida, where it can go diving in the morning, sip tropical drinks in the afternoon, and walk along the beach in the evening.

But how can we live without the Scripting Newswire? You can always find a link to the current “Hey, Scripting Guy!” article on the Script Center home page. If you miss a few days, you can always go back and catch up via the “Hey, Scripting Guy!” archive. In addition, we have started using Twitter to keep the scripting community updated in real time about what is happening on the Script Center. For instance, if you were following us on Twitter, you would know exactly what we are working on and when. This would actually give you a chance to send us a quick question by e-mail, and you could influence the way the article is written. You could say, “I see you are working on an article about working with event logs for next week. Are you going to talk about how to back them up?” We could then reply to you, “You know we did not think that was an issue, but I will be sure to cover that.” Now that is much better than a scripting newsletter. No wonder it retired. It was outmoded and could not keep up with the 21st century!

 

This is the end of another Quick-Hits Friday. It also brings us another week closer to Tech∙Ed 2009. Ed Wilson will be speaking there about using Windows PowerShell 2.0 to manage the remote desktop. If you are going, please choose your sessions in advance because this gives us an indicator of the interest in a particular session. We can then move rooms around to accommodate the interest, or even add additional sessions if required. Craig Liebendorfer and Ed will also have a booth, so stop by and say hi. Have a great weekend, and we will see you on Monday. Until then, peace.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys