How to click throw every item in a list quickly

Dec 2, 2014 at 5:12 PM
I have a solution in place that works but I am thinking there must be a faster way to traverse a list.

Currently I get the Window and List and then store the List items into an array:
$list = Get-UIAWindow -Name myWindow | Get-UIAList;

$items = $list | Get-UIAListItem;

for each ($client in $items) {
$client | Invoke-UIAListItemSelectItem;
# do something else 
}
The problem I am having is the list contains about 1000 items. So storing the items into the array takes 3 - 4 minutes by itself.

What I would like to do is get a quick count of the number of items in the list and then just do a while loop through the list and pass an index to the listitem I want to select. I feel like that way it would not need to read in every item before we start working with it.

Is this possible with one of the Cmdlets?
Coordinator
Dec 2, 2014 at 11:42 PM
Edited Dec 2, 2014 at 11:44 PM
Hi mkessler31,
choosing a way to work with list items depends on what you want to do and of what type your list items are.
For example, I created a Windows.Forms form with a standard .NET listbox, set it to support multi-selection and my code for selecting all items is:
[UIAutomation.Preferences]::Highlight = $false;
[UIAutomation.Preferences]::HighlightParent = $false;
$null = Get-UiaWindow -n testBigList | Get-UiaList | Get-UiaListItem | %{ $_.AddToSelection(); }
It took 69 seconds on my netbook.

The general rules here are below:
1) eliminate output wherever you can, i.e. use instructions like these:
$null = expression
void;
expression | Out-Null
I measured performance someday with dotTrace and found that the worst thing is output to powershell.exe.
2) calling methods on objects could be a bit faster than passing data from a cmdlet to cmdlet because the first cmdlet in the pipeline sends object(s) to the powershell engine, which in turn sends them to the second cmdlet in the pipeline, and so on, Methods work directly with objects, not through the powershell engine.
There could be some methods exposed on elements depending on how the author of your list items created them. In my case I was given the AddToSelection() method.

There are also two methods available on every container object: Children and Descendants. They look like properties, however they are methods. They are calculated dynamically, so you cannot simply call $list.Children.Count.
Instead, you could try something like
$items = $list.Descendants;
I cannot predict whether you find a better way to navigate through elements as it depends on what your elements (list items) and container (list) offer. :)

One more way to do the same and for the same time:
$wnd = Get-UiaWindow -n testbiglist
$null =  $wnd.Children.Lists[0].Children.ListItems | %{ $_.AddToSelection(); }
Alex