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


Troubleshooting an Active Directory HTA


Hey, Scripting Guy! Question

Hey, Scripting Guy! I have created an HTML Application (HTA) to prompt a support person for their administrative ID and password and a computer name that they wish to delete from Active Directory. The script uses the alternate credentials to find the computer object alright, but does not use the alternate credentials to delete the object. I am having issues figuring out a way to get this done.

– DC

SpacerHey, Scripting Guy! Answer

Hi DC,

Here are a couple of articles that talk about deleting a computer account from Active Direcotry: Article 1 and Article 2. Your script portion looks like it could be correct; we do not see any glaring error.

We would take the code out of the HTA and run only the code, first with hard-coded values to make sure it works. Then we would change the script to use an input box for the values and see if that works. If both of those tests work, there is a problem with something in the HTA. HTAs are difficult to troubleshoot and it is best to remove them from the scenario early on.

One thought we initially had was that you were having a problem maintaining state between two different subroutines, but that does not appear to be the problem as you both search for and delete within the same subroutine.

My guess now is that you are not actually using the credentials that you are passing. In most cases, a normal person is allowed to query Active Directory because of the need to locate services, verify rights, and so on. It is possible that this part of your script is being ignored, and hence my suggestion to strip everything out of the HTA and see if it works. If hard-coded credentials work, the next step is to see what happens when they are typed in an input box. It is possible that quotation marks are needed, special characters are being interpreted instead of escaped, and all the silly exceptions that makes writing scripts so much fun.

When you get it working, we would like it if you would be willing to share it with others via the Community-Submitted Scripts Repository. Send it by e-mail to scripter@microsoft.com with the subject of “Community-Submitted Scripts Repository.” Of course, you would want to first strip out your domain name information and the credential information.


How Can I Reboot Multiple Computers from a Text File?


Hey, Scripting Guy! Question

Hey, Scripting Guy! I’ve been trying to reboot multiple computers from a text file, but I can only get it to work if I use one server at a time. Here is my script:

 $a = Get-Content "C:\serverlist.txt"
foreach ($i in $a)
(gwmi win32_operatingsystem -Credential $cred -ComputerName $a).Win32Shutdown(6)

But when I run it, I get this error:

Method invocation failed because [System.Object[]] doesn't contain a method named 'Win32Shutdown'.
At :line:24 char:77
+ (gwmi win32_operatingsystem -Credential $cred -ComputerName $a).Win32Shutdown <<<< (6)

– PJ

SpacerHey, Scripting Guy! Answer

Hi PJ,

You almost have your script right. Here’s how it should be written:

$a = Get-Content "C:\serverlist.txt"
foreach ($i in $a)
(gwmi win32_operatingsystem -Credential $cred -ComputerName $i).Win32Shutdown(6)

The change is made to the value of the ComputerName parameter. The $i variable is the enumerator; $a is the array of computer names. As we mentioned a few weeks ago during WMI Week, the ComputerName parameter can take an array of computer names, but you would not then be able to directly call the Win32Shutdown method. To directly call that method, you must be working against a single instance of the object. This is why your error has square brackets: [System.Object[]]. That is an array. It is telling you that your array or collection of WIN32_operatingsystem does not have the Win32Shutdown method. This is true: Only a single instance of the object can be shutdown.


How Do I Create and Destroy DSNs Via Script?


Hey, Scripting Guy! Question

Hey, Scripting Guy! Back in 2004 you posted some information about how to create and destroy DSNs via script. I would like to see some further examples using DSNs for:




Text files

Yes, I could spend hours digging around in the registry looking for all the goodies I need, but you and I both know that without the enormous cerebral cortex of the Scripting Guy, I probably wouldn’t come off looking like an egghead in a lab coat. If the Scripting Guy deigns to answer this question it will certainly make my job easier. Unworthy to dimension your variables, I remain your devoted reader.

– JS

SpacerHey, Scripting Guy! Answer

Hi JS,

Seems like it was only yesterday. Maybe it is because we am listening to an old Eric Clapton song right now. In the article to which you refer, we say:

“If you’re using a different database, we’d recommend that you manually create an ODBC Data Sources Name (DSN). After you do that, fire up your favorite registry editor and look for the DSN here:


And here:


Take a look at the registry keys and values required for that type of database, and then plug that information into our script….”

This still is more than likely good advice. There are no good ways for scripting a DSN (that I know of) other than hacking the registry. So the best bet would be to create the DSN, look in the registry, make the changes to the script, and then send the newly working script to scripter@microsoft.com, so we can post it to the Community-Submitted Scripts repository Center (and then we don’t have to write the script).


How Can I Open Active Directory Users and Groups with the RunAs Command?


Hey, Scripting Guy! Question

Hey, Scripting Guy! I have been trying to open AD users and computers from the command line and with the runas command, but it keeps telling me:

“RUNAS ERROR: Unable to run – C:\WINDOWS\System32\dsa.msc
193: C:WINDOWS\System32\dsa.msc is not a valid Win32 application.”

I have tried to add the cscript.exe and wscript.exe in there, but it tells me there is no script to run. Here is my full code I am using:

@echo off
runas /profile /user:domain\admin "%systemroot%\System32\dsa.msc"

What am I doing wrong?

– WC

SpacerHey, Scripting Guy! Answer

Hi WC,

Aaron Margosis is a security specialist at Microsoft. See some of his very good articles on RunAs from his blog.


How Can I Delete All Local Printers with Exceptions?


Hey, Scripting Guy! Question

Hey, Scripting Guy! I just read this post on deleting all local printers. Is there a way to make exceptions to what gets deleted? For example: I want to delete all local printers except for “Adobe Printer.”

– DD

SpacerHey, Scripting Guy! Answer

Hi DD,

Inside the loop where you delete the printers, you will need to add an If statement and examine the name of the printer. If the name of the printer matches, you don’t do anything. Here is an example of such an If statement:

For Each objPrinter in colInstalledPrinters
   If objPrinter.name <> "adobe" Then
   End IF

You can test this logic by playing around with FakeDelete.vbs script, which will allow you to correctly determine the printer name you will need to use before attempting the deletion task. Here’s FakeDelete.vbs:

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colInstalledPrinters =  objWMIService.ExecQuery _
    ("Select * from Win32_Printer")

For Each objPrinter in colInstalledPrinters
        If objPrinter.name <> "MY PRINTER NAME" Then
           wscript.Echo objprinter.name
           ' objPrinter.Delete_
       End If

How Can I Carry Out an Uninstallation Function of Addition and Deletion of the Application of the Control Panel?


Hey, Scripting Guy! Question

Hey, Scripting Guy! Is there the method to carry out an uninstallation function of “addition and deletion of the application of the Control Panel” in a script automatically?

– JN

SpacerHey, Scripting Guy! Answer

Hi JN,

No there is not. Not that I am aware of. You can use the WIN32_Product WMI class to uninstall software, but it only works with software that has been installed by using the MSI technology.

This article talks about using this WMI class. In the Community-Submitted Scripts Center, you will find a couple of examples of uninstalling software. The first uses WIN32_Product, and the second relies on the uninstall string from the application from within the registry. This is the type of method you must use if the application does not use MSI.


How Can I Run a Scheduled Task Using Windows PowerShell?


Hey, Scripting Guy! Question

Hey, Scripting Guy! I’m trying to get my Window PowerShell script to run as a scheduled task. I’ve set up my profile with the following commands so that I don’t have to interactively enter my credentials:

$password = get-content C:\cred.txt | convertto-securestring
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist`

Next, I set up a batch file to kick off the .ps1 script when the scheduled task runs. Are there any other switches that I need to run? I got an access denied error when trying to use the script this way:

powershell.exe -noexit c:\myscripts\restart-servers.ps1

– TJ

SpacerHey, Scripting Guy! Answer

Hi TJ,

A number of strange things happen when you use Windows PowerShell to run a scheduled task using various credentials. Here are some general troubleshooting tricks that might help you:

Make sure that script support has been enabled: Set-ExecutionPolicyunrestricted or remotesigned. On Windows Vista this command needs to run with administrator rights from an elevated prompt.

Pay attention to the user that is being used to launch the scheduled task. You could be getting access denied when trying to read your text file off the root!

Simplify! I would test my syntax for the scheduled job task by running a helloWorld.ps1 script to ensure that it runs.

Open a Windows PowerShell prompt, and type powershell -? | more to see your powershell.exe syntax.

Test your powershell.exe syntax by using the run command. Start / run powershell -noexit “C:\fso\HelloWorld.ps1”

When you have the above working, put it into a scheduled task.

After the simple scheduled task works, try your script.

We have once again reached the end of Quick-Hits Friday, which means it is also the end of the week. It is supposed to be nice and sunny this weekend. Get out and soak up some rays. We will see you Monday morning looking all tanned, and feeling rested and relaxed. Until then, peace.


Ed Wilson and Craig Liebendorfer, Scripting Guys