0

I have a script (below) which works perfectly when run on one test directory on a network drive, but is not fully accurate when modified to be run on all the directories (27 in total) on the same drive it is intended to be run on. The script's purpose is to retain the most up-to-date file as determined either; by virtue of the fact that that the file has never been superseded*, or, by any numeric value that may appear between the 3rd and 4th underscore (SECTION) of the file name.

File name format = NAME_DATE_SEQUENCE(reinserted in file as a 3-digit-numer)_SECTION_SEGMENT_SEQUENCE

For example if script encounters the following files in folder X of any of the directories..:

Name_20240301_001_SectionName_SegmentName_1.pdf and Name_20240301_001_SectionName2_SegmentName_1.pdf

.. it should retain the file with the greatest value apparent in the SECTION field and move any files that match the non-numeric part of the SECTION as well as NAME, DATE, SEQUENCE and SEGMENT, but have lesser or no numeric values in the SECTION, to a specific folder to be checked.

  • Some files will never be superseded, therefore will have no file that is a perfect match for all fields but the SECTION, and these need to be retained too.

So when I add all 27 directories I want this to apply to, do I need to duplicate the following script for each directory to help it proceed one directory at a time if resources are an issue, or is there some other way to list all required directories and apply it recursively whilst still keeping it accurate?

Script:

function Get-SectionNumber {
    param([string]$fileName)

    $parts = $fileName -split '_'
    if ($parts.Count -ge 4) {
        $sectionPart = $parts[3]
        $match = [regex]::Match($sectionPart, '(\d+)')
        if ($match.Success) {
            return [int]$match.Value
        }
    }
    return $null
}

function Get-SectionNonNumeric {
    param([string]$fileName)

    $parts = $fileName -split '_'
    if ($parts.Count -ge 4) {
        $sectionPart = $parts[3]
        $match = [regex]::Match($sectionPart, '(\D+)')
        if ($match.Success) {
            return $match.Value
        }
    }
    return $null
}

$sourceDirectory = "Drive:\Path1\Path1......"

$CheckDeletedDirectory = "Drive:\Path2\Path2......"

$files = Get-ChildItem -Path $sourceDirectory -File -Recurse

 portion of the section for grouping
$groupedFiles = $files | Group-Object { ($_.Name -split '_', 4)[0..2] -join '_' + '_' + (Get-SectionNonNumeric $_.Name) }

foreach ($group in $groupedFiles) {

    $sortedGroup = $group.Group | Sort-Object @{Expression={Get-SectionNumber $_.Name}; Descending=$true}

    $topFile = $sortedGroup[0]
    $sortedGroup[1..($sortedGroup.Count - 1)] | ForEach-Object {
        Move-Item -Path $_.FullName -Destination $catchDirectory -Force
        Write-Host "Moved $($file.FullName) to $CheckDeletedDirectory"
    }

       Write-Host "Retained file: $($topFile.FullName)"
}

Tried adding in all directories I want this run on, (27 in total)... changing $sourceDirectory to $sourceDirectories in case that made a difference What has me stumped is it initially ran perfectly on my C:\ drive with a much more simplistic mock directory/folder structure... and had also worked on the network drive it is intended to run on using a mock up example of the same directory depth structure present there, albeit for just 2 folders containing files. The only differences between successful and unsuccessful runs are the number of directories, subfolders and files involved.

4
  • “Tried adding in all directories I want this run on” - can you show the code you used for this, and explain what went wrong with it exactly? Did you get an error? Did it behave in an unexpected way? Commented Mar 2, 2024 at 8:57
  • @mclayton No error, the files it moved had nothing to do with the in-script logic and superseded and superseding files remained in the source directories # Specify the directories to search $baseDirectories = @( "V:\Path1..." "V:\Path2...", "V:\Path3...", Etc Etc.... ) # Path to the directory for moving unmatched files $CheckDeletedDirectory = "V:\CheckDeletePath" # Initialize counters $processedCount = 0 $retainedCount = 0 # Get all files in subfolders of the source directory $files = Get-ChildItem -Path $baseDirectories -File -Recurse Commented Mar 2, 2024 at 10:19
  • Simple solution is when there is no number return -1. You will only need one function instead of two. Commented Mar 2, 2024 at 11:36
  • @jdweng and mclayton thanks to you both! Just solved it! Problem was in my grouping logic... the segment inclusion fell off in between script iterations.. revised to the following, and working fine!: $groupedFiles = $files | Group-Object { ($_.Name -split '', 4)[0..2] -join '', (Get-SectionNonNumeric $_.Name), ($_.Name -split '_')[4] } Commented Mar 2, 2024 at 12:26

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.