PowerShell switch return missing file based on group

127 Views Asked by At

In theory, now that all the files in the '2023' folders have the same number of elements in the file name I can get an inventory. See my previous post for reference btw thanks @mklement0 it said not to comment thanks so this is my way around that.

For every computer id / process id there should be 4 distinct country files (Canada, Italy, Mexico, USA). Aside from outputting the file names in the '2023' folder, I need to output the missing file(s) based on the 4 countries since those are constant. I'm splitting the file name based on '.' and creating a column for each.

#splitFile_v2
$numberedFolder = 'C:\Users\cthor\OneDrive\Documents\PowerShell\Test'
$outputFile = "C:\Users\cthor\OneDrive\Documents\PowerShell\Results\results_$(Get-Date -f yyyy-MM-dd-hh-mm-ss).csv"
Get-ChildItem -Directory -Recurse -LiteralPath $numberedFolder -Filter '2023' |
    Get-ChildItem -File |
    Select-Object @{name='computer id';Expression={$_.Name.Split('.')[0]}},
    @{name='process id';Expression={"`t{0:d3}" -f [int] $_.Name.Split('.')[1]}}, #preverse leading 0's.
    @{name='computer name';Expression={$_.Name.Split('.')[2]}},
    @{name='city';Expression={$_.Name.Split('.')[3]}},
    @{name='country';Expression={$_.Name.Split('.')[4]}},
    @{name='date';Expression={$_.Name.Split('.')[5]}},
    @{name='file extension';Expression={$_.Name.Split('.')[6]}} |
    Group 'computer name','process id' -PipelineVariable 'group'|
    ForEach-Object {
        # Pass all objects that exist
        $_.group
        # Check for missing objects, and create a 'Missing item' object for any missing ones
        If($_.Count -ne 4){
        switch($_.group){
            {'Canada' -notin $_.country} {[PSCustomObject]@{'computer id' = $_.'computer id'; 'process id' = $_.'process id'; 'computer name' = $_.'computer name'; 'country' = 'Missing Canada'};break}
            {'Italy' -notin $_.country} {[PSCustomObject]@{'computer id' = $_.'computer id'; 'process id' = $_.'process id'; 'computer name' = $_.'computer name'; 'country' = 'Missing Italy'};break}
            {'Mexico' -notin $_.country} {[PSCustomObject]@{'computer id' = $_.'computer id'; 'process id' = $_.'process id'; 'computer name' = $_.'computer name'; 'country' = 'Missing Mexico'};break}
            {'USA' -notin $_.country} {[PSCustomObject]@{'computer id' = $_.'computer id'; 'process id' = $_.'process id'; 'computer name' = $_.'computer name'; 'country' = 'Missing USA'};break}
        } # End Switch
    } # End If
    } |
    Export-Csv -Path $outputFile -Append -NoTypeInformation

Current Output in csv file

computer id process id computer name city country date file
12345 001 chris_comp Mexico_City Mexico 2023_08_20 rtf
12345 001 chris_comp Milan Italy 2023_08_22 bmp
12345 001 chris_comp New_York USA 2023_08_22 xlsx
12345 001 chris_comp Toronto Canada 2023_08_22 txt
12345 002 chris_comp Mexico_City Mexico 2023_05_05 rtf
12345 002 chris_comp Milan Italy 2023_05_05 bmp
12345 002 chris_comp New_York USA 2023_05_05 xlsx
12345 002 chris_comp Toronto Canada 2023_05_05 txt
15555 001 andrew_comp Alberta Canada 2023_02_22 txt
15555 001 andrew_comp Juarez Mexico 2023_02_22 rtf
15555 001 andrew_comp New_York USA 2023_02_22 rtf
15555 001 andrew_comp Missing 'Italy'
42567 001 mike_comp Cancun Mexico 2023_03_12 rtf
42567 001 mike_comp Montreal Canada 2023_03_11 txt
42567 001 mike_comp Missing 'Canada'

12345 001 group - all files are there and get outputted.

12345 002 group - all files are there and get outputted.

15555 001 group - 3/4 files are there and get outputted along with the missing file.

42567 001 group - 2/4 files are there and get outputted however the 2 missing files Italy & USA do not get outputted. Adding insult to injury it outputs 'Missing Canada' which is not really missing.

1

There are 1 best solutions below

6
TheMadTechnician On

You can group by ComputerId and ProcessID, then in a ForEach-Object loop you can check for missing countries like this:

#splitFile
$numberedFolder = 'C:\Users\Documents\My Documents\PowerShell\Test'
$outputFile = "C:\Users\Documents\My Documents\PowerShell\Results_$(Get-Date -f yyyy-MM-dd-hh-mm-ss).csv"
Get-ChildItem -Directory -Recurse -LiteralPath $numberedFolder -Filter '2023' |
    Get-ChildItem -File |
    Select-Object @{name='computer id';Expression={$_.Name.Split('.')[0]}},
    @{name='process id';Expression={ '{0:d3}' -f [int]$_.Name.Split('.')[1]}}, #trying to preverse leading 0's. will always be 3 digits long.
    @{name='computer name';Expression={$_.Name.Split('.')[2]}},
    @{name='city';Expression={$_.Name.Split('.')[3]}},
    @{name='country';Expression={$_.Name.Split('.')[4]}},
    @{name='date';Expression={$_.Name.Split('.')[5]}},
    @{name='file extension';Expression={$_.Name.Split('.')[6]}} |
    Group 'computer name','process id' -PipelineVariable 'Group'|
    ForEach-Object {
        # Pass all objects that exist
        $_.group
        # Check for missing objects, and create a 'Missing item' object for any missing ones
        If($_.Count -ne 4){
        switch($_.group){
            {'Mexico' -notin $_.Country}{[PSCustomObject]@{'Computer id'="Missing 'Mexico'"}}
            {'Canada' -notin $_.country}{[PSCustomObject]@{'computer id'="Missing 'Canada'"}}
            {'Italy' -notin $_.country}{[PSCustomObject]@{'computer id'="Missing 'Italy'"}}
            {'USA' -notin $_.country}{[PSCustomObject]@{'computer id'="Missing 'USA'"}}
        } # End Switch
    } # End If
    } |
    Export-Csv -Path $outputFIle -Append -NoTypeInformation