How Can I Dynamically Populate a List Box in an HTA?

Hey, Scripting Guy! Question

Hey, Scripting Guy! In my HTA, I would like to query a computer for a list of local user accounts, then dynamically create a list box containing those accounts. How can I do that?

— BN

SpacerHey, Scripting Guy! AnswerScript Center

Hey, BN. You know, if you’d ever seen the Scripting Guys in … action … you’d think twice about asking us a question about doing things dynamically. But as long as you stick to things like dynamic list boxes (and forego things like dynamic personalities) we might be able to help.


Let’s start off by showing you the complete code for an HTA that retrieves all the local user accounts and then displays those accounts in a list box, which is populated on-the-fly. To make use of this code, copy it from your browser, paste it into Notepad or another text editor, and then save it with a .hta file extension. And if you’re already lost because you have no idea what an HTA is (hint: it’s short for HTML Application), then you might want to check out our HTA Developers Center, and maybe even peruse our HTA tutorial series.


Here’s the code:

<html>
<head>
<title>Local Users</title>

<HTA:APPLICATION
ID=”objHTAHelpomatic”
APPLICATIONNAME=”LocalUsers”
SCROLL=”yes”
SINGLEINSTANCE=”yes”
WINDOWSTATE=”maximize”
>
</head>

<SCRIPT Language=”VBScript”>

Sub Window_Onload
Set objNetwork = CreateObject(“Wscript.Network”)
strComputer = objNetwork.ComputerName
Set colAccounts = GetObject(“WinNT://” & strComputer & “”)
colAccounts.Filter = Array(“user”)

For Each objUser In colAccounts
Set objOption = Document.createElement(“OPTION”)
objOption.Text = objUser.Name
objOption.Value = objUser.Name
LocalUsers.Add(objOption)
Next
End Sub

</SCRIPT>

<body>
<select size=”5″ name=”LocalUsers”>
</select>
</body>
</html>


The part we care about is the Window_Onload subroutine. (Incidentally, we use this subroutine because Window_Onload automatically runs any time an HTA is started or any time the HTA window is refreshed.) Inside this subroutine we do two things: retrieve a list of all the local user accounts, and then take those user names and put them into a list box. We won’t spend any time today talking about the process for retrieving local user accounts; all we’ll do for now is tell you that we do that using these four lines of code:

Set objNetwork = CreateObject(“Wscript.Network”)
strComputer = objNetwork.ComputerName
Set colAccounts = GetObject(“WinNT://” & strComputer & “”)
colAccounts.Filter = Array(“user”)

The part we will talk about today involves taking those user accounts and adding them to the list box. Before doing that we should point out that, when we start this HTA, the list box already exists; there just aren’t any items there. Admittedly, we could have been even more dynamic and created the list box itself on-the-fly. But that was a bit more complicated than we wanted to deal with, and didn’t really seem worth it anyway. In case you’re wondering, here are the HTML tags that create an empty list box:

<select size=”5″ name=”LocalUsers”>
</select>

And now, at last, here’s the code that populates that list box with user names:

For Each objUser In colAccounts
Set objOption = Document.createElement(“OPTION”)
objOption.Text = objUser.Name
objOption.Value = objUser.Name
LocalUsers.Add(objOption)
Next

What we do here is set up a For Each loop to cycle through the collection of user accounts. For each user account we create an instance of the HTML Option object; each Option object is equivalent to an item in the list box. That’s what this line of code is for:

Set objOption = Document.createElement(“OPTION”)

We then use these two lines of code to configure the Text and Value properties for the item:

objOption.Text = objUser.Name
objOption.Value = objUser.Name

If you haven’t done a lot of work with HTML, the Text is simply the text that appears in the list box. In the sample list box shown below, Option 2 is not only the user name that appears in the list box, it’s also the Text of the highlighted item:

HTA List Box


The Value, meanwhile, is the data reported to a subroutine when a given option is chosen. Text and Value for an option do not have to be identical. We made them identical in this case simply because it makes sense: you want the user name to show up in the list box, and you probably want the user name to be used in your subroutine. (For example, your subroutine likely binds to that particular account, and you’ll need the user name in order to do that.) However, we could have set the Text to be the user name and the value to be, say, an employee ID number (assuming we had that information available to us). That’s up to you.


After configuring the Option object we add the new item to the list box like so:

LocalUsers.Add(objOption)

As you can see, all we do is refer to the list box (LocalUsers) and call the Add method. Along the way, we pass Add a single parameter: the object reference to our Option object. That’s pretty much it: we loop around, repeat the process for all the user accounts in the collection, and we’re done.


Yes, very easy and requires very little coding. But what did you expect? After all, even when the Scripting Guys are being dynamic, we still try to expend as little effort as possible.