Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save futuremotiondev/9b73861835f92b432f76e8c5ed87706c to your computer and use it in GitHub Desktop.
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.
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