Maximilian Burszley's helpful answer explains the problem with your code and offers an effective solution.
If you're happy with your (fixed) code's performance and you see no need to improve your code, that's all you need.
To learn about reusable techniques that both shorten and speed up your code, read on.
A concise, PowerShell-idiomatic solution that performs much better (PSv4+):
# Read the CSV rows (into custom objects whose properties contain the
# column values).
$rows = Import-CSV "C:\T2\SetManagers\EmployeeManager.csv"
# Collect all Employee and Manager column values in an array each.
$employeeLists = $rows.Employee
$managerLists = $rows.Manager
# Loop over all column values, extract only the first ","-separated token each
# and send the combined output to an output file.
$employeeLists.ForEach({ ($_ -split ',')[0] }) > "C:\T2\SetManagers\ESplit.txt"
$managerLists.ForEach({ ($_ -split ',')[0] }) > "C:\T2\SetManagers\MSplit.txt"
Specifically, the code above avoids:
Building up an array in a loop with +=
, which necessitates recreating the array (with the new value appended) in each iteration.
Instead, it uses member-access enumeration (PSv3+) to directly retrieve an array of property values (e.g., $employeeLists = $rows.Employee
)
Even in PSv2 a relatively concise and more efficient form is possible; the PSv2 equivalent of $employeeLists = $rows.Employee
is:
# *PowerShell* does the work of collecting the outputs from the individual
# loop iterations and simply returns an array.
$employeeLists = foreach ($row in $rows) { $row.Employee }
Finally, if you do need to build up a collection iteratively and speed matters, use
an extensible collection type such as [System.Collections.Generic.List[object]]
and its .Add()
method instead of arrays with +=
.
Calling Out-File
in a loop, which incurs the cmdlet's startup and teardown cost in each iteration and also requires reopening and closing the file every time.
- Instead, the combined output of the statement is written to the output file in a single
Out-File
call (shortened to >
for brevity).
The PSv4+ .ForEach()
method rather than a foreach
loop performs better (though only slightly), and has the advantage that you can directly use it as the first segment of a pipeline (whereas a foreach
loop would require wrapping in $(...)
).
In PSv3-, use a foreach
loop.