Fully parameterized PowerShell function for file removal I would like your opinion on my Remove-Files PowerShell function. It is used in my File-Removal-PowerShell-Script. It is designed to be very flexible so a script user can have configure it to remove files in multiple and various way as it often the chase.
Remove-Files function
function Remove-Files {
    [CmdletBinding(SupportsShouldProcess = $true)]
    [OutputType([PSCustomObject])]
    param (
        [Parameter(Position = 0, Mandatory, ValueFromPipelineByPropertyName)]
        [string]
        $FolderPath,

        [Parameter(Position = 1, Mandatory, ValueFromPipelineByPropertyName)]
        [string]
        $FileName,

        [Parameter(Position = 2, ValueFromPipelineByPropertyName)]
        [int]
        $OlderThen = 0,

        [Parameter(Position = 3, ValueFromPipelineByPropertyName)]
        [string]
        $Recurse = &quot;false&quot;,

        [Parameter(Position = 4, ValueFromPipelineByPropertyName)]
        [string]
        $Force = &quot;false&quot;
    )

    begin {
        $DateToDelete = (Get-Date).AddDays(- $OlderThen)
    }

    process {
        $FolderSpaceFreed = 0
        $FilesRemoved = 0
        $FailedRemovals = 0

        if (-not (Test-Path -Path $FolderPath)) {
            Write-Log -Message &quot;ERROR: $FolderPath folder does not exist&quot;
            return
        }

        $FullPath = Join-Path -Path $FolderPath -ChildPath $FileName

        if ($Recurse -eq &quot;true&quot;) {
            $FileList = Get-ChildItem -Path $FullPath -Recurse
        }
        else {
            $FileList = Get-ChildItem -Path $FullPath
        }

        $FileList = $FileList | Where-Object {$_.LastWriteTime -lt $DateToDelete}

        foreach ($File in $FileList) {
            $FileSize  = (Get-Item -Path $File.FullName).Length
            $SpaceFreed = Get-FormattedFileSize -Size $FileSize

            if ($Force -eq &quot;true&quot;) {
                Get-Item -Path $File.FullName | Remove-Item -Force
            }
            else {
                Get-Item -Path $File.FullName | Remove-Item
            }

            if (-not (Test-Path -Path $File.FullName)) {
                $Message = &quot;Successfully deleted &quot; + $File.Name + &quot; file - removed $SpaceFreed&quot;
                $FolderSpaceFreed += $FileSize
                $FilesRemoved ++
            }
            else {
                $Message = &quot;Failed to delete &quot; + $File.Name + &quot; file&quot;
                $FailedRemovals ++
            }
            Write-Log -Message $Message
        }

        $SpaceFreed = Get-FormattedFileSize -Size $FolderSpaceFreed

        if ($FilesRemoved -gt 0) {
            Write-Log -Message &quot;Successfully deleted $FilesRemoved files in $FolderPath folder, and $SpaceFreed of space was freed&quot;
        }
        if ($FailedRemovals -gt 0) {
            Write-Log -Message &quot;Failed to delete $FailedRemovals files in $FolderPath folder&quot;
        }
        if ($FilesRemoved -eq 0 -and $FailedRemovals -eq 0) {
            Write-Log -Message &quot;No files for delition were found in $FolderPath folder&quot;
        }
        New-Object -TypeName psobject -Property @{
            FolderSpaceFreed =  $FolderSpaceFreed
            FilesRemoved = $FilesRemoved
            FailedRemovals = $FailedRemovals
        }
    }
}

Before someone says anything about it, I have to tell you why I did not use a switch type for -Recurse and -Force parameters, and it is because the function is feed from .csv file with data, and I did not find a elegant way to pass string value to a switch parameter.
I have found a way to use pass string values to switch parameters to Remove-Files function so I have refactored the function ho have two switch parameters.
The new version
function Remove-Files {
    [CmdletBinding(SupportsShouldProcess = $true)]
    [OutputType([PSCustomObject])]
    param (
        [Parameter(Mandatory = $true,
                   Position = 0,
                   ParameterSetName = &quot;FolderPath&quot;,
                   ValueFromPipeline = $false,
                   ValueFromPipelineByPropertyName = $true,
                   HelpMessage = &quot;Full folder path in which file/files are to be deleted&quot;)]
        [string]
        $FolderPath,

        [Parameter(Mandatory = $true,
                   Position = 1,
                   ParameterSetName = &quot;FileName&quot;,
                   ValueFromPipeline = $false,
                   ValueFromPipelineByPropertyName = $true,
                   HelpMessage = &quot;File name that can include wildcard character&quot;)]
        [SupportsWildcards()]
        [string]
        $FileName,

        [Parameter(Mandatory = $false,
                   Position = 2,
                   ParameterSetName = &quot;OlderThen&quot;,
                   ValueFromPipeline = $false,
                   ValueFromPipelineByPropertyName = $true,
                   HelpMessage = &quot;Number of days to delete files older than that&quot;)]
        [int]
        $OlderThen = 0,

        [Parameter(Mandatory = $false,
                   Position = 3,
                   ParameterSetName = &quot;Recurse&quot;,
                   ValueFromPipeline = $false,
                   ValueFromPipelineByPropertyName = $true,
                   HelpMessage = &quot;Switch on to file remove files in subfolders&quot;)]
        [switch]
        $Recurse = $false,

        [Parameter(Mandatory = $false,
                   Position = 4,
                   ParameterSetName = &quot;Force&quot;,
                   ValueFromPipeline = $false,
                   ValueFromPipelineByPropertyName = $true,
                   HelpMessage = &quot;Switch on to force remove files&quot;)]
        [switch]
        $Force = $false
    )

    process {
        $FolderSpaceFreed = 0
        $FilesRemoved = 0
        $FailedRemovals = 0

        if (-not (Test-Path -Path $FolderPath)) {
            Write-Log -Message &quot;ERROR: $FolderPath folder does not exist&quot;
            return
        }

        $FullPath = Join-Path -Path $FolderPath -ChildPath $FileName

        if ($Recurse) {
            $FileList = Get-ChildItem -Path $FullPath -Recurse
        }
        else {
            $FileList = Get-ChildItem -Path $FullPath 
        }

        $DateToDelete = (Get-Date).AddDays(- $OlderThen)

        $FileList = $FileList | Where-Object {$_.CreationTime -lt $DateToDelete}

        foreach ($File in $FileList) {
            $FileSize  = (Get-Item -Path $File.FullName).Length
            $SpaceFreed = Get-FormattedFileSize -Size $FileSize

            if ($Force) {
                Get-Item -Path $File.FullName | Remove-Item -Force
            }
            else {
                Get-Item -Path $File.FullName | Remove-Item
            }

            if (-not (Test-Path -Path $File.FullName)) {
                $Message = &quot;Successfully deleted &quot; + $File.Name + &quot; file - removed $SpaceFreed&quot;
                $FolderSpaceFreed += $FileSize
                $FilesRemoved ++
            }
            else {
                $Message = &quot;Failed to delete &quot; + $File.Name + &quot; file&quot;
                $FailedRemovals ++
            }
            Write-Log -Message $Message
        }

        $SpaceFreed = Get-FormattedFileSize -Size $FolderSpaceFreed

        if ($FilesRemoved -gt 0) {
            Write-Log -Message &quot;Successfully deleted $FilesRemoved files in $FolderPath folder, and $SpaceFreed of space was freed&quot;
        }
        if ($FailedRemovals -gt 0) {
            Write-Log -Message &quot;Failed to delete $FailedRemovals files in $FolderPath folder&quot;
        }
        if ($FilesRemoved -eq 0 -and $FailedRemovals -eq 0) {
            Write-Log -Message &quot;No files for delition were found in $FolderPath folder&quot;
        }
        New-Object -TypeName psobject -Property @{
            FolderSpaceFreed =  $FolderSpaceFreed
            FilesRemoved = $FilesRemoved
            FailedRemovals = $FailedRemovals
        }
    }
}