How to remove item from an array in PowerShell?
The best way to do this is to use Where-Object
to perform the filtering and use the returned array.
You can also use @splat
to pass multiple parameters to a command (new in V2). If you cannot upgrade (and you should if at all possible, then just collect the output from Get-ChildItems (only repeating that one CmdLet) and do all the filtering in common code).
The working part of your script becomes:
$moreArgs = @{}if (-not $NoRecurse) { $moreArgs["Recurse"] = $true}$filesToDelete = Get-ChildItem $BackupDir @moreArgs | where-object {-not $_.PsIsContainer -and $_.LastWriteTime -lt $(Get-Date).AddDays($days) -and -not $_.FullName.Contains($exclusion)}
In PSH arrays are immutable, you cannot modify them, but it very easy to create a new one (operators like +=
on arrays actually create a new array and return that).
I agree with Richard, that Where-Object
should be used here. However, it's harder to read.What I would propose:
# get $filesToDelete and #exclusionList. In V2 use splatting as proposed by Richard.$res = $filesToDelete | % { $file = $_ $isExcluded = ($exclusionList | % { $file.FullName.Contains($_) } ) if (!$isExcluded) { $file }}#the files are in $res
Also note that generally it is not possible to iterate over a collection and change it. You would get an exception.
$a = New-Object System.Collections.ArrayList$a.AddRange((1,2,3))foreach($item in $a) { $a.Add($item*$item) }An error occurred while enumerating through a collection:At line:1 char:8+ foreach <<<< ($item in $a) { $a.Add($item*$item) } + CategoryInfo : InvalidOperation: (System.Collecti...numeratorSimple:ArrayListEnumeratorSimple) [], RuntimeException + FullyQualifiedErrorId : BadEnumeration
This is ancient. But, I wrote these a while ago to add and remove from powershell lists using recursion. It leverages the ability of powershell to do multiple assignment . That is, you can do $a,$b,$c=@('a','b','c')
to assign a b and c to their variables. Doing $a,$b=@('a','b','c')
assigns 'a'
to $a
and @('b','c')
to $b
.
First is by item value. It'll remove the first occurrence.
function Remove-ItemFromList ($Item,[array]$List(throw"the item $item was not in the list"),[array]$chckd_list=@()){ if ($list.length -lt 1 ) { throw "the item $item was not in the list" } $check_item,$temp_list=$list if ($check_item -eq $item ) { $chckd_list+=$temp_list return $chckd_list } else { $chckd_list+=$check_item return (Remove-ItemFromList -item $item -chckd_list $chckd_list -list $temp_list ) }}
This one removes by index. You can probably mess it up good by passing a value to count in the initial call.
function Remove-IndexFromList ([int]$Index,[array]$List,[array]$chckd_list=@(),[int]$count=0){ if (($list.length+$count-1) -lt $index ) { throw "the index is out of range" } $check_item,$temp_list=$list if ($count -eq $index) { $chckd_list+=$temp_list return $chckd_list } else { $chckd_list+=$check_item return (Remove-IndexFromList -count ($count + 1) -index $index -chckd_list $chckd_list -list $temp_list ) }}