John Balan John Balan - 2 months ago 8x
PowerShell Question

PowerShell reading a list of text files in a folder

We need to get a list of workstation ids for a set of users. We modified the startup script to run a batch file that dumps the info we need to a file share in the following method:


Edit: Here is a sample of the text file (there are 2000 users, so we will have 2000 files in time)


We will have duplicates because they will login multiple times.

This file has the list of machines (workstation and citrix servers that the user has logged into). Now I am trying to extract the information in a meaningful manner (there are over 1300 files and the final count will be around 2000). So far this is what I have:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
# this is the path for the share
$SearchFolder = "\\server\Users\*.txt"

# Search each txt file in the path and store all of the lines and filenames that don't match the pattern

$File = Select-String -Path $SearchFolder -Pattern %CLIENTNAME%,"ECHO is on", "server*","vs*","ctx*" -NotMatch | select line, filename


What this gives me is the following:

Workstation1 User1
Workstation2 User2
Workstation3 User3
Workstation4 User3
Workstation4 User3

What I want to do is get a list of unique workstations that a user has logged in to.




How can I do this?


The output that you've stored in $File should already be an array of objects, each of which has a property called .line (which is the computer name) and a property called .filename (which is the user name).

By grouping them by user, you can get a list of workstations, and from there you can make that list unique:

$groups = $File | Group-Object filename

This gives you a new type of object, where the .Name property refers to the element being grouped by, in this case the filename (which is the user name). The .Group property is the original object(s).

So from there, you can iterate over the groups and get the workstations for each one:

$all = $groups | ForEach-Object {
    $user = [System.IO.Path]::GetFileNameWithoutExtension($_.Name)
    $computers = $_.Group.line | Sort-Object | Select-Object -Unique
        User = $user
        Computers = $computers

Now $all will contain an array of objects, where each object represents a user, with an array of the computers. You can format that however you like.