locked
PowerShell Get-Childitem -Include with multiple items in the include? RRS feed

  • Question

  • I'm working on a script.  Part of it is to delete files from a folder older than X number of days.  I want to limit to types of *.bak, *.trn, and *.diff.  It works perfectly if I pass in one of those types at a time but I fail to figure out how to use the -Include modifer so that all three can be pass in at once.  Do any of you guys know how?
    Joe Moyle
    Friday, February 19, 2010 8:12 PM

Answers

  • Joe

    You ever see "Get Smart" when he says "It was THIS CLOSE!"

    You already had the answer! Kill the Quotes.

    I just ran this on my own system

    GET-CHILDITEM -Recurse -include *.doc,*.txt

    Recursed through a structure and pulled up all *.doc and *.txt files

    So your script I THINK should be


    $INCLUDE='*.trn,*.bak,*.diff'

    $Files = Get-Childitem $Folder_Path -Recurse -Include $Include | Where {$_.LastWriteTime -le $Last_Write}


    I think the " (Double Quotes) were killing the results on the input.  

    Sean
    The Energized Tech

    • Marked as answer by IamMred Friday, April 30, 2010 1:36 AM
    Friday, February 19, 2010 9:34 PM
  • You need to specify your $Include variable as an array, eg

    $Include=@("*.trn","*.bak","*.diff")

    Then you should be able to call you script with the single line vairable, eg

    $Files = Get-Childitem $Folder_Path -Recurse -Include "$Include" | `
        Where {$_.LastWriteTime -le "$Last_Write"}

    • Proposed as answer by Daniel Horwood Sunday, August 8, 2010 6:56 AM
    • Marked as answer by Joe Moyle Monday, August 9, 2010 5:04 PM
    Sunday, August 8, 2010 6:56 AM
  • I'm bummed out to find it just doesn't seem to work.  I've settled for the following in the parent script

    Delete_Files_Older_Than_X_Days -Days_Back 7 -Folder_Path $Backup_Folder -Include "*.bak"
    Delete_Files_Older_Than_X_Days -Days_Back 7 -Folder_Path $Backup_Folder -Include "*.diff"
    Delete_Files_Older_Than_X_Days -Days_Back 7 -Folder_Path $Backup_Folder -Include "*.trn"

    and the following in the child script

      If ($Include)
      {
       $Files = Get-Childitem $Folder_Path -Recurse -Include $Include | `
        Where {$_.LastWriteTime -le "$Last_Write"}
      }

    It works but I'd sure like a more elegant solution.
    Joe Moyle
    • Marked as answer by IamMred Friday, April 30, 2010 1:36 AM
    Sunday, February 28, 2010 3:00 AM

All replies

  • I thought I had better provide a little code snippet.  This is the part of my script I am having trouble with.

       $Files = Get-Childitem $Folder_Path -Recurse -Include "$Include" | `
        Where {$_.LastWriteTime -le "$Last_Write"}

    I pass in the value of $Include from a calling script.  I currently pass in "*.trn" or "*.bak" or "*.diff".  I've tried the following to no avail

    "*.trn,*.diff,*.bak"

    "*.trn","*.bak","*.diff"

    I've also tried multiple include clauses like -Include "*.trn" -Include "*.bak".
    Joe Moyle
    Friday, February 19, 2010 8:28 PM
  • Joe

    You ever see "Get Smart" when he says "It was THIS CLOSE!"

    You already had the answer! Kill the Quotes.

    I just ran this on my own system

    GET-CHILDITEM -Recurse -include *.doc,*.txt

    Recursed through a structure and pulled up all *.doc and *.txt files

    So your script I THINK should be


    $INCLUDE='*.trn,*.bak,*.diff'

    $Files = Get-Childitem $Folder_Path -Recurse -Include $Include | Where {$_.LastWriteTime -le $Last_Write}


    I think the " (Double Quotes) were killing the results on the input.  

    Sean
    The Energized Tech

    • Marked as answer by IamMred Friday, April 30, 2010 1:36 AM
    Friday, February 19, 2010 9:34 PM
  • Thanks Sean.  I'll try it out at my earliest convenience and update this thread with the outcome.

    If it works I'll attribute my failure to getting up at 3:30 AM this morning, drinking too much coffee today, and I reaching a point when I posted where my eyes were swimming from being in front of the screen in "debug mode" all day.  :)
    Joe Moyle
    Friday, February 19, 2010 10:43 PM
  • Joe

    Ahhhh so you mean an "a typical day for an ITPro" ;)

    Sean
    The Energized Tech
    Powershell. It's so Easy and it's FREE! Dive in and use it now, It'll take no time. :) http://www.energizedtech.com
    Sunday, February 21, 2010 4:30 PM
  • I'm bummed out to find it just doesn't seem to work.  I've settled for the following in the parent script

    Delete_Files_Older_Than_X_Days -Days_Back 7 -Folder_Path $Backup_Folder -Include "*.bak"
    Delete_Files_Older_Than_X_Days -Days_Back 7 -Folder_Path $Backup_Folder -Include "*.diff"
    Delete_Files_Older_Than_X_Days -Days_Back 7 -Folder_Path $Backup_Folder -Include "*.trn"

    and the following in the child script

      If ($Include)
      {
       $Files = Get-Childitem $Folder_Path -Recurse -Include $Include | `
        Where {$_.LastWriteTime -le "$Last_Write"}
      }

    It works but I'd sure like a more elegant solution.
    Joe Moyle
    • Marked as answer by IamMred Friday, April 30, 2010 1:36 AM
    Sunday, February 28, 2010 3:00 AM
  • You need to specify your $Include variable as an array, eg

    $Include=@("*.trn","*.bak","*.diff")

    Then you should be able to call you script with the single line vairable, eg

    $Files = Get-Childitem $Folder_Path -Recurse -Include "$Include" | `
        Where {$_.LastWriteTime -le "$Last_Write"}

    • Proposed as answer by Daniel Horwood Sunday, August 8, 2010 6:56 AM
    • Marked as answer by Joe Moyle Monday, August 9, 2010 5:04 PM
    Sunday, August 8, 2010 6:56 AM
  • Thanks for the reply Daniel.  I'll give that a try when I'm in the office tomorrow.  I'll update this forum with the results.
    Joe Moyle
    Sunday, August 8, 2010 7:04 PM
  • That did the trick Daniel.  Thank you so much for this technique!  I'm sure it will come in handy in many scripts.
    Joe Moyle
    Monday, August 9, 2010 5:05 PM
  • Yes, thanks - I found this useful as well. And also wanted to note that the PATH parameter can act a little squirrely too. Rather than using quotes for paths that had spaces in their names,  I got around that by using parens like so:

    gci -Path($Myfolder) -recurse-filter"$Myfilespec"-exclude*temp*,*tmp*-Verbose

    • Proposed as answer by jadelise Saturday, June 2, 2012 5:37 PM
    • Unproposed as answer by jadelise Saturday, June 2, 2012 5:39 PM
    Tuesday, March 20, 2012 8:31 PM
  • get-childitem $_Folder_Root -include *  -force  | Remove-Item   -recurse -force -whatif

    Output

    What if: Performing operation "Remove Directory" on Target "\\ComputerName\temp-storage\!_Info".
    What if: Performing operation "Remove Directory" on Target "\\ComputerName\temp-storage\$RECYCLE.BIN".
    What if: Performing operation "Remove Directory" on Target "\\ComputerName\temp-storage\System Volume Information".
    What if: Performing operation "Remove File" on Target "\\ComputerName\temp-storage\AFileWeWantToDelete.txt".

    An example can be helpful, this is derived from the earlier posts, thanks everyone, this was very helpful.

    Without the -exclude above, note the use of -whatif to see what would happen, not do what would happens.

    # Full working example, use at your own risk. Change the Computer name and share to your TEST! environment
    # Delete everything under this folder but the excluded items in the array variable $_Excluded_Items
    $_Folder_Root = "\\YourValidONlineComputerNameHere\YourValidShareYouHaveRightsToAccessHere"

    # Add items as seen here, you may use wild cards, this is the part this post taught me.
    # Note that the earlier post that I thought implied that the -include and -exclude could not be used
    # together are proved wrong here.

    # Create an array of exclude items.

    $_Excluded_Items = @("*$RECYCLE.BIN*","*System Volume Information*")

    # These items would normally not be deletable. It's up to you to identify what goes in there.

    # Test using whatif as seen here
    # When you remove the -exclude and it's array variable and use -whatif you can see what would be deleted
    # if you didn't exclude the items. When you do use the -exclude you can check the output using -whatif to make sure
    # you are excluding what you want. Very important when doing a recursive deletions.
    # Snakes! Very dangerous.

    # This line will do the deletion if you take off the -whatif

    get-childitem $_Folder_Root -include *  -Exclude $_Excluded_Items -force  | Remove-Item -recurse –force -whatif

    Write-host ""
    What if: Performing operation "Remove Directory" on Target "\\ComputerName\temp-storage\!_Info".
    What if: Performing operation "Remove File" on Target "\\COMPUTERNAME\temp-storage\AFileWeWantToDelete.txt".
    # We see the -exclude worked because we only see two entries.

    Note that it will delete the file in the root folder and the folders recursively. This assume you have the appropriate permissions. More testing may be needed for more complex folder structures that could have file paths that are to long and security restrictions that may not be revealed by the -whatif. But if you can identifiy them you can add them to the exclusion so that they don't throw an error. If this is to be run as a scheduled task the errors would never be seen, so redirecting the script to a file might be a good idea.

    Hope this helps someone.

    • Proposed as answer by jadelise Saturday, June 2, 2012 6:41 PM
    Saturday, June 2, 2012 6:41 PM
  • Thanks.

    Kudos for the Get Smart quote. I think it was actually: "Missed it by THAT MUCH!"

    Micah

    Monday, December 31, 2012 4:02 PM
  • This doesn't work at all.  For an answer that works, see Daniel Horwood's response, i.e. pass an array as -Include's parameter: $Include=@("*.trn","*.bak","*.diff")
    Saturday, June 18, 2016 12:40 PM
  • This is the only answer that worked. Thank you Daniel
    Thursday, July 14, 2016 1:45 PM
  • $pattern="packages","obj","bin" # needs to be string[]

    or

    [string[]] $pattern="packages","obj","bin"

    Get-ChildItem -Recurse -Name -Attributes H,!H -Directory -Include $pattern
    Thursday, July 19, 2018 6:14 AM