Search code examples
powershellget-childitem

Using Array and get-childitem to find filenames with specific ids


In the most basic sense, I have a SQL query which returns an array of IDs, which I've stored into a variable $ID. I then want to perform a Get-childitem on a specific folder for any filenames that contain any of the IDs in said variable ($ID) There are three possible filenames that could exist:

  • $ID.xml
  • $ID_input.xml
  • $ID_output.xml

Once I have the results of get-childitem, I want to output this as a text file and delete the files from the folder. The part I'm having trouble with is filtering the results of get-childitem to define the filenames I'm looking for, so that only files that contain the IDs from the SQL output are displayed in my get-childitem results.

I found another way of doing this, which works fine, by using for-each ($i in $id), then building the desired filenames from that and performing a remove item on them:

# Build list of XML files
$XMLFile = foreach ($I in $ID)
        {
          "$XMLPath\$I.xml","$XMLPath\$I`_output.xml","$XMLPath\$I`_input.xml"
        }

# Delete XML files
$XMLFile | Remove-Item -Force

However, this produces a lot of errors in the shell, as it tries to delete files that don't exist, but whose IDs do exist in the database. I also can't figure out how to produce a text output of the files that were actually deleted, doing it this way, so I'd like to get back to the get-childitem approach, if possible.

Any ideas would be greatly appreciated. If you require more info, just ask.


Solution

  • You can find all *.xml files with Get-ChildItem to minimize the number of files to test and then use regex to match the filenames. It's faster than a loop/multiple test, but harder to read if you're not familiar with regex.

    $id = 123,111
    
    #Create regex-pattern (search-pattern)
    $regex = "^($(($id | ForEach-Object { [regex]::Escape($_) }) -join '|'))(?:_input|_output)?$"
    
    $filesToDelete = Get-ChildItem -Path "c:\users\frode\Desktop\test" -Filter "*.xml" | Where-Object { $_.BaseName -match $regex }
    
    #Save list of files
    $filesToDelete | Select-Object -ExpandProperty FullName | Out-File "deletedfiles.txt" -Append
    
    #Remove files (remove -WhatIf when ready)
    $filesToDelete | Remove-Item -Force -WhatIf
    

    Regex demo: https://regex101.com/r/dS2dJ5/2