0

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.

cthorn112
  • 13
  • 4
  • Personally I would group by ComputerId and ProcessId, then if there are 4 files in the group pass them down the pipeline, and if not pass what you have, and determine what is missing (something like `switch($_.group){{'Mexico' -notin $_.Country}{@{'Computer id'="Missing 'Mexico'"};{'Canada' -notin $_.country}{@{'computer id'="Missing 'Canada'"};}`) – TheMadTechnician Aug 24 '23 at 18:27
  • makes sense since the combination of those two will always have a unique country. Sounds like I'm going to need to put it before the select-object and then pipeline into or am I way off? – cthorn112 Aug 24 '23 at 19:19
  • after the select actually. You'll want to use properties that you create in your select as part of it. I'd put it just before the `|Export-Csv` – TheMadTechnician Aug 24 '23 at 19:22
  • I tried playing with syntax, adding a comma at the end of Split(.)[6] and moving the | around but no luck... ` @{name='file extension';Expression={$_.Name.Split('.')[6]}} switch($_.group) { {'Canada' -notin $_.country}{ @{'computer id'="Missing 'Canada'"}; {'Italy' -notin $_.country} @{'computer id'="Missing 'Italy'"}; {'Mexico' -notin $_.country} @{'computer id'="Missing 'Mexico'"}; {'USA' -notin $_.country} @{'computer id'="Missing 'USA'"} }} | Export-Csv ] – cthorn112 Aug 25 '23 at 16:55

1 Answers1

0

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
TheMadTechnician
  • 34,906
  • 3
  • 42
  • 56
  • Thank you for helping me out TheMadTechnician! Ran the code and got back error messages that started with "Unable to find type [PSComputerObject].." Did some googling and looks like I'm in over my head. Do I need to declare? I'm running on PSVersion 5.1 Unable to find type [PSComputerObject]. At line:19 char:43 + {'Mexico' -notin $_.country}{[PSComputerObject]@{'compute ... + ~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (PSComputerObject:TypeName) [], RuntimeException + FullyQualifiedErrorId : TypeNotFound – cthorn112 Aug 25 '23 at 19:59
  • Sorry, that should have been `[PSCustomObject]` not `[PSComputerObject]`. I updated the answer to reflect the correction. I blame it on trying to do too many things on a Friday before vacation. – TheMadTechnician Aug 25 '23 at 21:06
  • No worries, the thought did not occur for me to change it. I ran the code and did not get the desired output. Too long for me to copy here but basically it's listing out each country whether missing or not in addition to the correct output. I'm thinking it might have to do with the @{'Computer id'="Missing 'Mexico'"} part. I'm gonna mess around with it. – cthorn112 Aug 25 '23 at 21:30
  • just realized I should be outputting computer id + process id instead of just process id. {'Mexico' -notin $_.Country}{[PSCustomObject]@{'Computer id'="Missing 'Mexico'"}} I'm still unable to output the missing file, see the original post where Missing 'Italy' file for '15555.001'. any ideas on where I'm going wrong? – cthorn112 Aug 28 '23 at 14:50
  • So I made some progress with formatting the outputted values into their respective columns. Latest dilemma, if there is more than 1 country missing it will not return additional countries. Probably because of the break but if I don't include the break it returns too many missing countries that are not really missing. I only included the first row of code since I'm limited to the number of characters. {'Canada' -notin $_.country} {[PSCustomObject]@{'computer id' = $_.'computer id'; 'process id' = $_.'process id'; 'computer name' = $_.'computer name'; 'country' = "Missing 'Canada'"};break} – cthorn112 Aug 29 '23 at 14:28