Created
February 7, 2025 23:05
-
-
Save futuremotiondev/9b73861835f92b432f76e8c5ed87706c to your computer and use it in GitHub Desktop.
Accumulates files from all directories or files passed into the function and then processes in parallel at the end block. Supports wildcards, pipeline input, and literal paths.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using namespace System.IO | |
using namespace System.Collections.Generic | |
function Convert-ParallelFileAccumulator { | |
[CmdletBinding(DefaultParameterSetName='Path')] | |
param ( | |
# Define the 'Path' parameter, allowing wildcards and pipeline input | |
[Parameter( | |
Mandatory, | |
Position = 0, | |
ValueFromPipeline, | |
ValueFromPipelineByPropertyName, | |
ParameterSetName = "Path", | |
HelpMessage="Path to one or more locations." | |
)] | |
[SupportsWildcards()] | |
[ValidateNotNullOrEmpty()] | |
[String[]] $Path, | |
# Define the 'LiteralPath' parameter, disallowing wildcards and requiring absolute paths | |
[Parameter( | |
Mandatory, | |
Position = 0, | |
ValueFromPipelineByPropertyName, | |
ParameterSetName = "LiteralPath", | |
HelpMessage="Literal path to one or more locations." | |
)] | |
[ValidateScript({$_ -notmatch '[\?\*]'}, | |
ErrorMessage = "Wildcard characters *, ? are not acceptable with -LiteralPath")] | |
[ValidateScript({[System.IO.Path]::IsPathRooted($_)}, | |
ErrorMessage = "Relative paths are not allowed in -LiteralPath.")] | |
[Alias('PSPath')] | |
[ValidateNotNullOrEmpty()] | |
[String[]] $LiteralPath, | |
# Optional switch to enable recursive search | |
[Switch] $Recurse | |
) | |
begin { | |
# Function to validate if a file has an acceptable extension | |
function ValidateFile { | |
param ( [String] $File ) | |
($File -match "^.+\.(svg|png|bmp|gif)$") # Match specific file extensions | |
} | |
# Initialize a HashSet to store unique file paths | |
$fileList = [HashSet[String]]::new() | |
} | |
process { | |
# Resolve paths based on provided parameters | |
$resolvedPaths = if($PSBoundParameters['Path']) { | |
$Path | Get-Item -Force | |
} elseif($PSBoundParameters['LiteralPath']) { | |
$LiteralPath | Get-Item -Force | |
} | |
# Iterate over each resolved path | |
$resolvedPaths | % { | |
$currentItem = $_.FullName | |
# Check if the current item is a directory | |
if (Test-Path -LiteralPath $currentItem -PathType Container) { | |
# Prepare parameters for Get-ChildItem | |
$gciSplat = @{ | |
LiteralPath = $currentItem | |
Force = $true | |
ErrorAction = 'SilentlyContinue' | |
File = $true | |
} | |
# Add recursion option if specified | |
if($PSBoundParameters.ContainsKey('Recurse')){ | |
$gciSplat['Recurse'] = $true | |
} | |
# Retrieve child items from the directory | |
$childItems = Get-ChildItem @gciSplat | |
if($childItems){ | |
foreach ($item in $childItems) { | |
# Validate and add files to the list | |
if(ValidateFile $item){ | |
$null = $fileList.Add($item) | |
} | |
} | |
} | |
# Check if the current item is a file | |
} elseif(Test-Path -LiteralPath $currentItem -PathType Leaf) { | |
# Validate and add the file to the list | |
if(ValidateFile $currentItem){ | |
$null = $fileList.Add($currentItem) | |
} | |
} | |
} | |
} | |
end { | |
# Process each file in parallel | |
$fileList | ForEach-Object -Parallel { | |
$currentFile = Get-Item -LiteralPath $_ -Force | |
# Placeholder for additional processing code | |
# Code goes here | |
} -ThrottleLimit 24 # Limit the number of concurrent threads | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment