problem with sort-object and select-object

Robert Little 1 Reputation point
2022-01-20T13:37:52.93+00:00

I am trying to use Sort-Object and Select-Object to keep (and delete) X number of sub folders (c:\temp\temp_yyyymmdd) ) in a particular folder (c:\temp) . There are several examples out there of this, but I wanted to understand why my code isn't working. I am trying to use Sort-Object to sort the subfolders by creation time (this works) and then use Select-Object -First (I've tried -Last and -Skip as well) to isolate the 2 most recent folders that I want to keep and then delete all others.

In the example folder structure below I would want to keep the 2 most recent and delete the older 3.

c:\temp\
c:\temp\temp_20211102
c:\temp\temp_20211124
c:\temp\temp_20211208
c:\temp\temp_20220119
c:\temp\temp_20220120

code is below

function Remove-OldBackups
{
    $numberToRetain = 1
    write-host ""
    write-host "now running Remove-OldBackups"

    write-host "AppInstanceRootPath is $AppInstanceRootPath"
    write-host "AppInstanceName is $AppInstanceName (we're excluding this folder)"

    #$itemsToDelete = get-childitem -Path $AppInstanceRootPath -Exclude $AppInstanceName | Select-String -Pattern $AppInstanceName | Sort-Object -Property CreationDate -Descending | Select-Object -last 
    $itemsToDelete = get-childitem -Path $AppInstanceRootPath -Exclude $AppInstanceName | Select-String -Pattern $AppInstanceName | Sort-Object -Property CreationDate -Descending | Select-Object -First $numberToRetain

    write-host ""
    write-host "items to delete are"
    $itemsToDelete
    write-host ""

    write-host ""
    write-host "Now removing old instance backups on $env:computername\$AppInstanceRootPath"

    foreach ($folder in $itemsToDelete)
    {
        write-host "folder to delete is $folder"
        #Get-ChildItem -Directory $folder * -Recurse | Remove-Item
        #Remove-Item -Recurse -Force $folder
    }
}
Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,449 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Andreas Baumgarten 103.4K Reputation points MVP
    2022-01-20T13:50:59.043+00:00

    Hi @Robert Little ,

    I am not sure what happens here with the Select-String -Pattern $AppInstanceName in you code. If I remember right the output of Select-String is a string or boolean.
    This would not work with the next pipe Sort-Object because Sort-Object expects objects and not strings.

    What is the output of $itemsToDelete = get-childitem -Path $AppInstanceRootPath -Exclude $AppInstanceName | Select-String -Pattern $AppInstanceName without the Sort-Object and the Select-Object?

    ----------

    (If the reply was helpful please don't forget to upvote and/or accept as answer, thank you)

    Regards
    Andreas Baumgarten

    0 comments No comments

  2. Rich Matheisen 45,671 Reputation points
    2022-01-20T15:51:21.1+00:00

    If your intention is to deal with only directory names and not with directory names and any files in the root of your search, then you should add "-Dir" to the Get-ChildItem. You also need to pay attention to the output types of Select-String:

    Outputs
    Microsoft.PowerShell.Commands.MatchInfo or System.Boolean

    By default, the output is a set of MatchInfo objects with one for each match found. If you use the Quiet parameter, the output is a Boolean value indicating whether the pattern was found.

    And you need to pay attention to the Select-String inputs. You're feeding it objects of the type System.IO.FileSystemInfo.

    I'm not sure why you first EXCLUDE $AppInstanceName in the Get-ChildItem and then use that same pattern in your Select-Object.

    Try replacing the selection code with something like this:

    $itemsToDelete = Get-ChildItem -Path $AppInstanceRootPath -Exclude $AppInstanceName -Dir |
        Where-Object ($_.ToString() -match $AppInstanceName) | # not sure why you want to match this after excluding in in Get-ChildItem!
            Sort-Object -Property CreationDate -Descending | 
                Select-Object -Property FullName -First $numberToRetain
    
    0 comments No comments